From c4089b795b260fd4a5a5a42e6489493aae9f3e19 Mon Sep 17 00:00:00 2001 From: Neko Ayaka Date: Mon, 24 Jul 2023 19:17:33 +0800 Subject: [PATCH] feat: auto migration to supergroup, improved welcome message (#165) --- .../handlers/chatmigrate/chatmigrate.go | 130 ++++++++++++++++++ internal/bots/telegram/handlers/handlers.go | 10 +- .../bots/telegram/handlers/welcome/welcome.go | 20 ++- .../models/chathistories/chat_histories.go | 21 +++ internal/models/logs/logs.go | 78 +++++++++++ internal/models/models.go | 2 + .../models/tgchats/auto_recaps_subscribers.go | 20 +++ internal/models/tgchats/feature_flags.go | 22 +++ internal/models/tgchats/recaps_options.go | 23 ++++ pkg/bots/tgbot/context.go | 6 + pkg/bots/tgbot/dispatcher.go | 58 ++++++-- 11 files changed, 374 insertions(+), 16 deletions(-) create mode 100644 internal/bots/telegram/handlers/chatmigrate/chatmigrate.go create mode 100644 internal/models/logs/logs.go diff --git a/internal/bots/telegram/handlers/chatmigrate/chatmigrate.go b/internal/bots/telegram/handlers/chatmigrate/chatmigrate.go new file mode 100644 index 0000000..f7921e0 --- /dev/null +++ b/internal/bots/telegram/handlers/chatmigrate/chatmigrate.go @@ -0,0 +1,130 @@ +package chatmigrate + +import ( + "fmt" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/nekomeowww/fo" + "go.uber.org/fx" + "go.uber.org/zap" + + "github.com/nekomeowww/insights-bot/internal/models/chathistories" + "github.com/nekomeowww/insights-bot/internal/models/logs" + "github.com/nekomeowww/insights-bot/internal/models/tgchats" + "github.com/nekomeowww/insights-bot/pkg/bots/tgbot" + "github.com/nekomeowww/insights-bot/pkg/logger" +) + +func NewModules() fx.Option { + return fx.Options( + fx.Provide(NewHandlers()), + ) +} + +type NewHandlersParams struct { + fx.In + + TgChats *tgchats.Model + ChatHistories *chathistories.Model + Logs *logs.Model + Logger *logger.Logger +} + +type Handlers struct { + tgchats *tgchats.Model + chatHistories *chathistories.Model + logs *logs.Model + logger *logger.Logger +} + +func NewHandlers() func(param NewHandlersParams) *Handlers { + return func(param NewHandlersParams) *Handlers { + return &Handlers{ + tgchats: param.TgChats, + chatHistories: param.ChatHistories, + logs: param.Logs, + logger: param.Logger, + } + } +} + +func (h *Handlers) Install(dispatcher *tgbot.Dispatcher) { + dispatcher.OnChatMigrationFrom(tgbot.NewHandler(h.handleChatMigrationFrom)) +} + +func (h *Handlers) handleChatMigrationFrom(c *tgbot.Context) (tgbot.Response, error) { + if c.Update.Message == nil { + return nil, nil + } + if c.Update.Message.MigrateFromChatID == 0 { + return nil, nil + } + + fromChatID := c.Update.Message.MigrateFromChatID + toChatID := c.Update.Message.Chat.ID + + may := fo. + NewMay0(). + Use(fo.WithLogFuncHandler(func(a ...any) { + h.logger.Error(fmt.Sprint(a...)) + })) + + may.Invoke(func() error { + err := h.tgchats.MigrateFeatureFlagsOfChatFromChatIDToChatID(fromChatID, toChatID) + if err != nil { + return fmt.Errorf("failed to migrate all feature flags of chat from chat id %d to chat id %d: %w", fromChatID, toChatID, err) + } + + return nil + }()) + may.Invoke(func() error { + err := h.tgchats.MigrateOptionOfChatFromChatIDToChatID(fromChatID, toChatID) + if err != nil { + return fmt.Errorf("failed to migrate all options of chat from chat id %d to chat id %d: %w", fromChatID, toChatID, err) + } + + return nil + }()) + may.Invoke(func() error { + err := h.tgchats.MigrateSubscribersOfChatFromChatIDToChatID(fromChatID, toChatID) + if err != nil { + return fmt.Errorf("failed to migrate all subscribers of chat from chat id %d to chat id %d: %w", fromChatID, toChatID, err) + } + + return nil + }()) + may.Invoke(func() error { + err := h.chatHistories.MigrateChatHistoriesOfChatFromChatIDToChatID(fromChatID, toChatID) + if err != nil { + return fmt.Errorf("failed to migrate all chat histories of chat from chat id %d to chat id %d: %w", fromChatID, toChatID, err) + } + + return nil + }()) + may.Invoke(func() error { + err := h.logs.MigrateLogsOfChatFromChatIDToChatID(fromChatID, toChatID) + if err != nil { + return fmt.Errorf("failed to migrate all logs of chat from chat id %d to chat id %d: %w", fromChatID, toChatID, err) + } + + return nil + }()) + + h.logger.Info(fmt.Sprintf("成功将群组 %d 的所有数据迁移到群组 %d", fromChatID, toChatID), zap.Int64("from_chat_id", fromChatID), zap.Int64("to_chat_id", toChatID)) + + message := tgbotapi.NewMessage(toChatID, + fmt.Sprintf(""+ + "%s @%s 监测到您的群组已从 群组(group) 升级为了 超级群组(supergroup),届时"+ + ",群组的 ID 将会发生变更,现已自动将过去的历史记录和数据留存自动迁移到了新的群组 ID 名下,"+ + "之前的设置将会保留并继续沿用,不过需要注意的是,由于 Telegram 官方的限制,迁移事件前的消息 ID 将无"+ + "法与今后发送的消息 ID 相兼容,所以当下一次总结消息时将不会包含在迁移事件发生前所发送的消息,由此带来"+ + "的不便敬请谅解。", + tgbot.FullNameFromFirstAndLastName(c.Bot.Self.FirstName, c.Bot.Self.LastName), + c.Bot.Self.UserName, + )) + message.ParseMode = tgbotapi.ModeHTML + + c.Bot.MaySend(message) + + return nil, nil +} diff --git a/internal/bots/telegram/handlers/handlers.go b/internal/bots/telegram/handlers/handlers.go index 10f302a..4407789 100644 --- a/internal/bots/telegram/handlers/handlers.go +++ b/internal/bots/telegram/handlers/handlers.go @@ -3,6 +3,7 @@ package handlers import ( "go.uber.org/fx" + "github.com/nekomeowww/insights-bot/internal/bots/telegram/handlers/chatmigrate" "github.com/nekomeowww/insights-bot/internal/bots/telegram/handlers/recap" "github.com/nekomeowww/insights-bot/internal/bots/telegram/handlers/summarize" "github.com/nekomeowww/insights-bot/internal/bots/telegram/handlers/welcome" @@ -15,6 +16,7 @@ func NewModules() fx.Option { fx.Options(recap.NewModules()), fx.Options(summarize.NewModules()), fx.Options(welcome.NewModules()), + fx.Options(chatmigrate.NewModules()), ) } @@ -23,9 +25,10 @@ type NewHandlersParam struct { Dispatcher *tgbot.Dispatcher - RecapHandlers *recap.Handlers - SummarizeHandlers *summarize.Handlers - WelcomeHandlers *welcome.Handlers + RecapHandlers *recap.Handlers + SummarizeHandlers *summarize.Handlers + WelcomeHandlers *welcome.Handlers + ChatMigrationHandlers *chatmigrate.Handlers } type Handlers struct { @@ -41,6 +44,7 @@ func NewHandlers() func(param NewHandlersParam) *Handlers { param.SummarizeHandlers, param.RecapHandlers, param.WelcomeHandlers, + param.ChatMigrationHandlers, }, } } diff --git a/internal/bots/telegram/handlers/welcome/welcome.go b/internal/bots/telegram/handlers/welcome/welcome.go index 2fa6034..856f2c0 100644 --- a/internal/bots/telegram/handlers/welcome/welcome.go +++ b/internal/bots/telegram/handlers/welcome/welcome.go @@ -8,6 +8,7 @@ import ( "go.uber.org/fx" "github.com/nekomeowww/insights-bot/internal/models/chathistories" + "github.com/nekomeowww/insights-bot/internal/models/logs" "github.com/nekomeowww/insights-bot/internal/models/tgchats" "github.com/nekomeowww/insights-bot/pkg/bots/tgbot" "github.com/nekomeowww/insights-bot/pkg/logger" @@ -25,12 +26,14 @@ type NewHandlersParams struct { TgChats *tgchats.Model ChatHistories *chathistories.Model + Logs *logs.Model Logger *logger.Logger } type Handlers struct { tgchats *tgchats.Model chatHistories *chathistories.Model + logs *logs.Model logger *logger.Logger } @@ -39,6 +42,7 @@ func NewHandlers() func(param NewHandlersParams) *Handlers { return &Handlers{ tgchats: param.TgChats, chatHistories: param.ChatHistories, + logs: param.Logs, logger: param.Logger, } } @@ -101,6 +105,14 @@ func (h *Handlers) handleBotLeftChat(chatID int64) { return fmt.Errorf("failed to delete all chat histories by chat id %d: %w", chatID, err) } + return nil + }()) + may.Invoke(func() error { + err := h.logs.PruneAllLogsContentForChatID(chatID) + if err != nil { + return fmt.Errorf("failed to prune all related content for chat id %d: %w", chatID, err) + } + return nil }()) } @@ -109,11 +121,17 @@ func (h *Handlers) handleBotJoinChat(c *tgbot.Context) { msg := tgbotapi.NewMessage(c.Update.MyChatMember.Chat.ID, fmt.Sprintf(""+ "欢迎使用 @%s!\n\n"+ "- 如果要让我帮忙阅读网页文章,请直接使用开箱即用的命令 /smr@%s 要阅读"+ - "的链接;\n"+ + "的链接;\n\n"+ "- 如果想要我帮忙总结本群组的聊天记录,请以管理员身份将"+ "我配置为本群组的管理员(可以关闭所有权限),然后在非匿名和非其他身份的身"+ "份下(推荐,否则容易出现权限识别错误的情况)发送 /configure_recap@%s "+ "来开始配置本群组的聊天回顾功能。\n\n"+ + "- 如果你在授权 Bot 管理员之后希望 Bot 将已经记录的消息全数移除,可以通过撤销"+ + " Bot 的管理员权限来触发 Bot 的历史数据自动清理(如果该部分代码在分岔后未经修"+ + "改)。\n"+ + "- 如果你的群组尚未是超级群组(supergroup),那么消息链接引用将不会按照预期工"+ + "作,如果你需要使用消息链接引用功能,请通过短时间内将群组开放为公共群组并还原回"+ + "私有群组,或通过其他操作将本群组升级为超级群组后,该功能方可正常运作。\n\n"+ "如果还有疑问的话也可以执行帮助命令 /help@%s 来查看支持的命令,或者前往 Bot "+ "所在的开源仓库提交 Issue。\n\n"+ "祝你使用愉快!"+ diff --git a/internal/models/chathistories/chat_histories.go b/internal/models/chathistories/chat_histories.go index 5a0943b..c41adb2 100644 --- a/internal/models/chathistories/chat_histories.go +++ b/internal/models/chathistories/chat_histories.go @@ -24,6 +24,7 @@ import ( "github.com/nekomeowww/insights-bot/pkg/bots/tgbot" "github.com/nekomeowww/insights-bot/pkg/linkprev" "github.com/nekomeowww/insights-bot/pkg/logger" + "github.com/nekomeowww/insights-bot/pkg/types/telegram" ) type FromPlatform int @@ -306,6 +307,26 @@ func (m *Model) DeleteAllChatHistoriesByChatID(chatID int64) error { return nil } +func (m *Model) MigrateChatHistoriesOfChatFromChatIDToChatID(fromChatID, toChatID int64) error { + affectedRows, err := m.ent.ChatHistories. + Update(). + Where(chathistories.ChatID(fromChatID)). + SetChatID(toChatID). + SetChatType(string(telegram.ChatTypeSuperGroup)). + Save(context.Background()) + if err != nil { + return err + } + + m.logger.Info("successfully migrated options of chat", + zap.Int64("from_chat_id", fromChatID), + zap.Int64("to_chat_id", toChatID), + zap.Int("affected_rows", affectedRows), + ) + + return nil +} + func (m *Model) FindLastOneHourChatHistories(chatID int64) ([]*ent.ChatHistories, error) { return m.FindChatHistoriesByTimeBefore(chatID, time.Hour) } diff --git a/internal/models/logs/logs.go b/internal/models/logs/logs.go new file mode 100644 index 0000000..da42b1e --- /dev/null +++ b/internal/models/logs/logs.go @@ -0,0 +1,78 @@ +package logs + +import ( + "context" + + "github.com/nekomeowww/insights-bot/ent/logchathistoriesrecap" + "github.com/nekomeowww/insights-bot/internal/configs" + "github.com/nekomeowww/insights-bot/internal/datastore" + "github.com/nekomeowww/insights-bot/pkg/logger" + "go.uber.org/fx" + "go.uber.org/zap" +) + +type NewModelParams struct { + fx.In + + Config *configs.Config + Ent *datastore.Ent + Digger *datastore.AutoRecapTimeCapsuleDigger + Logger *logger.Logger +} + +type Model struct { + config *configs.Config + ent *datastore.Ent + logger *logger.Logger + digger *datastore.AutoRecapTimeCapsuleDigger +} + +func NewModel() func(NewModelParams) (*Model, error) { + return func(param NewModelParams) (*Model, error) { + return &Model{ + config: param.Config, + ent: param.Ent, + logger: param.Logger, + digger: param.Digger, + }, nil + } +} + +func (m *Model) PruneAllLogsContentForChatID(chatID int64) error { + err := m.ent.LogChatHistoriesRecap. + Update(). + Where( + logchathistoriesrecap.ChatIDEQ(chatID), + ). + SetRecapInputs(""). + SetRecapOutputs(""). + Exec(context.TODO()) + + if err != nil { + return err + } + + return nil +} + +func (m *Model) MigrateLogsOfChatFromChatIDToChatID(fromChatID int64, toChatID int64) error { + affectedRows, err := m.ent.LogChatHistoriesRecap. + Update(). + Where( + logchathistoriesrecap.ChatIDEQ(fromChatID), + ). + SetChatID(toChatID). + Save(context.TODO()) + + if err != nil { + return err + } + + m.logger.Info("successfully migrated options of chat", + zap.Int64("from_chat_id", fromChatID), + zap.Int64("to_chat_id", toChatID), + zap.Int("affected_rows", affectedRows), + ) + + return nil +} diff --git a/internal/models/models.go b/internal/models/models.go index a05225b..2660e21 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -4,6 +4,7 @@ import ( "go.uber.org/fx" "github.com/nekomeowww/insights-bot/internal/models/chathistories" + "github.com/nekomeowww/insights-bot/internal/models/logs" "github.com/nekomeowww/insights-bot/internal/models/smr" "github.com/nekomeowww/insights-bot/internal/models/tgchats" ) @@ -13,5 +14,6 @@ func NewModules() fx.Option { fx.Provide(chathistories.NewModel()), fx.Provide(tgchats.NewModel()), fx.Provide(smr.NewModel()), + fx.Provide(logs.NewModel()), ) } diff --git a/internal/models/tgchats/auto_recaps_subscribers.go b/internal/models/tgchats/auto_recaps_subscribers.go index e68ac01..e34a994 100644 --- a/internal/models/tgchats/auto_recaps_subscribers.go +++ b/internal/models/tgchats/auto_recaps_subscribers.go @@ -5,6 +5,7 @@ import ( "github.com/nekomeowww/insights-bot/ent" "github.com/nekomeowww/insights-bot/ent/telegramchatautorecapssubscribers" + "go.uber.org/zap" ) func (m *Model) FindOneAutoRecapsSubscriber(chatID int64, userID int64) (*ent.TelegramChatAutoRecapsSubscribers, error) { @@ -83,3 +84,22 @@ func (m *Model) DeleteAllSubscribersByChatID(chatID int64) error { return nil } + +func (m *Model) MigrateSubscribersOfChatFromChatIDToChatID(fromChatID int64, toChatID int64) error { + affectedRows, err := m.ent.TelegramChatAutoRecapsSubscribers. + Update(). + Where(telegramchatautorecapssubscribers.ChatID(fromChatID)). + SetChatID(toChatID). + Save(context.Background()) + if err != nil { + return err + } + + m.logger.Info("successfully migrated options of chat", + zap.Int64("from_chat_id", fromChatID), + zap.Int64("to_chat_id", toChatID), + zap.Int("affected_rows", affectedRows), + ) + + return nil +} diff --git a/internal/models/tgchats/feature_flags.go b/internal/models/tgchats/feature_flags.go index 0e1c379..9281fe2 100644 --- a/internal/models/tgchats/feature_flags.go +++ b/internal/models/tgchats/feature_flags.go @@ -226,3 +226,25 @@ func (m *Model) DeleteOneFeatureFlagByChatID(chatID int64) error { return nil } + +func (m *Model) MigrateFeatureFlagsOfChatFromChatIDToChatID(fromChatID int64, toChatID int64) error { + affectedRows, err := m.ent.TelegramChatFeatureFlags. + Update(). + Where( + telegramchatfeatureflags.ChatIDEQ(fromChatID), + ). + SetChatID(toChatID). + SetChatType(string(telegram.ChatTypeSuperGroup)). + Save(context.Background()) + if err != nil { + return err + } + + m.logger.Info("successfully migrated feature flags of chat", + zap.Int64("from_chat_id", fromChatID), + zap.Int64("to_chat_id", toChatID), + zap.Int("affected_rows", affectedRows), + ) + + return nil +} diff --git a/internal/models/tgchats/recaps_options.go b/internal/models/tgchats/recaps_options.go index 969b035..15e557d 100644 --- a/internal/models/tgchats/recaps_options.go +++ b/internal/models/tgchats/recaps_options.go @@ -7,6 +7,7 @@ import ( "github.com/nekomeowww/insights-bot/ent" "github.com/nekomeowww/insights-bot/ent/telegramchatrecapsoptions" "github.com/nekomeowww/insights-bot/pkg/types/tgchat" + "go.uber.org/zap" ) func (m *Model) FindOneRecapsOption(chatID int64) (*ent.TelegramChatRecapsOptions, error) { @@ -72,3 +73,25 @@ func (m *Model) DeleteOneOptionByChatID(chatID int64) error { return nil } + +func (m *Model) MigrateOptionOfChatFromChatIDToChatID(fromChatID int64, toChatID int64) error { + affectedRows, err := m.ent.TelegramChatRecapsOptions. + Update(). + Where( + telegramchatrecapsoptions.ChatIDEQ(fromChatID), + ). + SetChatID(toChatID). + Save(context.Background()) + + if err != nil { + return err + } + + m.logger.Info("successfully migrated options of chat", + zap.Int64("from_chat_id", fromChatID), + zap.Int64("to_chat_id", toChatID), + zap.Int("affected_rows", affectedRows), + ) + + return nil +} diff --git a/pkg/bots/tgbot/context.go b/pkg/bots/tgbot/context.go index 014287c..7343593 100644 --- a/pkg/bots/tgbot/context.go +++ b/pkg/bots/tgbot/context.go @@ -33,6 +33,8 @@ const ( UpdateTypeLeftChatMember UpdateType = "left_chat_member" UpdateTypeNewChatMembers UpdateType = "new_chat_members" UpdateTypeChatJoinRequest UpdateType = "chat_join_request" + UpdateTypeChatMigrationFrom UpdateType = "chat_migration_from" + UpdateTypeChatMigrationTo UpdateType = "chat_migration_to" ) type Context struct { @@ -76,6 +78,10 @@ func (c *Context) UpdateType() UpdateType { return UpdateTypeNewChatMembers case c.Update.Message.LeftChatMember != nil: return UpdateTypeLeftChatMember + case c.Update.Message.MigrateFromChatID != 0: + return UpdateTypeChatMigrationFrom + case c.Update.Message.MigrateToChatID != 0: + return UpdateTypeChatMigrationTo default: return UpdateTypeMessage } diff --git a/pkg/bots/tgbot/dispatcher.go b/pkg/bots/tgbot/dispatcher.go index 1a345d9..01c9abf 100644 --- a/pkg/bots/tgbot/dispatcher.go +++ b/pkg/bots/tgbot/dispatcher.go @@ -30,6 +30,7 @@ type Dispatcher struct { leftChatMemberHandlers []Handler newChatMembersHandlers []Handler myChatMemberHandlers []Handler + chatMigrationFromHandlers []Handler } func NewDispatcher() func(logger *logger.Logger) *Dispatcher { @@ -47,6 +48,7 @@ func NewDispatcher() func(logger *logger.Logger) *Dispatcher { leftChatMemberHandlers: make([]Handler, 0), newChatMembersHandlers: make([]Handler, 0), myChatMemberHandlers: make([]Handler, 0), + chatMigrationFromHandlers: make([]Handler, 0), } d.startCommandHandler.helpCommandHandler = d.helpCommand @@ -360,6 +362,34 @@ func (d *Dispatcher) dispatchNewChatMember(c *Context) { }) } +func (d *Dispatcher) OnChatMigrationFrom(h Handler) { + d.chatMigrationFromHandlers = append(d.chatMigrationFromHandlers, h) +} + +func (d *Dispatcher) dispatchChatMigrationFrom(c *Context) { + d.Logger.Debug(fmt.Sprintf("[群组迁移] 超级群组 [%s (%s)] 已迁移自群组 [%s (%s)]", + color.FgGreen.Render(c.Update.Message.Chat.Title), + color.FgYellow.Render(c.Update.Message.Chat.ID), + color.FgGreen.Render(c.Update.Message.Chat.Title), + color.FgYellow.Render(c.Update.Message.MigrateFromChatID), + )) + + d.dispatchInGoroutine(func() { + for _, h := range d.chatMigrationFromHandlers { + _, _ = h.Handle(c) + } + }) +} + +func (d *Dispatcher) dispatchChatMigrationTo(c *Context) { + d.Logger.Debug(fmt.Sprintf("[群组迁移] 群组 [%s (%s)] 已迁移至超级群组 [%s (%s)]", + color.FgGreen.Render(c.Update.Message.Chat.Title), + color.FgYellow.Render(c.Update.Message.Chat.ID), + color.FgGreen.Render(c.Update.Message.Chat.Title), + color.FgYellow.Render(c.Update.Message.MigrateToChatID), + )) +} + func (d *Dispatcher) Dispatch(bot *tgbotapi.BotAPI, update tgbotapi.Update, rueidisClient rueidis.Client) { for _, m := range d.middlewares { m(NewContext(bot, update, d.Logger, rueidisClient), func() {}) @@ -370,39 +400,43 @@ func (d *Dispatcher) Dispatch(bot *tgbotapi.BotAPI, update tgbotapi.Update, ruei case UpdateTypeMessage: d.dispatchMessage(ctx) case UpdateTypeEditedMessage: - d.Logger.Warn("edited message is not supported yet") + d.Logger.Debug("edited message is not supported yet") case UpdateTypeChannelPost: d.dispatchChannelPost(ctx) case UpdateTypeEditedChannelPost: - d.Logger.Warn("edited channel post is not supported yet") + d.Logger.Debug("edited channel post is not supported yet") case UpdateTypeInlineQuery: - d.Logger.Warn("inline query is not supported yet") + d.Logger.Debug("inline query is not supported yet") case UpdateTypeChosenInlineResult: - d.Logger.Warn("chosen inline result is not supported yet") + d.Logger.Debug("chosen inline result is not supported yet") case UpdateTypeCallbackQuery: d.dispatchCallbackQuery(ctx) case UpdateTypeShippingQuery: - d.Logger.Warn("shipping query is not supported yet") + d.Logger.Debug("shipping query is not supported yet") case UpdateTypePreCheckoutQuery: - d.Logger.Warn("pre checkout query is not supported yet") + d.Logger.Debug("pre checkout query is not supported yet") case UpdateTypePoll: - d.Logger.Warn("poll is not supported yet") + d.Logger.Debug("poll is not supported yet") case UpdateTypePollAnswer: - d.Logger.Warn("poll answer is not supported yet") + d.Logger.Debug("poll answer is not supported yet") case UpdateTypeMyChatMember: d.dispatchMyChatMember(ctx) case UpdateTypeChatMember: - d.Logger.Warn("chat member is not supported yet") + d.Logger.Debug("chat member is not supported yet") case UpdateTypeLeftChatMember: d.dispatchLeftChatMember(ctx) case UpdateTypeNewChatMembers: d.dispatchNewChatMember(ctx) case UpdateTypeChatJoinRequest: - d.Logger.Warn("chat join request is not supported yet") + d.Logger.Debug("chat join request is not supported yet") + case UpdateTypeChatMigrationFrom: + d.dispatchChatMigrationFrom(ctx) + case UpdateTypeChatMigrationTo: + d.dispatchChatMigrationTo(ctx) case UpdateTypeUnknown: - d.Logger.Warn("unable to dispatch update due to unknown update type") + d.Logger.Debug("unable to dispatch update due to unknown update type") default: - d.Logger.Warn("unable to dispatch update due to unknown update type", zap.String("update_type", string(ctx.UpdateType()))) + d.Logger.Debug("unable to dispatch update due to unknown update type", zap.String("update_type", string(ctx.UpdateType()))) } }