vegapokerbot/internal/handler/fsmwizard/add_chat_member_state.go

170 lines
4.2 KiB
Go
Raw Normal View History

package fsmwizard
2024-05-13 17:18:22 +03:00
import (
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db/model"
2024-05-13 17:18:22 +03:00
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/iface"
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/util"
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/pkg/fsm"
"github.com/mymmrac/telego"
tu "github.com/mymmrac/telego/telegoutil"
"golang.org/x/text/language"
2024-05-13 17:18:22 +03:00
)
const MaxChatMembers = 32
2024-05-13 17:18:22 +03:00
const AddChatMemberStateID fsm.StateID = "add_chat_member"
type AddChatMemberState struct {
State
}
func NewAddChatMemberState(app iface.App) fsm.IState[Wizard] {
return &AddChatMemberState{newBase(app)}
}
func (s *AddChatMemberState) Enter(pl *Wizard, mc fsm.MachineControls[*Wizard]) error {
if pl.Data.MyChatMember == nil {
s.Move(mc, WaitingForMemberWebhookStateID, pl)
2024-05-13 17:18:22 +03:00
}
return nil
}
func (s *AddChatMemberState) Handle(pl *Wizard, mc fsm.MachineControls[*Wizard]) {
next := WaitingForMemberWebhookStateID
defer func() {
s.Move(mc, next, pl)
}()
2024-05-13 19:46:55 +03:00
cr := s.App.DB().ForChat()
tgChat := pl.Data.MyChatMember.Chat
2024-05-13 19:46:55 +03:00
user, chat := s.getUserAndChat(tgChat)
if user == nil || chat == nil {
return
}
2024-05-13 19:46:55 +03:00
s.Payload.Loc = s.Localizer(user.Language)
if s.handleTooManyMembers(tgChat.ID) {
return
}
2024-05-13 19:46:55 +03:00
if chat.ID == 0 {
chat = &model.Chat{
TelegramID: tgChat.ID,
UserID: user.ID,
}
err := cr.Save(chat)
if err != nil {
2024-05-13 19:46:55 +03:00
s.curseAndLeave(tgChat.ID, err)
return
}
} else {
chat.UserID = user.ID
err := s.App.DB().ForIntegration().DeleteForChat(chat.ID)
if err != nil {
2024-05-13 19:46:55 +03:00
s.curseAndLeave(tgChat.ID, err)
return
}
err = cr.Save(chat)
if err != nil {
2024-05-13 19:46:55 +03:00
s.curseAndLeave(tgChat.ID, err)
return
}
}
2024-05-13 19:46:55 +03:00
_, err := s.App.TG().SendMessage(&telego.SendMessageParams{
ChatID: tu.ID(user.ChatID),
2024-05-13 19:46:55 +03:00
Text: s.Payload.Loc.Template("bot_was_added", map[string]interface{}{"Name": tgChat.Title}),
ParseMode: telego.ModeMarkdown,
})
s.LogError(err)
pl.User = user
pl.TGChat = tgChat
next = KeyboardChooserStateID
}
2024-05-13 19:46:55 +03:00
func (s *AddChatMemberState) handleTooManyMembers(chatID int64) bool {
totalMembers, err := s.App.TG().GetChatMemberCount(&telego.GetChatMemberCountParams{
ChatID: tu.ID(chatID),
})
if err != nil {
s.curseAndLeave(chatID, err)
return true
}
if *totalMembers > MaxChatMembers {
_, err = s.App.TG().SendMessage(&telego.SendMessageParams{
ChatID: tu.ID(chatID),
Text: s.Payload.Loc.Template(
"too_many_members_in_the_group", map[string]interface{}{"Limit": MaxChatMembers}),
ParseMode: telego.ModeMarkdown,
})
s.leaveChat(chatID)
s.LogError(err)
return true
}
return false
}
func (s *AddChatMemberState) getUserAndChat(tgChat telego.Chat) (*model.User, *model.Chat) {
cr := s.App.DB().ForChat()
chat, err := cr.ByTelegramID(tgChat.ID)
if err != nil {
s.curseAndLeave(tgChat.ID, err)
return nil, nil
}
user, err := s.getRegisteredAdmin(tgChat.ID)
if err != nil {
s.curseAndLeave(tgChat.ID, err)
return nil, nil
}
if user == nil || user.ID == 0 {
_, err = s.App.TG().SendMessage(&telego.SendMessageParams{
ChatID: tu.ID(tgChat.ID),
Text: s.Localizer(language.English.String()).
Template("you_should_register_first", map[string]interface{}{"Name": s.App.TGProfile().Username}),
ParseMode: telego.ModeMarkdown,
})
s.leaveChat(tgChat.ID)
s.LogError(err)
return nil, nil
}
return user, chat
}
func (s *AddChatMemberState) curseAndLeave(chatID int64, err error) {
s.LogError(util.SendInternalError(s.App.TG(), chatID, s.Localizer()))
s.leaveChat(chatID)
s.LogError(err)
}
func (s *AddChatMemberState) getRegisteredAdmin(chatID int64) (*model.User, error) {
admins, err := s.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 := s.App.DB().ForUser().ByTelegramIDs(adminIDs)
if err != nil {
return nil, err
}
if len(dbAdmins) > 0 {
return &dbAdmins[0], nil
}
return nil, nil
}
func (s *AddChatMemberState) leaveChat(chatID int64) {
s.LogError(s.App.TG().LeaveChat(&telego.LeaveChatParams{
ChatID: tu.ID(chatID),
}))
2024-05-13 17:18:22 +03:00
}
func (s *AddChatMemberState) ID() fsm.StateID {
return AddChatMemberStateID
}