webhook: Add several abstracted constructors

This commit is contained in:
diamondburned 2023-08-15 00:29:37 -07:00
parent 13ac33f33f
commit b1a54c0b41
No known key found for this signature in database
GPG Key ID: D78C4471CE776659
1 changed files with 33 additions and 0 deletions

View File

@ -6,6 +6,7 @@ import (
"context"
"mime/multipart"
"net/url"
"regexp"
"strconv"
"github.com/pkg/errors"
@ -22,6 +23,23 @@ import (
// TODO: if there's ever an Arikawa v3, then a new Client abstraction could be
// made that wraps around Session being an interface. Just a food for thought.
var webhookURLRe = regexp.MustCompile(`https://discord(?:app)?.com/api/webhooks/(\d+)/(.+)`)
// ParseURL parses the given Discord webhook URL.
func ParseURL(webhookURL string) (id discord.WebhookID, token string, err error) {
matches := webhookURLRe.FindStringSubmatch(webhookURL)
if matches == nil {
return 0, "", errors.New("invalid webhook URL")
}
idInt, err := strconv.ParseUint(matches[1], 10, 64)
if err != nil {
return 0, "", errors.Wrap(err, "failed to parse webhook ID")
}
return discord.WebhookID(idInt), matches[2], nil
}
// Session keeps a single webhook session. It is referenced by other webhook
// clients using the same session.
type Session struct {
@ -45,6 +63,11 @@ func (s *Session) OnResponse(r httpdriver.Request, resp httpdriver.Response) err
return s.Limiter.Release(r.GetPath(), httpdriver.OptHeader(resp))
}
// Client creates a new Webhook API client from the session.
func (s *Session) Client() *Client {
return &Client{httputil.NewClient(), s}
}
// Client is the client used to interact with a webhook.
type Client struct {
// Client is the httputil.Client used to call Discord's API.
@ -78,6 +101,16 @@ func NewCustom(id discord.WebhookID, token string, hcl *httputil.Client) *Client
}
}
// NewFromURL creates a new webhook client using the passed webhook URL. It
// uses its own rate limiter.
func NewFromURL(url string) (*Client, error) {
id, token, err := ParseURL(url)
if err != nil {
return nil, err
}
return New(id, token), nil
}
// FromAPI creates a new client that shares the same internal HTTP client with
// the one in the API's. This is often useful for bots that need webhook
// interaction, since the rate limiter is shared.