From 8074db6b644a0ba1637916efb41f1ab4f4bb30ff Mon Sep 17 00:00:00 2001 From: LemonNeko Date: Tue, 7 May 2024 00:37:30 +0800 Subject: [PATCH 1/5] feat: provide retry button when smr failed to read --- .../summarize/retry_callback_query.go | 32 +++++++++++++ .../telegram/handlers/summarize/summarize.go | 1 + internal/services/smr/processor.go | 47 ++++++++++++++++--- locales/en.yaml | 1 + locales/zh-CN.yaml | 1 + 5 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 internal/bots/telegram/handlers/summarize/retry_callback_query.go diff --git a/internal/bots/telegram/handlers/summarize/retry_callback_query.go b/internal/bots/telegram/handlers/summarize/retry_callback_query.go new file mode 100644 index 0000000..330180b --- /dev/null +++ b/internal/bots/telegram/handlers/summarize/retry_callback_query.go @@ -0,0 +1,32 @@ +package summarize + +import ( + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/nekomeowww/insights-bot/pkg/bots/tgbot" + "github.com/nekomeowww/insights-bot/pkg/types/smr" + "go.uber.org/zap" +) + +func (h *Handlers) handleCallbackQueryRetry(c *tgbot.Context) (tgbot.Response, error) { + messageID := c.Update.CallbackQuery.Message.MessageID + var data smr.TaskInfo + + err := c.BindFromCallbackQueryData(&data) + if err != nil { + h.logger.Error("failed to bind callback query data when retry smr", + zap.Error(err), + zap.Int("message_id", messageID), + zap.Int64("chat_id", c.Update.CallbackQuery.Message.Chat.ID), + zap.Int64("from_id", c.Update.CallbackQuery.From.ID), + zap.String("data", c.Update.CallbackQuery.Data), + ) + + return nil, nil + } + + h.smrQueue.AddTask(data) + // remove the retry button + c.Bot.MayRequest(tgbotapi.NewEditMessageTextAndMarkup(data.ChatID, messageID, h.i18n.TWithLanguage(data.Language, "commands.groups.summarization.commands.smr.reading"), tgbotapi.InlineKeyboardMarkup{})) + + return nil, nil +} diff --git a/internal/bots/telegram/handlers/summarize/summarize.go b/internal/bots/telegram/handlers/summarize/summarize.go index c2c8aff..fa640ae 100644 --- a/internal/bots/telegram/handlers/summarize/summarize.go +++ b/internal/bots/telegram/handlers/summarize/summarize.go @@ -61,4 +61,5 @@ func (h *Handlers) Install(dispatcher *tgbot.Dispatcher) { dispatcher.OnChannelPost(tgbot.NewHandler(h.HandleChannelPost)) dispatcher.OnCallbackQuery("smr/summarization/feedback/react", tgbot.NewHandler(h.handleCallbackQueryReact)) + dispatcher.OnCallbackQuery("smr/summarization/retry", tgbot.NewHandler(h.handleCallbackQueryRetry)) } diff --git a/internal/services/smr/processor.go b/internal/services/smr/processor.go index 5777695..dc62e9c 100644 --- a/internal/services/smr/processor.go +++ b/internal/services/smr/processor.go @@ -18,7 +18,7 @@ import ( "go.uber.org/zap" ) -func (s *Service) processOutput(info types.TaskInfo, result *smr.URLSummarizationOutput) string { +func (s *Service) formatOutput(info types.TaskInfo, result *smr.URLSummarizationOutput) string { switch info.Platform { case bot.FromPlatformTelegram: return result.FormatSummarizationAsHTML() @@ -31,7 +31,7 @@ func (s *Service) processOutput(info types.TaskInfo, result *smr.URLSummarizatio } } -func (s *Service) processError(err error, language string) string { +func (s *Service) formatError(err error, language string) string { if errors.Is(err, smr.ErrContentNotSupported) { return s.i18n.TWithLanguage(language, "commands.groups.summarization.commands.smr.contentNotSupported") } else if errors.Is(err, smr.ErrNetworkError) || errors.Is(err, smr.ErrRequestFailed) { @@ -41,7 +41,22 @@ func (s *Service) processError(err error, language string) string { return s.i18n.TWithLanguage(language, "commands.groups.summarization.commands.smr.failedToRead") } -func (s *Service) sendResult(output *smr.URLSummarizationOutput, info types.TaskInfo, result string) { +func (s *Service) newRetryButtonMarkup(info types.TaskInfo) (tgbotapi.InlineKeyboardMarkup, error) { + data, err := s.tgBot.Bot().AssignOneCallbackQueryData("smr/summarization/retry", &info) + + if err != nil { + return tgbotapi.InlineKeyboardMarkup{}, err + } + + return tgbotapi.NewInlineKeyboardMarkup([]tgbotapi.InlineKeyboardButton{ + { + Text: s.i18n.TWithLanguage(info.Language, "commands.groups.summarization.commands.smr.retry"), + CallbackData: &data, + }, + }), nil +} + +func (s *Service) sendResult(output *smr.URLSummarizationOutput, info types.TaskInfo, result string, provideRetryButton bool) { switch info.Platform { case bot.FromPlatformTelegram: msgEdit := tgbotapi.EditMessageTextConfig{ @@ -53,6 +68,22 @@ func (s *Service) sendResult(output *smr.URLSummarizationOutput, info types.Task ParseMode: tgbotapi.ModeHTML, } + if provideRetryButton { + var err error + retryButtonMarkup, err := s.newRetryButtonMarkup(info) + if err != nil { + s.logger.Error("smr service: failed to create retry button markup", + zap.Error(err), + zap.Int64("chat_id", info.ChatID), + zap.String("platform", info.Platform.String()), + ) + + return + } + + msgEdit.ReplyMarkup = &retryButtonMarkup + } + if output == nil { _, err := s.tgBot.Send(msgEdit) if err != nil { @@ -99,6 +130,7 @@ func (s *Service) sendResult(output *smr.URLSummarizationOutput, info types.Task ) } case bot.FromPlatformSlack: + // TODO: provide retry button token, err := s.ent.SlackOAuthCredentials.Query(). Where(slackoauthcredentials.TeamID(info.TeamID)). First(context.Background()) @@ -127,6 +159,7 @@ func (s *Service) sendResult(output *smr.URLSummarizationOutput, info types.Task ) } case bot.FromPlatformDiscord: + // TODO: provide retry button channelID, _ := snowflake.Parse(info.ChannelID) _, err := s.discordBot.Rest(). CreateMessage(channelID, discord.NewMessageCreateBuilder(). @@ -174,12 +207,12 @@ func (s *Service) processor(info types.TaskInfo) { smrResult, err := s.model.SummarizeInputURL(ctx, info.URL, info.Platform) if err != nil { s.logger.Warn("smr service: summarization failed", zap.Error(err)) - errStr := s.processError(err, lo.Ternary(info.Language == "", "en", info.Language)) - s.sendResult(nil, info, errStr) + errStr := s.formatError(err, lo.Ternary(info.Language == "", "en", info.Language)) + s.sendResult(nil, info, errStr, true) return } - finalResult := s.processOutput(info, smrResult) - s.sendResult(smrResult, info, finalResult) + finalResult := s.formatOutput(info, smrResult) + s.sendResult(smrResult, info, finalResult, false) } diff --git a/locales/en.yaml b/locales/en.yaml index 1f71388..38f43e5 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -80,6 +80,7 @@ commands: failedToRead: Quantum Speed-Reading was unsuccessful. Would you like to retry? failedToReadDueToFailedToFetch: Encountered an issue retrieving the content for Quantum Speed-Reading. Perhaps another attempt might succeed? contentNotSupported: This content is not supported by Quantum Speed-Reading. Considering another link might be beneficial. + retry: Retry prompts: smr: diff --git a/locales/zh-CN.yaml b/locales/zh-CN.yaml index a5ee322..ec0551b 100644 --- a/locales/zh-CN.yaml +++ b/locales/zh-CN.yaml @@ -37,6 +37,7 @@ commands: failedToReadDueToFailedToFetch: 量子速读的链接读取失败了哦。可以再试试? contentNotSupported: 暂时不支持量子速读这样的内容呢,可以换个别的链接试试。 permissionDenied: 本应用没有权限向这个频道发送消息,尝试重新安装一下? + retry: 重试 modules: telegram: From cc1d33bc2842ba112a5dc520091af74a4eacf052 Mon Sep 17 00:00:00 2001 From: LemonNeko Date: Tue, 7 May 2024 12:05:01 +0800 Subject: [PATCH 2/5] should not provide retry button when content is not supported --- internal/services/smr/processor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/services/smr/processor.go b/internal/services/smr/processor.go index dc62e9c..cf19434 100644 --- a/internal/services/smr/processor.go +++ b/internal/services/smr/processor.go @@ -208,7 +208,7 @@ func (s *Service) processor(info types.TaskInfo) { if err != nil { s.logger.Warn("smr service: summarization failed", zap.Error(err)) errStr := s.formatError(err, lo.Ternary(info.Language == "", "en", info.Language)) - s.sendResult(nil, info, errStr, true) + s.sendResult(nil, info, errStr, !errors.Is(err, smr.ErrContentNotSupported)) return } From 202af4bda0a081b30ef1f5c00d03b74869fe463f Mon Sep 17 00:00:00 2001 From: LemonNeko Date: Tue, 7 May 2024 12:06:35 +0800 Subject: [PATCH 3/5] fix ent generation check --- go.sum | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/go.sum b/go.sum index 61071df..c7ffd80 100644 --- a/go.sum +++ b/go.sum @@ -130,6 +130,8 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/maxbrunsfeld/counterfeiter/v6 v6.6.1 h1:9XE5ykDiC8eNSqIPkxx0EsV3kMX1oe4kQWRZjIgytUA= @@ -151,6 +153,8 @@ github.com/nekomeowww/xo v1.4.0 h1:aueb6SZPV5yF8Eauir8WF7iCBCa0Wjkrw6148y8iCsA= github.com/nekomeowww/xo v1.4.0/go.mod h1:2puSnnYUtvKHV3krZfCRolEqTv9nuU+I59GhxADADFY= github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM= github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM= github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= @@ -193,6 +197,10 @@ github.com/slack-go/slack v0.12.5 h1:ddZ6uz6XVaB+3MTDhoW04gG+Vc/M/X1ctC+wssy2cqs github.com/slack-go/slack v0.12.5/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= From 4f8578b541f5d7cedfa162dbcefc15e8d8128f39 Mon Sep 17 00:00:00 2001 From: LemonNeko Date: Tue, 7 May 2024 12:08:43 +0800 Subject: [PATCH 4/5] fix lint issues --- internal/services/smr/processor.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/services/smr/processor.go b/internal/services/smr/processor.go index cf19434..61d89ed 100644 --- a/internal/services/smr/processor.go +++ b/internal/services/smr/processor.go @@ -71,6 +71,7 @@ func (s *Service) sendResult(output *smr.URLSummarizationOutput, info types.Task if provideRetryButton { var err error retryButtonMarkup, err := s.newRetryButtonMarkup(info) + if err != nil { s.logger.Error("smr service: failed to create retry button markup", zap.Error(err), From d43ab971b9ba7f17cce766e5cc0d63245d9c6943 Mon Sep 17 00:00:00 2001 From: LemonNeko Date: Tue, 7 May 2024 12:31:00 +0800 Subject: [PATCH 5/5] fix: failed to remove retry button --- .../handlers/summarize/retry_callback_query.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/internal/bots/telegram/handlers/summarize/retry_callback_query.go b/internal/bots/telegram/handlers/summarize/retry_callback_query.go index 330180b..8e2ceb8 100644 --- a/internal/bots/telegram/handlers/summarize/retry_callback_query.go +++ b/internal/bots/telegram/handlers/summarize/retry_callback_query.go @@ -24,9 +24,21 @@ func (h *Handlers) handleCallbackQueryRetry(c *tgbot.Context) (tgbot.Response, e return nil, nil } - h.smrQueue.AddTask(data) + err = h.smrQueue.AddTask(data) + + if err != nil { + h.logger.Error("failed to move task back to queue", zap.Error(err)) + return nil, nil + } + // remove the retry button - c.Bot.MayRequest(tgbotapi.NewEditMessageTextAndMarkup(data.ChatID, messageID, h.i18n.TWithLanguage(data.Language, "commands.groups.summarization.commands.smr.reading"), tgbotapi.InlineKeyboardMarkup{})) + c.Bot.MayRequest(tgbotapi.NewEditMessageTextAndMarkup( + data.ChatID, + messageID, + h.i18n.TWithLanguage(data.Language, "commands.groups.summarization.commands.smr.reading"), + tgbotapi.InlineKeyboardMarkup{ + InlineKeyboard: [][]tgbotapi.InlineKeyboardButton{}, + })) return nil, nil }