Skip to content

Commit

Permalink
Change addwebhook method to take an AddWebhookOpts param (#125)
Browse files Browse the repository at this point in the history
* Add a small breaking change to the addwebhook method, such that it now takes an AddWebhookOpts

* comments

* Fix tests
  • Loading branch information
PaulSonOfLars authored Jan 1, 2024
1 parent 3e3aa15 commit ee17423
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 16 deletions.
3 changes: 3 additions & 0 deletions ext/botmapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ var ErrBotUrlPathAlreadyExists = errors.New("url path already exists in bot mapp
// addBot Adds a new bot to the botMapping structure.
// Pass an empty urlPath/webhookSecret if using polling instead of webhooks.
func (m *botMapping) addBot(b *gotgbot.Bot, urlPath string, webhookSecret string) (*botData, error) {
// Clean up the URLPath such that it remains consistent.
urlPath = strings.TrimPrefix(urlPath, "/")

m.mux.Lock()
defer m.mux.Unlock()

Expand Down
21 changes: 18 additions & 3 deletions ext/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,23 +282,38 @@ func (u *Updater) StopAllBots() {
// This does NOT set the webhook on telegram - this should be done by the caller.
// The opts parameter allows for specifying various webhook settings.
func (u *Updater) StartWebhook(b *gotgbot.Bot, urlPath string, opts WebhookOpts) error {
err := u.AddWebhook(b, urlPath, opts)
if u.webhookServer != nil {
return ErrExpectedEmptyServer
}

err := u.AddWebhook(b, urlPath, &AddWebhookOpts{SecretToken: opts.SecretToken})
if err != nil {
return fmt.Errorf("failed to add webhook: %w", err)
}

return u.StartServer(opts)
}

// AddWebhookOpts stores any optional parameters for the Updater.AddWebhook method.
type AddWebhookOpts struct {
// The secret token to be used to validate webhook authenticity.
SecretToken string
}

// AddWebhook prepares the webhook server to receive webhook updates for one bot, on a specific path.
func (u *Updater) AddWebhook(b *gotgbot.Bot, urlPath string, opts WebhookOpts) error {
func (u *Updater) AddWebhook(b *gotgbot.Bot, urlPath string, opts *AddWebhookOpts) error {
// We expect webhooks to use unique URL paths; otherwise, we wouldnt be able to differentiate them from polling, or
// from each other.
if urlPath == "" {
return fmt.Errorf("expected a non-empty url path: %w", ErrEmptyPath)
}

bData, err := u.botMapping.addBot(b, strings.TrimPrefix(urlPath, "/"), opts.SecretToken)
secretToken := ""
if opts != nil {
secretToken = opts.SecretToken
}

bData, err := u.botMapping.addBot(b, urlPath, secretToken)
if err != nil {
return fmt.Errorf("failed to add webhook for bot: %w", err)
}
Expand Down
21 changes: 10 additions & 11 deletions ext/updater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ func TestUpdaterThrowsErrorWhenSameWebhookAddedTwice(t *testing.T) {
d := ext.NewDispatcher(&ext.DispatcherOpts{})
u := ext.NewUpdater(d, nil)

err := u.AddWebhook(b, "test", ext.WebhookOpts{})
err := u.AddWebhook(b, "test", nil)
if err != nil {
t.Errorf("failed to add webhook: %v", err)
return
}

// Adding a second time should throw an error
err = u.AddWebhook(b, "test", ext.WebhookOpts{})
err = u.AddWebhook(b, "test", nil)
if err == nil {
t.Errorf("should have failed to add the same webhook twice, but didnt")
return
Expand All @@ -53,7 +53,7 @@ func TestUpdaterSupportsWebhookReAdding(t *testing.T) {
d := ext.NewDispatcher(&ext.DispatcherOpts{})
u := ext.NewUpdater(d, nil)

err := u.AddWebhook(b, "test", ext.WebhookOpts{})
err := u.AddWebhook(b, "test", nil)
if err != nil {
t.Errorf("failed to add webhook: %v", err)
return
Expand All @@ -66,7 +66,7 @@ func TestUpdaterSupportsWebhookReAdding(t *testing.T) {
}

// Should be able to re-add the bot now
err = u.AddWebhook(b, "test", ext.WebhookOpts{})
err = u.AddWebhook(b, "test", nil)
if err != nil {
t.Errorf("Failed to re-add a previously removed bot: %v", err)
return
Expand Down Expand Up @@ -154,7 +154,7 @@ func TestUpdaterDisallowsEmptyWebhooks(t *testing.T) {
d := ext.NewDispatcher(&ext.DispatcherOpts{})
u := ext.NewUpdater(d, nil)

err := u.AddWebhook(b, "", ext.WebhookOpts{})
err := u.AddWebhook(b, "", nil)
if !errors.Is(err, ext.ErrEmptyPath) {
t.Errorf("Expected an empty path error trying to add an empty webhook : %v", err)
return
Expand All @@ -169,7 +169,7 @@ func TestUpdater_GetHandlerFunc(t *testing.T) {

type args struct {
urlPath string
opts ext.WebhookOpts
opts *ext.AddWebhookOpts
httpResponse int
handlerPrefix string
requestPath string // Should start with '/'
Expand Down Expand Up @@ -215,7 +215,7 @@ func TestUpdater_GetHandlerFunc(t *testing.T) {
name: "missing secret token",
args: args{
urlPath: "123:hello",
opts: ext.WebhookOpts{
opts: &ext.AddWebhookOpts{
SecretToken: "secret",
},
httpResponse: http.StatusUnauthorized,
Expand All @@ -226,7 +226,7 @@ func TestUpdater_GetHandlerFunc(t *testing.T) {
name: "matching secret token",
args: args{
urlPath: "123:hello",
opts: ext.WebhookOpts{
opts: &ext.AddWebhookOpts{
SecretToken: "secret",
},
httpResponse: http.StatusOK,
Expand All @@ -240,7 +240,7 @@ func TestUpdater_GetHandlerFunc(t *testing.T) {
name: "invalid secret token",
args: args{
urlPath: "123:hello",
opts: ext.WebhookOpts{
opts: &ext.AddWebhookOpts{
SecretToken: "secret",
},
httpResponse: http.StatusUnauthorized,
Expand Down Expand Up @@ -547,13 +547,12 @@ func benchmarkUpdaterWithNBots(b *testing.B, numBot int) {
return nil
}})

opts := ext.WebhookOpts{}
for i := 0; i < numBot; i++ {
token := strconv.Itoa(i)
err := u.AddWebhook(&gotgbot.Bot{
Token: token,
BotClient: &gotgbot.BaseBotClient{},
}, token, opts)
}, token, nil)
if err != nil {
b.Fatalf("failed to add webhook for bot: %s", err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion samples/echoMultiBot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func startWebhookBots(updater *ext.Updater, bots []*gotgbot.Bot, domain string,

// We add all the bots to the updater.
for idx, b := range bots {
err = updater.AddWebhook(b, b.Token, opts)
err = updater.AddWebhook(b, b.Token, &ext.AddWebhookOpts{SecretToken: webhookSecret})
if err != nil {
return fmt.Errorf("failed to add bot: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion samples/webappBot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func main() {
}))

// We add the bot webhook to our updater, such that we can populate the updater's http.Handler.
err = updater.AddWebhook(b, b.Token, ext.WebhookOpts{SecretToken: webhookSecret})
err = updater.AddWebhook(b, b.Token, &ext.AddWebhookOpts{SecretToken: webhookSecret})
if err != nil {
panic("Failed to add bot webhooks to updater: " + err.Error())
}
Expand Down

0 comments on commit ee17423

Please sign in to comment.