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 { iface.Base } func NewChatMemberUpdatedHandler(app iface.App) *ChatMemberUpdatedHandler { return &ChatMemberUpdatedHandler{iface.NewBase(app, 0, 0)} } 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 { _ = util.SendInternalError(h.App.TG(), tgChat.ID, nil) h.leaveChat(tgChat.ID) return err } user, err := h.getRegisteredAdmin(tgChat.ID) if err != nil { _ = util.SendInternalError(h.App.TG(), 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.Localizer(language.English.String()).Message("you_should_register_first"), ParseMode: telego.ModeMarkdown, }) h.leaveChat(tgChat.ID) return err } loc := h.Localizer(user.Language) totalMembers, err := h.App.TG().GetChatMemberCount(&telego.GetChatMemberCountParams{ ChatID: tu.ID(tgChat.ID), }) if err != nil { _ = util.SendInternalError(h.App.TG(), 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 { _ = util.SendInternalError(h.App.TG(), 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 { _ = util.SendInternalError(h.App.TG(), tgChat.ID, loc) h.leaveChat(tgChat.ID) return err } err = cr.Save(chat) if err != nil { _ = util.SendInternalError(h.App.TG(), 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.Localizer(user.Language).Template( "bot_was_removed_from_group", map[string]interface{}{"Name": tgChat.Title}), ParseMode: telego.ModeMarkdown, }) } 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, uint8(model.StandardKeyboard)).String(), }, }, { { Text: loc.Message("sp_vote_keyboard"), CallbackData: util.NewKeyboardChooserPayload( user.TelegramID, chat.ID, uint8(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), }) }