vegapokerbot/internal/handler/callback_query_handler.go

216 lines
6.7 KiB
Go

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)
}
// @todo implement poker polls handling.
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
}