Merge pull request #300 from mymmrac/telegram-bot-commands
feat(telegram): Init bot commands on start
This commit is contained in:
commit
25639168ea
1 changed files with 65 additions and 9 deletions
|
|
@ -7,12 +7,12 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/mymmrac/telego"
|
"github.com/mymmrac/telego"
|
||||||
"github.com/mymmrac/telego/telegohandler"
|
|
||||||
th "github.com/mymmrac/telego/telegohandler"
|
th "github.com/mymmrac/telego/telegohandler"
|
||||||
tu "github.com/mymmrac/telego/telegoutil"
|
tu "github.com/mymmrac/telego/telegoutil"
|
||||||
|
|
||||||
|
|
@ -41,7 +41,7 @@ var (
|
||||||
type TelegramChannel struct {
|
type TelegramChannel struct {
|
||||||
*channels.BaseChannel
|
*channels.BaseChannel
|
||||||
bot *telego.Bot
|
bot *telego.Bot
|
||||||
bh *telegohandler.BotHandler
|
bh *th.BotHandler
|
||||||
commands TelegramCommander
|
commands TelegramCommander
|
||||||
config *config.Config
|
config *config.Config
|
||||||
chatIDs map[string]int64
|
chatIDs map[string]int64
|
||||||
|
|
@ -101,6 +101,12 @@ func (c *TelegramChannel) Start(ctx context.Context) error {
|
||||||
|
|
||||||
c.ctx, c.cancel = context.WithCancel(ctx)
|
c.ctx, c.cancel = context.WithCancel(ctx)
|
||||||
|
|
||||||
|
if err := c.initBotCommands(c.ctx); err != nil {
|
||||||
|
logger.WarnCF("telegram", "Failed to initialize bot commands", map[string]any{
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
updates, err := c.bot.UpdatesViaLongPolling(c.ctx, &telego.GetUpdatesParams{
|
updates, err := c.bot.UpdatesViaLongPolling(c.ctx, &telego.GetUpdatesParams{
|
||||||
Timeout: 30,
|
Timeout: 30,
|
||||||
})
|
})
|
||||||
|
|
@ -109,20 +115,19 @@ func (c *TelegramChannel) Start(ctx context.Context) error {
|
||||||
return fmt.Errorf("failed to start long polling: %w", err)
|
return fmt.Errorf("failed to start long polling: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
bh, err := telegohandler.NewBotHandler(c.bot, updates)
|
bh, err := th.NewBotHandler(c.bot, updates)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.cancel()
|
c.cancel()
|
||||||
return fmt.Errorf("failed to create bot handler: %w", err)
|
return fmt.Errorf("failed to create bot handler: %w", err)
|
||||||
}
|
}
|
||||||
c.bh = bh
|
c.bh = bh
|
||||||
|
|
||||||
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
|
||||||
c.commands.Help(ctx, message)
|
|
||||||
return nil
|
|
||||||
}, th.CommandEqual("help"))
|
|
||||||
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
||||||
return c.commands.Start(ctx, message)
|
return c.commands.Start(ctx, message)
|
||||||
}, th.CommandEqual("start"))
|
}, th.CommandEqual("start"))
|
||||||
|
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
||||||
|
return c.commands.Help(ctx, message)
|
||||||
|
}, th.CommandEqual("help"))
|
||||||
|
|
||||||
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
||||||
return c.commands.Show(ctx, message)
|
return c.commands.Show(ctx, message)
|
||||||
|
|
@ -141,7 +146,13 @@ func (c *TelegramChannel) Start(ctx context.Context) error {
|
||||||
"username": c.bot.Username(),
|
"username": c.bot.Username(),
|
||||||
})
|
})
|
||||||
|
|
||||||
go bh.Start()
|
go func() {
|
||||||
|
if err = bh.Start(); err != nil {
|
||||||
|
logger.ErrorCF("telegram", "Bot handler failed", map[string]any{
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -152,7 +163,7 @@ func (c *TelegramChannel) Stop(ctx context.Context) error {
|
||||||
|
|
||||||
// Stop the bot handler
|
// Stop the bot handler
|
||||||
if c.bh != nil {
|
if c.bh != nil {
|
||||||
c.bh.Stop()
|
_ = c.bh.StopWithContext(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel our context (stops long polling)
|
// Cancel our context (stops long polling)
|
||||||
|
|
@ -163,6 +174,51 @@ func (c *TelegramChannel) Stop(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *TelegramChannel) initBotCommands(ctx context.Context) error {
|
||||||
|
currentCommands, err := c.bot.GetMyCommands(ctx, &telego.GetMyCommandsParams{
|
||||||
|
Scope: tu.ScopeDefault(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("get commands: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
commands := []telego.BotCommand{
|
||||||
|
{
|
||||||
|
Command: "start",
|
||||||
|
Description: "Start the bot",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Command: "help",
|
||||||
|
Description: "Show a help message",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Command: "show",
|
||||||
|
Description: "Show current configuration",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Command: "list",
|
||||||
|
Description: "List available options",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setting commands on each start will hit the rate limit very quickly, that's why we check if an update is needed
|
||||||
|
if !slices.Equal(currentCommands, commands) {
|
||||||
|
logger.InfoC("telegram", "Updating bot commands")
|
||||||
|
|
||||||
|
err = c.bot.SetMyCommands(ctx, &telego.SetMyCommandsParams{
|
||||||
|
Commands: commands,
|
||||||
|
Scope: tu.ScopeDefault(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("set commands: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.DebugC("telegram", "Bot commands are up to date")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *TelegramChannel) Send(ctx context.Context, msg bus.OutboundMessage) error {
|
func (c *TelegramChannel) Send(ctx context.Context, msg bus.OutboundMessage) error {
|
||||||
if !c.IsRunning() {
|
if !c.IsRunning() {
|
||||||
return channels.ErrNotRunning
|
return channels.ErrNotRunning
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue