From 48c941a8d962b1bf2e469dd5ed85da0e7c359188 Mon Sep 17 00:00:00 2001 From: Demian Date: Fri, 3 Nov 2023 00:12:36 +0100 Subject: [PATCH] middleware: move m appending into separate func --- bot.go | 98 +++++++++++++++++++++------------------------------ bot_test.go | 2 +- middleware.go | 17 +++++---- 3 files changed, 51 insertions(+), 66 deletions(-) diff --git a/bot.go b/bot.go index 2a8a5af..5f5f66f 100644 --- a/bot.go +++ b/bot.go @@ -160,28 +160,24 @@ var ( // // Example: // -// b.Handle("/start", func (c tele.Context) error { -// return c.Reply("Hello!") -// }) +// b.Handle("/start", func (c tele.Context) error { +// return c.Reply("Hello!") +// }) // -// b.Handle(&inlineButton, func (c tele.Context) error { -// return c.Respond(&tele.CallbackResponse{Text: "Hello!"}) -// }) +// b.Handle(&inlineButton, func (c tele.Context) error { +// return c.Respond(&tele.CallbackResponse{Text: "Hello!"}) +// }) // // Middleware usage: // -// b.Handle("/ban", onBan, middleware.Whitelist(ids...)) -// +// b.Handle("/ban", onBan, middleware.Whitelist(ids...)) func (b *Bot) Handle(endpoint interface{}, h HandlerFunc, m ...MiddlewareFunc) { - mw := m if len(b.group.middleware) > 0 { - mw = make([]MiddlewareFunc, 0, len(b.group.middleware)+len(m)) - mw = append(mw, b.group.middleware...) - mw = append(mw, m...) + m = appendMiddleware(b.group.middleware, m) } handler := func(c Context) error { - return applyMiddleware(h, mw...)(c) + return applyMiddleware(h, m...)(c) } switch end := endpoint.(type) { @@ -259,16 +255,16 @@ func (b *Bot) NewContext(u Update) Context { // some Sendable (or string!) and optional send options. // // NOTE: -// Since most arguments are of type interface{}, but have pointer -// method receivers, make sure to pass them by-pointer, NOT by-value. // -// What is a send option exactly? It can be one of the following types: +// Since most arguments are of type interface{}, but have pointer +// method receivers, make sure to pass them by-pointer, NOT by-value. // -// - *SendOptions (the actual object accepted by Telegram API) -// - *ReplyMarkup (a component of SendOptions) -// - Option (a shortcut flag for popular options) -// - ParseMode (HTML, Markdown, etc) +// What is a send option exactly? It can be one of the following types: // +// - *SendOptions (the actual object accepted by Telegram API) +// - *ReplyMarkup (a component of SendOptions) +// - Option (a shortcut flag for popular options) +// - ParseMode (HTML, Markdown, etc) func (b *Bot) Send(to Recipient, what interface{}, opts ...interface{}) (*Message, error) { if to == nil { return nil, ErrBadRecipient @@ -440,14 +436,13 @@ func (b *Bot) Copy(to Recipient, msg Editable, options ...interface{}) (*Message // // Use cases: // -// b.Edit(m, m.Text, newMarkup) -// b.Edit(m, "new text", tele.ModeHTML) -// b.Edit(m, &tele.ReplyMarkup{...}) -// b.Edit(m, &tele.Photo{File: ...}) -// b.Edit(m, tele.Location{42.1337, 69.4242}) -// b.Edit(c, "edit inline message from the callback") -// b.Edit(r, "edit message from chosen inline result") -// +// b.Edit(m, m.Text, newMarkup) +// b.Edit(m, "new text", tele.ModeHTML) +// b.Edit(m, &tele.ReplyMarkup{...}) +// b.Edit(m, &tele.Photo{File: ...}) +// b.Edit(m, tele.Location{42.1337, 69.4242}) +// b.Edit(c, "edit inline message from the callback") +// b.Edit(r, "edit message from chosen inline result") func (b *Bot) Edit(msg Editable, what interface{}, opts ...interface{}) (*Message, error) { var ( method string @@ -506,7 +501,6 @@ func (b *Bot) Edit(msg Editable, what interface{}, opts ...interface{}) (*Messag // // If edited message is sent by the bot, returns it, // otherwise returns nil and ErrTrueResult. -// func (b *Bot) EditReplyMarkup(msg Editable, markup *ReplyMarkup) (*Message, error) { msgID, chatID := msg.MessageSig() params := make(map[string]string) @@ -540,7 +534,6 @@ func (b *Bot) EditReplyMarkup(msg Editable, markup *ReplyMarkup) (*Message, erro // // If edited message is sent by the bot, returns it, // otherwise returns nil and ErrTrueResult. -// func (b *Bot) EditCaption(msg Editable, caption string, opts ...interface{}) (*Message, error) { msgID, chatID := msg.MessageSig() @@ -574,9 +567,8 @@ func (b *Bot) EditCaption(msg Editable, caption string, opts ...interface{}) (*M // // Use cases: // -// b.EditMedia(m, &tele.Photo{File: tele.FromDisk("chicken.jpg")}) -// b.EditMedia(m, &tele.Video{File: tele.FromURL("http://video.mp4")}) -// +// b.EditMedia(m, &tele.Photo{File: tele.FromDisk("chicken.jpg")}) +// b.EditMedia(m, &tele.Video{File: tele.FromURL("http://video.mp4")}) func (b *Bot) EditMedia(msg Editable, media Inputtable, opts ...interface{}) (*Message, error) { var ( repr string @@ -658,15 +650,14 @@ func (b *Bot) EditMedia(msg Editable, media Inputtable, opts ...interface{}) (*M // Delete removes the message, including service messages. // This function will panic upon nil Editable. // -// - A message can only be deleted if it was sent less than 48 hours ago. -// - A dice message in a private chat can only be deleted if it was sent more than 24 hours ago. -// - Bots can delete outgoing messages in private chats, groups, and supergroups. -// - Bots can delete incoming messages in private chats. -// - Bots granted can_post_messages permissions can delete outgoing messages in channels. -// - If the bot is an administrator of a group, it can delete any message there. -// - If the bot has can_delete_messages permission in a supergroup or a -// channel, it can delete any message there. -// +// - A message can only be deleted if it was sent less than 48 hours ago. +// - A dice message in a private chat can only be deleted if it was sent more than 24 hours ago. +// - Bots can delete outgoing messages in private chats, groups, and supergroups. +// - Bots can delete incoming messages in private chats. +// - Bots granted can_post_messages permissions can delete outgoing messages in channels. +// - If the bot is an administrator of a group, it can delete any message there. +// - If the bot has can_delete_messages permission in a supergroup or a +// channel, it can delete any message there. func (b *Bot) Delete(msg Editable) error { msgID, chatID := msg.MessageSig() @@ -688,7 +679,6 @@ func (b *Bot) Delete(msg Editable) error { // // Currently, Telegram supports only a narrow range of possible // actions, these are aligned as constants of this package. -// func (b *Bot) Notify(to Recipient, action ChatAction) error { if to == nil { return ErrBadRecipient @@ -708,10 +698,9 @@ func (b *Bot) Notify(to Recipient, action ChatAction) error { // // Example: // -// b.Ship(query) // OK -// b.Ship(query, opts...) // OK with options -// b.Ship(query, "Oops!") // Error message -// +// b.Ship(query) // OK +// b.Ship(query, opts...) // OK with options +// b.Ship(query, "Oops!") // Error message func (b *Bot) Ship(query *ShippingQuery, what ...interface{}) error { params := map[string]string{ "shipping_query_id": query.ID, @@ -764,9 +753,8 @@ func (b *Bot) Accept(query *PreCheckoutQuery, errorMessage ...string) error { // // Example: // -// b.Respond(c) -// b.Respond(c, response) -// +// b.Respond(c) +// b.Respond(c, response) func (b *Bot) Respond(c *Callback, resp ...*CallbackResponse) error { var r *CallbackResponse if resp == nil { @@ -824,7 +812,6 @@ func (b *Bot) AnswerWebApp(query *Query, r Result) (*WebAppMessage, error) { // // Usually, Telegram-provided File objects miss FilePath so you might need to // perform an additional request to fetch them. -// func (b *Bot) FileByID(fileID string) (File, error) { params := map[string]string{ "file_id": fileID, @@ -904,7 +891,6 @@ func (b *Bot) File(file *File) (io.ReadCloser, error) { // // If the message is sent by the bot, returns it, // otherwise returns nil and ErrTrueResult. -// func (b *Bot) StopLiveLocation(msg Editable, opts ...interface{}) (*Message, error) { msgID, chatID := msg.MessageSig() @@ -929,7 +915,6 @@ func (b *Bot) StopLiveLocation(msg Editable, opts ...interface{}) (*Message, err // // It supports ReplyMarkup. // This function will panic upon nil Editable. -// func (b *Bot) StopPoll(msg Editable, opts ...interface{}) (*Poll, error) { msgID, chatID := msg.MessageSig() @@ -969,7 +954,6 @@ func (b *Bot) Leave(chat *Chat) error { // // It supports Silent option. // This function will panic upon nil Editable. -// func (b *Bot) Pin(msg Editable, opts ...interface{}) error { msgID, chatID := msg.MessageSig() @@ -1014,7 +998,6 @@ func (b *Bot) UnpinAll(chat *Chat) error { // // Including current name of the user for one-on-one conversations, // current username of a user, group or channel, etc. -// func (b *Bot) ChatByID(id int64) (*Chat, error) { return b.ChatByUsername(strconv.FormatInt(id, 10)) } @@ -1112,9 +1095,8 @@ func (b *Bot) MenuButton(chat *User) (*MenuButton, error) { // // It accepts two kinds of menu button arguments: // -// - MenuButtonType for simple menu buttons (default, commands) -// - MenuButton complete structure for web_app menu button type -// +// - MenuButtonType for simple menu buttons (default, commands) +// - MenuButton complete structure for web_app menu button type func (b *Bot) SetMenuButton(chat *User, mb interface{}) error { params := map[string]interface{}{ "chat_id": chat.Recipient(), diff --git a/bot_test.go b/bot_test.go index 3f2f347..56d0063 100644 --- a/bot_test.go +++ b/bot_test.go @@ -373,7 +373,7 @@ func TestBotOnError(t *testing.T) { assert.True(t, ok) } -func TestBot_Middleware(t *testing.T) { +func TestBotMiddleware(t *testing.T) { t.Run("call order", func(t *testing.T) { var trace []string diff --git a/middleware.go b/middleware.go index e57465e..a8e2912 100644 --- a/middleware.go +++ b/middleware.go @@ -4,6 +4,15 @@ package telebot // which get called before the endpoint group or specific handler. type MiddlewareFunc func(HandlerFunc) HandlerFunc +func appendMiddleware(a, b []MiddlewareFunc) []MiddlewareFunc { + if len(a) == 0 { + return b + } + + m := make([]MiddlewareFunc, 0, len(a)+len(b)) + return append(m, append(a, b...)...) +} + func applyMiddleware(h HandlerFunc, m ...MiddlewareFunc) HandlerFunc { for i := len(m) - 1; i >= 0; i-- { h = m[i](h) @@ -25,11 +34,5 @@ func (g *Group) Use(middleware ...MiddlewareFunc) { // Handle adds endpoint handler to the bot, combining group's middleware // with the optional given middleware. func (g *Group) Handle(endpoint interface{}, h HandlerFunc, m ...MiddlewareFunc) { - mw := m - if len(g.middleware) > 0 { - mw = make([]MiddlewareFunc, 0, len(g.middleware)+len(m)) - mw = append(mw, g.middleware...) - mw = append(mw, m...) - } - g.b.Handle(endpoint, h, mw...) + g.b.Handle(endpoint, h, appendMiddleware(g.middleware, m)...) }