diff --git a/internal/fsm/machine.go b/internal/fsm/machine.go index 8d3ae44..22dda56 100644 --- a/internal/fsm/machine.go +++ b/internal/fsm/machine.go @@ -86,6 +86,7 @@ func (m *Machine[T]) Move(id StateID, payload *T) error { return err } m.state = id + m.payload = payload return nil } diff --git a/internal/handler/wizard/add_chat_member_state.go b/internal/handler/wizard/add_chat_member_state.go new file mode 100644 index 0000000..c255961 --- /dev/null +++ b/internal/handler/wizard/add_chat_member_state.go @@ -0,0 +1,31 @@ +package wizard + +import ( + "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/fsm" + "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/iface" +) + +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 { + _ = mc.Move(WaitingForMemberWebhookStateID, pl) + } + return nil +} + +func (s *AddChatMemberState) Handle(pl *Wizard, mc fsm.MachineControls[*Wizard]) { + // todo: copy implementation from func (h *ChatMemberUpdatedHandler) handleAddToChat(tgChat telego.Chat) error +} + +func (s *AddChatMemberState) ID() fsm.StateID { + return AddChatMemberStateID +} diff --git a/internal/handler/wizard/help_state.go b/internal/handler/wizard/help_state.go index 52c94b1..45ac4a8 100644 --- a/internal/handler/wizard/help_state.go +++ b/internal/handler/wizard/help_state.go @@ -7,6 +7,8 @@ import ( tu "github.com/mymmrac/telego/telegoutil" ) +const HelpStateID fsm.StateID = "help" + type HelpState struct { State } @@ -27,5 +29,5 @@ func (s *HelpState) Enter(pl *Wizard, _ fsm.MachineControls[*Wizard]) error { } func (s *HelpState) ID() fsm.StateID { - return "help" + return HelpStateID } diff --git a/internal/handler/wizard/init.go b/internal/handler/wizard/init.go index 6cf07df..64601fc 100644 --- a/internal/handler/wizard/init.go +++ b/internal/handler/wizard/init.go @@ -42,6 +42,9 @@ func newWizard() fsm.IMachine[Wizard] { func PopulateStates(app iface.App) { states = []fsm.IState[Wizard]{ NewRegisterState(app), + NewWaitingForMemberWebhookState(app), + NewAddChatMemberState(app), + NewRemoveChatMemberState(app), NewHelpState(app), } errorState = NewErrorState(app.Log()) diff --git a/internal/handler/wizard/register_state.go b/internal/handler/wizard/register_state.go index 43cf1c1..adc7dca 100644 --- a/internal/handler/wizard/register_state.go +++ b/internal/handler/wizard/register_state.go @@ -8,6 +8,8 @@ import ( tu "github.com/mymmrac/telego/telegoutil" ) +const RegisterStateID fsm.StateID = "register" + type RegisterState struct { State } @@ -16,7 +18,7 @@ func NewRegisterState(app iface.App) fsm.IState[Wizard] { return &RegisterState{newBase(app)} } -func (s *RegisterState) Handle(pl *Wizard, _ fsm.MachineControls[*Wizard]) { +func (s *RegisterState) Handle(pl *Wizard, mc fsm.MachineControls[*Wizard]) { loc := s.Localizer(pl.Data.Message.From.LanguageCode) userRepo := s.App.DB().ForUser() user, err := userRepo.ByTelegramID(pl.Data.Message.From.ID) @@ -37,12 +39,7 @@ func (s *RegisterState) Handle(pl *Wizard, _ fsm.MachineControls[*Wizard]) { if shouldUpdate { _ = userRepo.Save(user) } - _, err := s.App.TG().SendMessage(&telego.SendMessageParams{ - ChatID: tu.ID(pl.Data.Message.Chat.ID), - Text: loc.Message("welcome"), - ParseMode: telego.ModeMarkdown, - }) - s.LogError(err) + _ = mc.Move(WaitingForMemberWebhookStateID, pl) return } @@ -59,18 +56,20 @@ func (s *RegisterState) Handle(pl *Wizard, _ fsm.MachineControls[*Wizard]) { ParseMode: telego.ModeMarkdown, }) s.LogError(err) - return } + _ = mc.Move(WaitingForMemberWebhookStateID, pl) +} - _, err = s.App.TG().SendMessage(&telego.SendMessageParams{ +func (s *RegisterState) Exit(pl *Wizard) { + loc := s.Localizer(pl.Data.Message.From.LanguageCode) + _, err := s.App.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(pl.Data.Message.Chat.ID), Text: loc.Message("welcome"), ParseMode: telego.ModeMarkdown, }) s.LogError(err) - return } func (s *RegisterState) ID() fsm.StateID { - return "register" + return RegisterStateID } diff --git a/internal/handler/wizard/remove_chat_member_state.go b/internal/handler/wizard/remove_chat_member_state.go new file mode 100644 index 0000000..1a1387b --- /dev/null +++ b/internal/handler/wizard/remove_chat_member_state.go @@ -0,0 +1,31 @@ +package wizard + +import ( + "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/fsm" + "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/iface" +) + +const RemoveChatMemberStateID fsm.StateID = "remove_chat_member" + +type RemoveChatMemberState struct { + State +} + +func NewRemoveChatMemberState(app iface.App) fsm.IState[Wizard] { + return &RemoveChatMemberState{newBase(app)} +} + +func (s *RemoveChatMemberState) Enter(pl *Wizard, mc fsm.MachineControls[*Wizard]) error { + if pl.Data.MyChatMember == nil { + _ = mc.Move(WaitingForMemberWebhookStateID, pl) + } + return nil +} + +func (s *RemoveChatMemberState) Handle(pl *Wizard, mc fsm.MachineControls[*Wizard]) { + // todo: copy implementation from func (h *ChatMemberUpdatedHandler) handleRemoveFromChat(tgChat telego.Chat) error +} + +func (s *RemoveChatMemberState) ID() fsm.StateID { + return RemoveChatMemberStateID +} diff --git a/internal/handler/wizard/waiting_for_member_webhook_state.go b/internal/handler/wizard/waiting_for_member_webhook_state.go new file mode 100644 index 0000000..4b348e3 --- /dev/null +++ b/internal/handler/wizard/waiting_for_member_webhook_state.go @@ -0,0 +1,40 @@ +package wizard + +import ( + "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/fsm" + "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/iface" + "github.com/mymmrac/telego" + tu "github.com/mymmrac/telego/telegoutil" +) + +const WaitingForMemberWebhookStateID fsm.StateID = "waiting_for_member_webhook" + +type WaitingForMemberWebhookState struct { + State +} + +func NewWaitingForMemberWebhookState(app iface.App) fsm.IState[Wizard] { + return &WaitingForMemberWebhookState{newBase(app)} +} + +func (s *WaitingForMemberWebhookState) Handle(pl *Wizard, mc fsm.MachineControls[*Wizard]) { + cm := pl.Data.MyChatMember + if !cm.OldChatMember.MemberIsMember() && cm.OldChatMember.MemberUser().ID == s.App.TGProfile().ID && + cm.NewChatMember.MemberIsMember() && cm.NewChatMember.MemberUser().ID == s.App.TGProfile().ID { + _ = mc.Move(AddChatMemberStateID, pl) + return + } + if cm.OldChatMember.MemberIsMember() && cm.OldChatMember.MemberUser().ID == s.App.TGProfile().ID && + !cm.NewChatMember.MemberIsMember() && cm.NewChatMember.MemberUser().ID == s.App.TGProfile().ID { + _ = mc.Move(RemoveChatMemberStateID, pl) + return + } + + s.LogError(s.App.TG().LeaveChat(&telego.LeaveChatParams{ + ChatID: tu.ID(pl.Data.MyChatMember.Chat.ID), + })) +} + +func (s *WaitingForMemberWebhookState) ID() fsm.StateID { + return WaitingForMemberWebhookStateID +}