diff --git a/webhook/webhook_client_impl.go b/webhook/webhook_client_impl.go index 29537409..0c523bef 100644 --- a/webhook/webhook_client_impl.go +++ b/webhook/webhook_client_impl.go @@ -2,12 +2,36 @@ package webhook import ( "context" + "errors" + "net/url" + "strings" "github.com/disgoorg/disgo/discord" "github.com/disgoorg/disgo/rest" "github.com/disgoorg/snowflake/v2" ) +// ParseURL parses a webhook URL +func NewWithURL(webhook string, opts ...ConfigOpt) (Client, error) { + u, err := url.Parse(webhook) + if err != nil { + return nil, err + } + + parts := strings.FieldsFunc(u.Path, func(r rune) bool { return r == '/' }) + if len(parts) != 4 { + return nil, errors.New("invalid webhook URL") + } + id, token := parts[2], parts[3] + + sf, err := snowflake.Parse(id) + if err != nil { + return nil, err + } + + return New(sf, token, opts...), nil +} + // New creates a new Client with the given ID, token and ConfigOpt(s). func New(id snowflake.ID, token string, opts ...ConfigOpt) Client { config := DefaultConfig() diff --git a/webhook/webook_test.go b/webhook/webook_test.go new file mode 100644 index 00000000..3c00ce37 --- /dev/null +++ b/webhook/webook_test.go @@ -0,0 +1,56 @@ +package webhook + +import ( + "testing" + + "github.com/disgoorg/snowflake/v2" + "github.com/stretchr/testify/require" +) + +func TestParseURL(t *testing.T) { + tt := []struct { + URL string + ID snowflake.ID + Token string + Err bool + }{ + { + URL: "https://discord.com/api/webhooks/123456789123456789/foo", + ID: snowflake.ID(123456789123456789), + Token: "foo", + }, + { + URL: "https://discord.com/api/webhooks/123456789123456789/foo/", + ID: snowflake.ID(123456789123456789), + Token: "foo", + }, + { + URL: "https://canary.discord.com/api/webhooks/123456789123456789/foo", + ID: snowflake.ID(123456789123456789), + Token: "foo", + }, + { + URL: "foobarbaz", + Err: true, + }, + { + URL: "https://discord.com/api/webhooks/123456789123456789/foo?wait=10", + ID: snowflake.ID(123456789123456789), + Token: "foo", + }, + } + + for _, tc := range tt { + t.Run(tc.URL, func(t *testing.T) { + assert := require.New(t) + + c, err := NewWithURL(tc.URL) + if tc.Err { + assert.Error(err, "URL parsing should have resulted in an error") + return + } + assert.Equal(tc.ID, c.ID(), "URL ID should match") + assert.Equal(tc.Token, c.Token(), "URL token should match") + }) + } +}