diff --git a/internal/tg_bot/commands/access_governance_bot/add_comment.go b/internal/tg_bot/commands/access_governance_bot/add_comment.go index 0f3c83d..5ca70bd 100644 --- a/internal/tg_bot/commands/access_governance_bot/add_comment.go +++ b/internal/tg_bot/commands/access_governance_bot/add_comment.go @@ -45,7 +45,7 @@ func (c *addCommentCommand) CanHandle(command string) bool { return command == addCommentCommandName } -func (c *addCommentCommand) Handle(command, arguments string, user *models.User, chatID int64) []tgbotapi.Chattable { +func (c *addCommentCommand) Handle(command, arguments string, user *models.User, bot *tgbotapi.BotAPI, chatID int64) []tgbotapi.Chattable { switch user.TelegramState.LastCommandState { case "": return []tgbotapi.Chattable{c.handleAddCommentCommand(command, user, chatID)} diff --git a/internal/tg_bot/commands/access_governance_bot/approved_proposals.go b/internal/tg_bot/commands/access_governance_bot/approved_proposals.go index dc62d88..d0212de 100644 --- a/internal/tg_bot/commands/access_governance_bot/approved_proposals.go +++ b/internal/tg_bot/commands/access_governance_bot/approved_proposals.go @@ -32,7 +32,7 @@ func (c *approvedProposalsCommand) CanHandle(command string) bool { return command == approvedProposalsCommandName } -func (c *approvedProposalsCommand) Handle(text, arguments string, user *models.User, chatID int64) []tgbotapi.Chattable { +func (c *approvedProposalsCommand) Handle(command, arguments string, user *models.User, bot *tgbotapi.BotAPI, chatID int64) []tgbotapi.Chattable { proposals, err := c.proposalRepository.GetManyByStatus(models.ProposalStatusApproved, models.ProposalStatusRejected) if err != nil { c.logger.Errorw("failed to get proposals", "error", err) diff --git a/internal/tg_bot/commands/access_governance_bot/cancel_proposal.go b/internal/tg_bot/commands/access_governance_bot/cancel_proposal.go index 682b5f3..50c8f1b 100644 --- a/internal/tg_bot/commands/access_governance_bot/cancel_proposal.go +++ b/internal/tg_bot/commands/access_governance_bot/cancel_proposal.go @@ -31,7 +31,7 @@ func (c *cancelProposalCommand) CanHandle(command string) bool { return command == cancelProposalCommandName } -func (c *cancelProposalCommand) Handle(text, arguments string, user *models.User, chatID int64) []tgbotapi.Chattable { +func (c *cancelProposalCommand) Handle(command, arguments string, user *models.User, bot *tgbotapi.BotAPI, chatID int64) []tgbotapi.Chattable { user.TempProposal = models.Proposal{} user.TelegramState = models.TelegramState{} _, err := c.userRepository.Update(user) diff --git a/internal/tg_bot/commands/access_governance_bot/create_proposal.go b/internal/tg_bot/commands/access_governance_bot/create_proposal.go index 40bbcdd..a3c6cc0 100644 --- a/internal/tg_bot/commands/access_governance_bot/create_proposal.go +++ b/internal/tg_bot/commands/access_governance_bot/create_proposal.go @@ -64,7 +64,7 @@ func (c *createProposalCommand) CanHandle(command string) bool { return command == createProposalCommandName } -func (c *createProposalCommand) Handle(command, arguments string, user *models.User, chatID int64) []tgbotapi.Chattable { +func (c *createProposalCommand) Handle(command, arguments string, user *models.User, bot *tgbotapi.BotAPI, chatID int64) []tgbotapi.Chattable { var message tgbotapi.Chattable if command == createProposalCommandName { diff --git a/internal/tg_bot/commands/access_governance_bot/pending_proposals.go b/internal/tg_bot/commands/access_governance_bot/pending_proposals.go index dea4182..365fabb 100644 --- a/internal/tg_bot/commands/access_governance_bot/pending_proposals.go +++ b/internal/tg_bot/commands/access_governance_bot/pending_proposals.go @@ -32,7 +32,7 @@ func (c *pendingProposalsCommand) CanHandle(command string) bool { return command == pendingProposalsCommandName } -func (c *pendingProposalsCommand) Handle(text, arguments string, user *models.User, chatID int64) []tgbotapi.Chattable { +func (c *pendingProposalsCommand) Handle(command, arguments string, user *models.User, bot *tgbotapi.BotAPI, chatID int64) []tgbotapi.Chattable { proposals, err := c.proposalRepository.GetManyByStatus(models.ProposalStatusCreated) if err != nil { c.logger.Errorw("failed to get proposals", "error", err) diff --git a/internal/tg_bot/commands/access_governance_bot/start.go b/internal/tg_bot/commands/access_governance_bot/start.go index 5df1cde..be4ec77 100644 --- a/internal/tg_bot/commands/access_governance_bot/start.go +++ b/internal/tg_bot/commands/access_governance_bot/start.go @@ -16,7 +16,6 @@ import ( const startCommandName = "start" type startCommand struct { - bot *tgbotapi.BotAPI config configs.AccessGovernanceBotConfig userRepository repositories.UserRepository logger *zap.SugaredLogger @@ -34,7 +33,7 @@ func (c *startCommand) CanHandle(command string) bool { return command == startCommandName } -func (c *startCommand) Handle(text, arguments string, user *models.User, chatID int64) []tgbotapi.Chattable { +func (c *startCommand) Handle(command, arguments string, user *models.User, bot *tgbotapi.BotAPI, chatID int64) []tgbotapi.Chattable { var messages = []tgbotapi.Chattable{} parseMode := tgbotapi.ModeMarkdownV2 @@ -54,7 +53,7 @@ func (c *startCommand) Handle(text, arguments string, user *models.User, chatID messages = append(messages, message) if user.Role == models.UserRoleSeeder && user.DiscordID == 0 { - message := c.createInstructionMessageForSeeder(chatID) + message := c.createInstructionMessageForSeeder(bot, chatID) if message == nil { return []tgbotapi.Chattable{tgbot.DefaultErrorMessage(chatID)} @@ -66,23 +65,14 @@ func (c *startCommand) Handle(text, arguments string, user *models.User, chatID return messages } -func (c *startCommand) createInstructionMessageForSeeder(chatID int64) tgbotapi.Chattable { - if c.bot == nil { - var err error - c.bot, err = tgbotapi.NewBotAPI(c.config.AccessGovernanceBot.Token) - if err != nil { - c.logger.Fatalf("could not create bot: %v", err) - return nil - } - } - - seedersChatInviteLink, err := c.createSeedersChatInviteLink() +func (c *startCommand) createInstructionMessageForSeeder(bot *tgbotapi.BotAPI, chatID int64) tgbotapi.Chattable { + seedersChatInviteLink, err := tgbot.CreateChatInviteLink(bot, c.config.App.SeedersChatID) if err != nil { c.logger.Fatalf("could not create seeders chat invite link: %v", err) return nil } - membersChatInviteLink, err := c.createMembersChatInviteLink() + membersChatInviteLink, err := tgbot.CreateChatInviteLink(bot, c.config.App.MembersChatID) if err != nil { c.logger.Fatalf("could not create members chat invite link: %v", err) return nil @@ -104,33 +94,3 @@ func (c *startCommand) createInstructionMessageForSeeder(chatID int64) tgbotapi. return message } - -func (c *startCommand) createMembersChatInviteLink() (string, error) { - inviteLinkConfig := tgbotapi.ChatInviteLinkConfig{ - ChatConfig: tgbotapi.ChatConfig{ - ChatID: c.config.App.MembersChatID, - }, - } - - inviteLink, err := c.bot.GetInviteLink(inviteLinkConfig) - if err != nil { - return "", err - } - - return inviteLink, nil -} - -func (c *startCommand) createSeedersChatInviteLink() (string, error) { - inviteLinkConfig := tgbotapi.ChatInviteLinkConfig{ - ChatConfig: tgbotapi.ChatConfig{ - ChatID: c.config.App.SeedersChatID, - }, - } - - inviteLink, err := c.bot.GetInviteLink(inviteLinkConfig) - if err != nil { - return "", err - } - - return inviteLink, nil -} diff --git a/internal/tg_bot/commands/authorization_bot/start.go b/internal/tg_bot/commands/authorization_bot/start.go index 152668e..1920324 100644 --- a/internal/tg_bot/commands/authorization_bot/start.go +++ b/internal/tg_bot/commands/authorization_bot/start.go @@ -40,7 +40,7 @@ func (c *startCommand) CanHandle(command string) bool { return command == startCommandName } -func (c *startCommand) Handle(text, discordID string, user *models.User, chatID int64) []tgbotapi.Chattable { +func (c *startCommand) Handle(command, discordID string, user *models.User, bot *tgbotapi.BotAPI, chatID int64) []tgbotapi.Chattable { if (user.Role == models.UserRoleMember || user.Role == models.UserRoleSeeder) && user.DiscordID != 0 { return []tgbotapi.Chattable{ tgbotapi.NewMessage(chatID, "Привет, ты успешно авторизован, можешь возвращаться в Discord"), diff --git a/internal/tg_bot/commands/command.go b/internal/tg_bot/commands/command.go index 9921401..e29b1b3 100644 --- a/internal/tg_bot/commands/command.go +++ b/internal/tg_bot/commands/command.go @@ -8,5 +8,5 @@ import ( type Command interface { CanHandle(command string) bool - Handle(text, arguments string, user *models.User, chatID int64) []tgbotapi.Chattable + Handle(command, arguments string, user *models.User, bot *tgbotapi.BotAPI, chatID int64) []tgbotapi.Chattable } diff --git a/internal/tg_bot/extension/helpers.go b/internal/tg_bot/extension/helpers.go index 8c77c1d..7541860 100644 --- a/internal/tg_bot/extension/helpers.go +++ b/internal/tg_bot/extension/helpers.go @@ -9,3 +9,18 @@ func DefaultErrorMessage(chatID int64) tgbotapi.Chattable { func ErrorMessage(chatID int64, text string) tgbotapi.Chattable { return tgbotapi.NewMessage(chatID, text) } + +func CreateChatInviteLink(bot *tgbotapi.BotAPI, chatID int64) (string, error) { + inviteLinkConfig := tgbotapi.ChatInviteLinkConfig{ + ChatConfig: tgbotapi.ChatConfig{ + ChatID: chatID, + }, + } + + inviteLink, err := bot.GetInviteLink(inviteLinkConfig) + if err != nil { + return "", err + } + + return inviteLink, nil +} diff --git a/internal/tg_bot/handlers/access_governance_bot/command_handler.go b/internal/tg_bot/handlers/access_governance_bot/command_handler.go index 388ddce..47cbcf6 100644 --- a/internal/tg_bot/handlers/access_governance_bot/command_handler.go +++ b/internal/tg_bot/handlers/access_governance_bot/command_handler.go @@ -61,35 +61,7 @@ func (h *accessGovernanceBotCommandHandler) Handle(bot *tgbotapi.BotAPI, update } if len(message.NewChatMembers) > 0 { - messages := []tgbotapi.Chattable{} - - for _, newChatMember := range message.NewChatMembers { - user, err := h.userRepository.GetOneByTelegramNickname(newChatMember.UserName) - if user == nil || err != nil { - h.logger.Errorw("failed to get user", "error", err) - continue - } - - user.TelegramID = newChatMember.ID - - _, err = h.userRepository.Update(user) - if err != nil { - h.logger.Errorw("failed to update user", "error", err) - continue - } - - text := fmt.Sprintf(` -Привет, %s! Добро пожаловать в чат %s. - -Для того, чтобы авторизоваться тебе надо подключиться к нашему discord серверу(%s) и отправить команду %s в чате в discord. - `, newChatMember.FirstName, h.config.App.CommunityName, h.config.DiscordInviteLink, "`!authorize`") - message := tgbotapi.NewMessage(newChatMember.ID, text) - message.DisableWebPagePreview = true - message.ParseMode = tgbotapi.ModeMarkdown - messages = append(messages, message) - } - - return messages + return h.handleNewChatMembers(bot, message) } if telegramUser.ID != chatID { @@ -106,16 +78,16 @@ func (h *accessGovernanceBotCommandHandler) Handle(bot *tgbotapi.BotAPI, update h.logger.Infow("received message", "message", message) if message.IsCommand() { h.logger.Infow("received command", "command", message.Command()) - return h.tryToHandleCommand(message.Command(), h.commands, user, chatID) + return h.tryToHandleCommand(message.Command(), h.commands, user, bot, chatID) } else if user.TelegramState.LastCommand != "" { h.logger.Infow("received subcommand", "subcommand", message.Text) - return h.tryToHandleSubCommand(user.TelegramState.LastCommand, message.Text, h.commands, user, chatID) + return h.tryToHandleSubCommand(user.TelegramState.LastCommand, message.Text, h.commands, user, bot, chatID) } } if callbackQuery != nil { h.logger.Infow("received callback query", "callback_query", callbackQuery) - return h.tryToHandleQueryCallback(callbackQuery.Data, h.commands, user, chatID) + return h.tryToHandleQueryCallback(callbackQuery.Data, h.commands, user, bot, chatID) } h.logger.Warn("received unknown message") @@ -171,7 +143,7 @@ func (h *accessGovernanceBotCommandHandler) createUserIfNeeded(telegramUser *tgb return user, nil } -func (h *accessGovernanceBotCommandHandler) tryToHandleCommand(command string, commands []commands.Command, user *models.User, chatID int64) []tgbotapi.Chattable { +func (h *accessGovernanceBotCommandHandler) tryToHandleCommand(command string, commands []commands.Command, user *models.User, bot *tgbotapi.BotAPI, chatID int64) []tgbotapi.Chattable { for _, handler := range commands { if handler.CanHandle(command) { user.TempProposal = models.Proposal{} @@ -182,7 +154,7 @@ func (h *accessGovernanceBotCommandHandler) tryToHandleCommand(command string, c h.logger.Errorw("failed to update user", "error", err) } - return handler.Handle(command, "", user, chatID) + return handler.Handle(command, "", user, bot, chatID) } } @@ -190,12 +162,12 @@ func (h *accessGovernanceBotCommandHandler) tryToHandleCommand(command string, c return []tgbotapi.Chattable{} } -func (h *accessGovernanceBotCommandHandler) tryToHandleSubCommand(command, subCommand string, commands []commands.Command, user *models.User, chatID int64) []tgbotapi.Chattable { +func (h *accessGovernanceBotCommandHandler) tryToHandleSubCommand(command, subCommand string, commands []commands.Command, user *models.User, bot *tgbotapi.BotAPI, chatID int64) []tgbotapi.Chattable { command = strings.Split(command, ":")[0] for _, handler := range commands { if handler.CanHandle(command) { - responseMessage := handler.Handle(subCommand, "", user, chatID) + responseMessage := handler.Handle(subCommand, "", user, bot, chatID) if responseMessage == nil { h.logger.Errorw("failed to handle subcommand", "subCommand", subCommand) break @@ -209,7 +181,7 @@ func (h *accessGovernanceBotCommandHandler) tryToHandleSubCommand(command, subCo return []tgbotapi.Chattable{} } -func (h *accessGovernanceBotCommandHandler) tryToHandleQueryCallback(query string, commands []commands.Command, user *models.User, chatID int64) []tgbotapi.Chattable { +func (h *accessGovernanceBotCommandHandler) tryToHandleQueryCallback(query string, commands []commands.Command, user *models.User, bot *tgbotapi.BotAPI, chatID int64) []tgbotapi.Chattable { parts := strings.Split(query, ":") if len(parts) == 0 { h.logger.Error("received empty query callback") @@ -227,10 +199,64 @@ func (h *accessGovernanceBotCommandHandler) tryToHandleQueryCallback(query strin h.logger.Errorw("failed to update user", "error", err) } - return handler.Handle(query, "", user, chatID) + return handler.Handle(query, "", user, bot, chatID) } } h.logger.Errorw("received unknown command", "command", command) return []tgbotapi.Chattable{} } + +func (h *accessGovernanceBotCommandHandler) handleNewChatMembers(bot *tgbotapi.BotAPI, message *tgbotapi.Message) []tgbotapi.Chattable { + messages := []tgbotapi.Chattable{} + + for _, newChatMember := range message.NewChatMembers { + user, err := h.userRepository.GetOneByTelegramNickname(newChatMember.UserName) + if user == nil || err != nil { + h.logger.Errorw("failed to get user", "error", err) + continue + } + + user.TelegramID = newChatMember.ID + + _, err = h.userRepository.Update(user) + if err != nil { + h.logger.Errorw("failed to update user", "error", err) + continue + } + + var messageText string + + if user.Role == models.UserRoleSeeder { + seedersChatInviteLink, err := tgbot.CreateChatInviteLink(bot, h.config.App.SeedersChatID) + if err != nil { + h.logger.Fatalf("could not create seeders chat invite link: %v", err) + continue + } + + messageText = fmt.Sprintf(` +Привет, %s! Добро пожаловать в сообщество %s. + +Для того, чтобы авторизоваться тебе надо: +1. Вступить в нашу группу для seeders - %s +2. Подключиться к нашему discord серверу - %s +3. Отправить команду %s в чате в discord +`, newChatMember.FirstName, h.config.App.CommunityName, seedersChatInviteLink, h.config.DiscordInviteLink, "`!authorize`") + } else if user.Role == models.UserRoleMember { + messageText = fmt.Sprintf(` +Привет, %s! Добро пожаловать в сообщество %s. + +Для того, чтобы авторизоваться тебе надо: +1. Подключиться к нашему discord серверу - %s +2. Отправить команду %s в чате в discord +`, newChatMember.FirstName, h.config.App.CommunityName, h.config.DiscordInviteLink, "`!authorize`") + } + + message := tgbotapi.NewMessage(newChatMember.ID, messageText) + message.DisableWebPagePreview = true + message.ParseMode = tgbotapi.ModeMarkdown + messages = append(messages, message) + } + + return messages +} diff --git a/internal/tg_bot/handlers/authorization_bot/command_handler.go b/internal/tg_bot/handlers/authorization_bot/command_handler.go index 80252fb..89b988c 100644 --- a/internal/tg_bot/handlers/authorization_bot/command_handler.go +++ b/internal/tg_bot/handlers/authorization_bot/command_handler.go @@ -63,7 +63,7 @@ func (h *authorizationBotCommandHandler) Handle(bot *tgbotapi.BotAPI, update tgb if message.IsCommand() { h.logger.Infow("received command", "command", message.Command()) - return h.tryToHandleCommand(message, h.commands, user, chatID) + return h.tryToHandleCommand(message, h.commands, user, bot, chatID) } } @@ -71,13 +71,13 @@ func (h *authorizationBotCommandHandler) Handle(bot *tgbotapi.BotAPI, update tgb return []tgbotapi.Chattable{} } -func (h *authorizationBotCommandHandler) tryToHandleCommand(message *tgbotapi.Message, commands []commands.Command, user *models.User, chatID int64) []tgbotapi.Chattable { +func (h *authorizationBotCommandHandler) tryToHandleCommand(message *tgbotapi.Message, commands []commands.Command, user *models.User, bot *tgbotapi.BotAPI, chatID int64) []tgbotapi.Chattable { command := message.Command() arguments := message.CommandArguments() for _, handler := range commands { if handler.CanHandle(command) { - return handler.Handle(command, arguments, user, chatID) + return handler.Handle(command, arguments, user, bot, chatID) } }