Skip to content

Commit 2563916

Browse files
authored
Merge pull request #300 from mymmrac/telegram-bot-commands
feat(telegram): Init bot commands on start
2 parents 8fddbae + b0c8fc4 commit 2563916

File tree

1 file changed

+65
-9
lines changed

1 file changed

+65
-9
lines changed

pkg/channels/telegram/telegram.go

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import (
77
"net/url"
88
"os"
99
"regexp"
10+
"slices"
1011
"strconv"
1112
"strings"
1213
"time"
1314

1415
"github.com/mymmrac/telego"
15-
"github.com/mymmrac/telego/telegohandler"
1616
th "github.com/mymmrac/telego/telegohandler"
1717
tu "github.com/mymmrac/telego/telegoutil"
1818

@@ -41,7 +41,7 @@ var (
4141
type TelegramChannel struct {
4242
*channels.BaseChannel
4343
bot *telego.Bot
44-
bh *telegohandler.BotHandler
44+
bh *th.BotHandler
4545
commands TelegramCommander
4646
config *config.Config
4747
chatIDs map[string]int64
@@ -101,6 +101,12 @@ func (c *TelegramChannel) Start(ctx context.Context) error {
101101

102102
c.ctx, c.cancel = context.WithCancel(ctx)
103103

104+
if err := c.initBotCommands(c.ctx); err != nil {
105+
logger.WarnCF("telegram", "Failed to initialize bot commands", map[string]any{
106+
"error": err.Error(),
107+
})
108+
}
109+
104110
updates, err := c.bot.UpdatesViaLongPolling(c.ctx, &telego.GetUpdatesParams{
105111
Timeout: 30,
106112
})
@@ -109,20 +115,19 @@ func (c *TelegramChannel) Start(ctx context.Context) error {
109115
return fmt.Errorf("failed to start long polling: %w", err)
110116
}
111117

112-
bh, err := telegohandler.NewBotHandler(c.bot, updates)
118+
bh, err := th.NewBotHandler(c.bot, updates)
113119
if err != nil {
114120
c.cancel()
115121
return fmt.Errorf("failed to create bot handler: %w", err)
116122
}
117123
c.bh = bh
118124

119-
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
120-
c.commands.Help(ctx, message)
121-
return nil
122-
}, th.CommandEqual("help"))
123125
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
124126
return c.commands.Start(ctx, message)
125127
}, th.CommandEqual("start"))
128+
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
129+
return c.commands.Help(ctx, message)
130+
}, th.CommandEqual("help"))
126131

127132
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
128133
return c.commands.Show(ctx, message)
@@ -141,7 +146,13 @@ func (c *TelegramChannel) Start(ctx context.Context) error {
141146
"username": c.bot.Username(),
142147
})
143148

144-
go bh.Start()
149+
go func() {
150+
if err = bh.Start(); err != nil {
151+
logger.ErrorCF("telegram", "Bot handler failed", map[string]any{
152+
"error": err.Error(),
153+
})
154+
}
155+
}()
145156

146157
return nil
147158
}
@@ -152,7 +163,7 @@ func (c *TelegramChannel) Stop(ctx context.Context) error {
152163

153164
// Stop the bot handler
154165
if c.bh != nil {
155-
c.bh.Stop()
166+
_ = c.bh.StopWithContext(ctx)
156167
}
157168

158169
// Cancel our context (stops long polling)
@@ -163,6 +174,51 @@ func (c *TelegramChannel) Stop(ctx context.Context) error {
163174
return nil
164175
}
165176

177+
func (c *TelegramChannel) initBotCommands(ctx context.Context) error {
178+
currentCommands, err := c.bot.GetMyCommands(ctx, &telego.GetMyCommandsParams{
179+
Scope: tu.ScopeDefault(),
180+
})
181+
if err != nil {
182+
return fmt.Errorf("get commands: %w", err)
183+
}
184+
185+
commands := []telego.BotCommand{
186+
{
187+
Command: "start",
188+
Description: "Start the bot",
189+
},
190+
{
191+
Command: "help",
192+
Description: "Show a help message",
193+
},
194+
{
195+
Command: "show",
196+
Description: "Show current configuration",
197+
},
198+
{
199+
Command: "list",
200+
Description: "List available options",
201+
},
202+
}
203+
204+
// Setting commands on each start will hit the rate limit very quickly, that's why we check if an update is needed
205+
if !slices.Equal(currentCommands, commands) {
206+
logger.InfoC("telegram", "Updating bot commands")
207+
208+
err = c.bot.SetMyCommands(ctx, &telego.SetMyCommandsParams{
209+
Commands: commands,
210+
Scope: tu.ScopeDefault(),
211+
})
212+
if err != nil {
213+
return fmt.Errorf("set commands: %w", err)
214+
}
215+
} else {
216+
logger.DebugC("telegram", "Bot commands are up to date")
217+
}
218+
219+
return nil
220+
}
221+
166222
func (c *TelegramChannel) Send(ctx context.Context, msg bus.OutboundMessage) error {
167223
if !c.IsRunning() {
168224
return channels.ErrNotRunning

0 commit comments

Comments
 (0)