From 7ca6beefb037d946b2278f9182cde5d53246f09a Mon Sep 17 00:00:00 2001 From: hrvadl Date: Sun, 9 Jun 2024 15:32:04 +0300 Subject: [PATCH] feat: improved user acceptance flow --- .golangci.yaml | 1 - .../callback/callbackdata/decisions.go | 8 ++--- .../handler/callback/callbackdata/parser.go | 18 +++++++--- internal/handler/callback/handler.go | 8 ++--- internal/handler/join/handler.go | 34 ++++++++++++------- internal/messages/terms.go | 2 -- 6 files changed, 44 insertions(+), 27 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index e813d0e..8e883fd 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -25,7 +25,6 @@ linters: - gochecknoinits # Checks that no init functions are present in Go code. - godot # Check if comments end in a period - godox # Tool for detection of FIXME, TODO and other comment keywords - - err113 # Golang linter to check the errors handling expressions - gomnd # An analyzer to detect magic numbers - ireturn # Accept Interfaces, Return Concrete Types - interfacebloat # A linter that checks the number of methods inside an interface diff --git a/internal/handler/callback/callbackdata/decisions.go b/internal/handler/callback/callbackdata/decisions.go index 06a63c9..5b9bf3c 100644 --- a/internal/handler/callback/callbackdata/decisions.go +++ b/internal/handler/callback/callbackdata/decisions.go @@ -7,10 +7,10 @@ const ( DeclineDecision = "decline" ) -func NewAgreeWithGroupID(groupdID int64) string { - return fmt.Sprintf("%s_%v", AgreeDecision, groupdID) +func NewAgreeWithGroupID(groupdID int64, msgID int) string { + return fmt.Sprintf("%s_%d_%d", AgreeDecision, groupdID, msgID) } -func NewDeclineWithGroupID(groupdID int64) string { - return fmt.Sprintf("%s_%v", DeclineDecision, groupdID) +func NewDeclineWithGroupID(groupdID int64, msgID int) string { + return fmt.Sprintf("%s_%d_%d", DeclineDecision, groupdID, msgID) } diff --git a/internal/handler/callback/callbackdata/parser.go b/internal/handler/callback/callbackdata/parser.go index 680ac38..590017c 100644 --- a/internal/handler/callback/callbackdata/parser.go +++ b/internal/handler/callback/callbackdata/parser.go @@ -7,13 +7,14 @@ import ( ) type Payload struct { - Decision string - GroupID int64 + Decision string + GroupID int64 + MessageID int } func Parse(data string) (*Payload, error) { splits := strings.Split(data, "_") - if len(splits) != 2 { //nolint:gomnd,mnd + if len(splits) != 3 { //nolint:gomnd,mnd return nil, fmt.Errorf("invalid callback query data token: %v", splits) } @@ -22,10 +23,19 @@ func Parse(data string) (*Payload, error) { return nil, fmt.Errorf("invalid groupID in callback query data: %s", splits[1]) } + messageID, err := strconv.Atoi(splits[2]) + if err != nil { + return nil, fmt.Errorf("invalid groupID in callback query data: %s", splits[1]) + } + decision := splits[0] if decision != AgreeDecision && decision != DeclineDecision { return nil, fmt.Errorf("invalid callback data for terms of use decision: %v", decision) } - return &Payload{decision, groupID}, nil + return &Payload{ + Decision: decision, + GroupID: groupID, + MessageID: messageID, + }, nil } diff --git a/internal/handler/callback/handler.go b/internal/handler/callback/handler.go index 3b09613..b59b0a3 100644 --- a/internal/handler/callback/handler.go +++ b/internal/handler/callback/handler.go @@ -67,10 +67,10 @@ func (h *handler) callbackQuery(ctx context.Context, bot *telego.Bot, query tele msg = fmt.Sprintf(messages.Decline, viper.GetString("admin-username")) } - _, err = bot.SendMessage(&telego.SendMessageParams{ - ChatID: tu.ID(query.From.ID), - Text: msg, - ReplyMarkup: tu.ReplyKeyboardRemove(), + _, err = bot.EditMessageText(&telego.EditMessageTextParams{ + MessageID: data.MessageID, + ChatID: tu.ID(query.From.ID), + Text: msg, }) if err != nil { log.Error("Sending decision message failed", slog.Any("error", err)) diff --git a/internal/handler/join/handler.go b/internal/handler/join/handler.go index def5117..fbff10a 100644 --- a/internal/handler/join/handler.go +++ b/internal/handler/join/handler.go @@ -70,30 +70,40 @@ func (h *handler) chatJoinRequest(ctx context.Context, bot *telego.Bot, request return } + _, err := bot.SendMessage(&telego.SendMessageParams{ + ChatID: tu.ID(request.From.ID), + ParseMode: telego.ModeHTML, + Text: messages.JoinHeader + messages.Rules, + }) + if err != nil { + log.Error("Sending TermsOfUse and Rules message failed", slog.Any("error", err)) + } + + msg := tu.Message(tu.ID(request.From.ID), messages.JoinFooter) + toEdit, err := bot.SendMessage(msg) + if err != nil { + log.Error("Sending terms of use failed", slog.Any("error", err)) + } + k := tu.InlineKeyboard( tu.InlineKeyboardRow( telego.InlineKeyboardButton{ Text: AgreeText, - CallbackData: callbackdata.NewAgreeWithGroupID(request.Chat.ID), + CallbackData: callbackdata.NewAgreeWithGroupID(request.Chat.ID, toEdit.MessageID), }, telego.InlineKeyboardButton{ Text: DontAgreeText, - CallbackData: callbackdata.NewDeclineWithGroupID(request.Chat.ID), + CallbackData: callbackdata.NewDeclineWithGroupID(request.Chat.ID, toEdit.MessageID), }, ), ) - _, err := bot.SendMessage(&telego.SendMessageParams{ - ChatID: tu.ID(request.From.ID), - ParseMode: telego.ModeHTML, - Text: messages.JoinHeader + messages.Rules, + _, err = bot.EditMessageReplyMarkup(&telego.EditMessageReplyMarkupParams{ + ReplyMarkup: k, + ChatID: tu.ID(request.From.ID), + MessageID: toEdit.MessageID, }) if err != nil { - log.Error("Sending TermsOfUse and Rules message failed", slog.Any("error", err)) - } - - msg := tu.Message(tu.ID(request.From.ID), messages.JoinFooter).WithReplyMarkup(k).WithProtectContent() - if _, err := bot.SendMessage(msg); err != nil { - log.Error("Sending terms of use failed", slog.Any("error", err)) + log.Error("Editing callback query failed", slog.Any("error", err)) } } diff --git a/internal/messages/terms.go b/internal/messages/terms.go index 2cd9ced..73ca98f 100644 --- a/internal/messages/terms.go +++ b/internal/messages/terms.go @@ -6,8 +6,6 @@ const JoinHeader = ` //nolint:lll const JoinFooter = ` -Перед тим як прийняти рішення, будь ласка, привітайтесь з ботом, написавши довільне повідомлення. Після цього ви зможете натиснути на потрібну кнопну та отримати результат вашого запиту. - Приймаючи запрошення в цю групу ви автоматично: 1. Засуджуєте війну рф проти України. 2. Не визнаєте тимчасовано окупованії українські території субʼєктом рф.