package handler import ( "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db/model" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/iface" "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" "golang.org/x/text/language" ) const MaxChatMembers = 32 type ChatMemberUpdatedHandler struct { app iface.App } func NewChatMemberUpdatedHandler(app iface.App) *ChatMemberUpdatedHandler { return &ChatMemberUpdatedHandler{app: app} } func (h *ChatMemberUpdatedHandler) Handle(wh telego.Update) error { cm := wh.MyChatMember if !cm.OldChatMember.MemberIsMember() && cm.OldChatMember.MemberUser().ID == h.app.TGProfile().ID && cm.NewChatMember.MemberIsMember() && cm.NewChatMember.MemberUser().ID == h.app.TGProfile().ID { return h.handleAddToChat(wh.MyChatMember.Chat) } if cm.OldChatMember.MemberIsMember() && cm.OldChatMember.MemberUser().ID == h.app.TGProfile().ID && !cm.NewChatMember.MemberIsMember() && cm.NewChatMember.MemberUser().ID == h.app.TGProfile().ID { return h.handleRemoveFromChat(wh.MyChatMember.Chat) } h.leaveChat(wh.MyChatMember.Chat.ID) return nil } func (h *ChatMemberUpdatedHandler) handleAddToChat(tgChat telego.Chat) error { cr := h.app.DB().ForChat() chat, err := cr.ByTelegramID(tgChat.ID) if err != nil { h.sendInternalError(tgChat.ID, nil) h.leaveChat(tgChat.ID) return err } user, err := h.getRegisteredAdmin(tgChat.ID) if err != nil { h.sendInternalError(tgChat.ID, nil) h.leaveChat(tgChat.ID) return err } if user == nil || user.ID == 0 { _, err = h.app.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(tgChat.ID), Text: h.app.Localizer(language.English.String()).Message("you_should_register_first"), ParseMode: telego.ModeMarkdown, }) h.leaveChat(tgChat.ID) return err } loc := h.app.Localizer(user.Language) totalMembers, err := h.app.TG().GetChatMemberCount(&telego.GetChatMemberCountParams{ ChatID: tu.ID(tgChat.ID), }) if err != nil { h.sendInternalError(tgChat.ID, nil) h.leaveChat(tgChat.ID) return err } if *totalMembers > MaxChatMembers { _, err = h.app.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(tgChat.ID), Text: loc.Template("too_many_members_in_the_group", map[string]interface{}{"Limit": MaxChatMembers}), ParseMode: telego.ModeMarkdown, }) h.leaveChat(tgChat.ID) return err } if chat == nil || chat.ID == 0 { chat = &model.Chat{ TelegramID: tgChat.ID, UserID: user.ID, } err := cr.Save(chat) if err != nil { h.sendInternalError(tgChat.ID, loc) h.leaveChat(tgChat.ID) return err } } else { chat.UserID = user.ID err := h.app.DB().ForIntegration().DeleteForChat(chat.ID) if err != nil { h.sendInternalError(tgChat.ID, loc) h.leaveChat(tgChat.ID) return err } err = cr.Save(chat) if err != nil { h.sendInternalError(tgChat.ID, loc) h.leaveChat(tgChat.ID) return err } } _, _ = h.app.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(user.ChatID), Text: loc.Template("bot_was_added", map[string]interface{}{"Name": tgChat.Title}), ParseMode: telego.ModeMarkdown, }) return h.sendKeyboardChooser(tgChat, user, loc) } func (h *ChatMemberUpdatedHandler) handleRemoveFromChat(tgChat telego.Chat) error { cr := h.app.DB().ForChat() chat, err := cr.ByTelegramID(tgChat.ID) if err != nil { return err } if chat != nil && chat.ID > 0 { user, _ := h.app.DB().ForUser().ByID(chat.UserID) if user != nil && user.ID > 0 && user.ChatID > 0 { _, _ = h.app.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(user.ChatID), Text: h.app.Localizer(user.Language).Template( "bot_was_removed_from_group", map[string]interface{}{"Name": tgChat.Title}), }) } return cr.Delete(chat) } return nil } func (h *ChatMemberUpdatedHandler) sendKeyboardChooser(chat telego.Chat, user *model.User, loc locale.Localizer) error { _, err := h.app.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(user.ChatID), Text: loc.Template("choose_keyboard", map[string]interface{}{"Name": chat.Title}), ParseMode: telego.ModeMarkdown, ReplyMarkup: &telego.InlineKeyboardMarkup{ InlineKeyboard: [][]telego.InlineKeyboardButton{ { { Text: loc.Message("standard_vote_keyboard"), CallbackData: util.NewKeyboardChooserPayload( user.TelegramID, chat.ID, model.StandardKeyboard).String(), }, }, { { Text: loc.Message("sp_vote_keyboard"), CallbackData: util.NewKeyboardChooserPayload( user.TelegramID, chat.ID, model.StoryPointsKeyboard).String(), }, }, }, }, }) return err } func (h *ChatMemberUpdatedHandler) getRegisteredAdmin(chatID int64) (*model.User, error) { admins, err := h.app.TG().GetChatAdministrators(&telego.GetChatAdministratorsParams{ ChatID: tu.ID(chatID), }) if err != nil { return nil, err } adminIDs := make([]int64, len(admins)) for i, admin := range admins { adminIDs[i] = admin.MemberUser().ID } dbAdmins, err := h.app.DB().ForUser().ByTelegramIDs(adminIDs) if err != nil { return nil, err } if len(dbAdmins) > 0 { return &dbAdmins[0], nil } return nil, nil } func (h *ChatMemberUpdatedHandler) leaveChat(chatID int64) { _ = h.app.TG().LeaveChat(&telego.LeaveChatParams{ ChatID: tu.ID(chatID), }) } func (h *ChatMemberUpdatedHandler) sendInternalError(chatID int64, loc locale.Localizer) { if loc == nil { loc = h.app.Localizer(language.English.String()) } _, _ = h.app.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(chatID), Text: loc.Message("internal_error"), ParseMode: telego.ModeMarkdown, }) }