package handler import ( "encoding/json" "errors" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db/model" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/iface" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/store" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/util" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/locale" "github.com/mymmrac/telego" tu "github.com/mymmrac/telego/telegoutil" ) type CallbackQueryHandler struct { app iface.App } func NewCallbackQueryHandler(app iface.App) Handler { return &CallbackQueryHandler{app: app} } func (h *CallbackQueryHandler) Handle(wh telego.Update) error { cq := wh.CallbackQuery user, err := h.app.DB().ForUser().ByTelegramID(cq.From.ID) if err != nil { return err } if user != nil && user.ID > 0 { return h.handleSetupKey(cq, user) } return errors.New("not implemented yet") } func (h *CallbackQueryHandler) handleSetupKey(cq *telego.CallbackQuery, user *model.User) error { var pl util.Payload if err := json.Unmarshal([]byte(cq.Data), &pl); err != nil { return err } switch pl.Action { case util.PayloadActionChooseKeyboard: return h.handleChooseKeyboard(pl, cq.Message.GetMessageID(), user) case util.PayloadActionYesNo: answer := pl.YesNoAnswer() switch answer.Type { case util.QuestionTypeRedmine: return h.handleAnswerRedmine(answer, pl.Chat, cq.Message.GetMessageID(), user) case util.QuestionTypeRedmineHours: return h.handleAnswerRedmineHours(answer, pl.Chat, cq.Message.GetMessageID(), user) case util.QuestionTypeRedmineSendResult: return h.handleAnswerRedmineSendResults(answer, cq.Message.GetMessageID(), user) } default: return nil } return nil } func (h *CallbackQueryHandler) handleChooseKeyboard(pl util.Payload, msgID int, user *model.User) error { cr := h.app.DB().ForChat() result := pl.KeyboardChoice() if pl.User != user.TelegramID { return nil } chat, err := cr.ByTelegramID(pl.Chat) if err != nil { return err } if chat == nil || chat.ID == 0 { return nil } chat.KeyboardType = model.KeyboardType(result.Type) if err := cr.Save(chat); err != nil { return err } kbTypeName := "standard_vote_keyboard" if model.KeyboardType(result.Type) == model.StoryPointsKeyboard { kbTypeName = "sp_vote_keyboard" } loc := h.app.Localizer(user.Language) _, _ = h.app.TG().EditMessageText(&telego.EditMessageTextParams{ ChatID: tu.ID(user.ChatID), MessageID: msgID, Text: loc.Template("chosen_keyboard", map[string]interface{}{"Name": loc.Message(kbTypeName)}), }) _, err = h.app.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(user.ChatID), Text: loc.Message("ask_for_redmine"), ParseMode: telego.ModeMarkdown, ReplyMarkup: &telego.InlineKeyboardMarkup{InlineKeyboard: [][]telego.InlineKeyboardButton{ { { Text: loc.Message("yes"), CallbackData: util.NewRedmineQuestionPayload(user.TelegramID, chat.TelegramID, true).String(), }, { Text: loc.Message("no"), CallbackData: util.NewRedmineQuestionPayload(user.TelegramID, chat.TelegramID, false).String(), }, }, }}, }) return err } func (h *CallbackQueryHandler) handleAnswerRedmine(answer util.Answer, chatID int64, msgID int, user *model.User) error { loc := h.app.Localizer(user.Language) if !answer.Result { _, _ = h.app.TG().EditMessageText(&telego.EditMessageTextParams{ ChatID: tu.ID(user.ChatID), MessageID: msgID, Text: loc.Message("redmine_will_not_be_configured"), }) return util.SendSetupDone(h.app.TG(), user.ChatID, loc) } _, err := h.app.TG().EditMessageText(&telego.EditMessageTextParams{ ChatID: tu.ID(user.ChatID), MessageID: msgID, Text: loc.Message("please_send_redmine_url"), }) store.RedmineSetups.Set(user.ChatID, &store.RedmineSetup{Chat: chatID}) return err } func (h *CallbackQueryHandler) handleAnswerRedmineHours(answer util.Answer, chatID int64, msgID int, user *model.User) error { loc := h.app.Localizer(user.Language) message := "redmine_hours_will_not_be_configured" if answer.Result { message = "redmine_hours_will_be_configured" } _, _ = h.app.TG().EditMessageText(&telego.EditMessageTextParams{ ChatID: tu.ID(user.ChatID), MessageID: msgID, Text: loc.Message(message), }) rs, found := store.RedmineSetups.Get(user.ChatID) if found { rs.SaveHours = answer.Result if err := h.updateRedmineIntegration(rs, loc, user); err != nil { return err } } _, err := h.app.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(user.ChatID), Text: loc.Message("should_send_poker_to_redmine"), ParseMode: telego.ModeMarkdown, ReplyMarkup: &telego.InlineKeyboardMarkup{InlineKeyboard: [][]telego.InlineKeyboardButton{ { { Text: loc.Message("yes"), CallbackData: util.NewRedmineSendResultQuestionPayload(user.TelegramID, chatID, true).String(), }, { Text: loc.Message("no"), CallbackData: util.NewRedmineSendResultQuestionPayload(user.TelegramID, chatID, false).String(), }, }, }}, }) return err } func (h *CallbackQueryHandler) handleAnswerRedmineSendResults(answer util.Answer, msgID int, user *model.User) error { loc := h.app.Localizer(user.Language) if !answer.Result { _, _ = h.app.TG().EditMessageText(&telego.EditMessageTextParams{ ChatID: tu.ID(user.ChatID), MessageID: msgID, Text: loc.Message("redmine_poker_will_not_be_configured"), }) return util.SendSetupDone(h.app.TG(), user.ChatID, loc) } _, err := h.app.TG().EditMessageText(&telego.EditMessageTextParams{ ChatID: tu.ID(user.ChatID), MessageID: msgID, Text: loc.Message("specify_result_field"), }) rs, _ := store.RedmineSetups.Get(user.ChatID) rs.WaitingForSPField = true return err } func (h *CallbackQueryHandler) updateRedmineIntegration(rs *store.RedmineSetup, loc locale.Localizer, user *model.User) error { dbChat, err := h.app.DB().ForChat().ByTelegramID(rs.Chat) if dbChat == nil || dbChat.ID == 0 { _ = util.SendInternalError(h.app.TG(), user.ChatID, loc) return err } savedRedmine, err := h.app.DB().ForIntegration().LoadForChatAndType(dbChat.ID, model.RedmineIntegration) if savedRedmine == nil || savedRedmine.ID == 0 { _ = util.SendInternalError(h.app.TG(), user.ChatID, loc) return err } var shouldUpdate bool savedRS := savedRedmine.LoadRedmine() if savedRS.SaveHours != rs.SaveHours { savedRS.SaveHours = rs.SaveHours shouldUpdate = true } if savedRS.SPFieldName != rs.SPFieldName { savedRS.SPFieldName = rs.SPFieldName shouldUpdate = true } if shouldUpdate { savedRedmine.StoreRedmine(savedRS) return h.app.DB().ForIntegration().Save(savedRedmine) } return nil }