From ac0292ab6f28e637b953150f9182ae788e427745 Mon Sep 17 00:00:00 2001 From: Vladimir Hodakov Date: Sat, 25 Nov 2017 03:00:34 +0400 Subject: [PATCH] Broadcast message to all Instinkt players Closes #7 --- lib/broadcaster/responders.go | 25 ++++++++++---- lib/broadcaster/sender.go | 20 +++++++---- .../chatterinterface/chatterinterface.go | 1 + lib/chatter/getters.go | 15 ++++++++- lib/forwarder/forwarder.go | 3 +- lib/router/private_request.go | 33 +++++++++---------- lib/squader/responders.go | 9 ++--- lib/squader/squader.go | 6 ++-- lib/talkers/errors.go | 8 +++-- lib/talkers/help.go | 1 + .../talkersinterface/talkersinterface.go | 4 +-- lib/users/responders.go | 6 ++-- 12 files changed, 81 insertions(+), 50 deletions(-) diff --git a/lib/broadcaster/responders.go b/lib/broadcaster/responders.go index d452102..7ea008b 100644 --- a/lib/broadcaster/responders.go +++ b/lib/broadcaster/responders.go @@ -7,16 +7,24 @@ import ( "github.com/go-telegram-bot-api/telegram-bot-api" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "strconv" - "strings" ) // AdminBroadcastMessageCompose saves message for future broadcast func (b *Broadcaster) AdminBroadcastMessageCompose(update *tgbotapi.Update, playerRaw *dbmapping.Player) string { - broadcastingMessageBody := strings.Replace(update.Message.Text, "/send_all ", "", 1) + broadcastingMessageBody := update.Message.CommandArguments() + messageRaw, ok := dbmapping.Broadcast{}, false - messageRaw, ok := b.createBroadcastMessage(playerRaw, broadcastingMessageBody, "all") - if !ok { - return "fail" + switch update.Message.Command() { + case "send_all": + messageRaw, ok = b.createBroadcastMessage(playerRaw, broadcastingMessageBody, "all") + if !ok { + return "fail" + } + case "send_league": + messageRaw, ok = b.createBroadcastMessage(playerRaw, broadcastingMessageBody, "league") + if !ok { + return "fail" + } } message := "Сообщение сохранено в базу.\n" @@ -36,7 +44,12 @@ func (b *Broadcaster) AdminBroadcastMessageCompose(update *tgbotapi.Update, play c.Bot.Send(msg) - message = "Чтобы отправить сообщение всем, отправь команду /send\\_confirm " + strconv.Itoa(messageRaw.ID) + switch update.Message.Command() { + case "send_all": + message = "Чтобы отправить сообщение всем, отправь команду /send\\_confirm " + strconv.Itoa(messageRaw.ID) + case "send_league": + message = "Чтобы отправить сообщение всем игрокам лиги Инстинкт, отправь команду /send\\_confirm " + strconv.Itoa(messageRaw.ID) + } msg = tgbotapi.NewMessage(update.Message.Chat.ID, message) msg.ParseMode = "Markdown" diff --git a/lib/broadcaster/sender.go b/lib/broadcaster/sender.go index 6962fab..e204076 100644 --- a/lib/broadcaster/sender.go +++ b/lib/broadcaster/sender.go @@ -7,12 +7,11 @@ import ( "github.com/go-telegram-bot-api/telegram-bot-api" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "strconv" - "strings" ) // AdminBroadcastMessageSend sends saved message to all private chats func (b *Broadcaster) AdminBroadcastMessageSend(update *tgbotapi.Update, playerRaw *dbmapping.Player) string { - messageNum := strings.Replace(update.Message.Text, "/send_confirm ", "", 1) + messageNum := update.Message.CommandArguments() messageNumInt, _ := strconv.Atoi(messageNum) messageRaw, ok := b.getBroadcastMessageByID(messageNumInt) if !ok { @@ -27,9 +26,18 @@ func (b *Broadcaster) AdminBroadcastMessageSend(update *tgbotapi.Update, playerR broadcastingMessageBody := messageRaw.Text - privateChats, ok := c.Chatter.GetAllPrivateChats() - if !ok { - return "fail" + privateChats := []dbmapping.Chat{} + switch messageRaw.BroadcastType { + case "all": + privateChats, ok = c.Chatter.GetAllPrivateChats() + if !ok { + return "fail" + } + case "league": + privateChats, ok = c.Chatter.GetLeaguePrivateChats() + if !ok { + return "fail" + } } for i := range privateChats { @@ -48,7 +56,7 @@ func (b *Broadcaster) AdminBroadcastMessageSend(update *tgbotapi.Update, playerR return "fail" } - message := "Сообщение всем отправлено. Надеюсь, пользователи бота за него тебя не убьют.\n" + message := "Сообщение отправлено. Надеюсь, пользователи бота за него тебя не убьют.\n" msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) msg.ParseMode = "Markdown" diff --git a/lib/chatter/chatterinterface/chatterinterface.go b/lib/chatter/chatterinterface/chatterinterface.go index a0cb109..3742881 100644 --- a/lib/chatter/chatterinterface/chatterinterface.go +++ b/lib/chatter/chatterinterface/chatterinterface.go @@ -15,6 +15,7 @@ type ChatterInterface interface { GetOrCreateChat(update *tgbotapi.Update) (dbmapping.Chat, bool) GetChatByID(chatID int64) (dbmapping.Chat, bool) GetAllPrivateChats() ([]dbmapping.Chat, bool) + GetLeaguePrivateChats() ([]dbmapping.Chat, bool) GetAllGroupChats() ([]dbmapping.Chat, bool) UpdateChatTitle(chatRaw *dbmapping.Chat, newTitle string) (*dbmapping.Chat, bool) diff --git a/lib/chatter/getters.go b/lib/chatter/getters.go index 204bcdd..920ac37 100644 --- a/lib/chatter/getters.go +++ b/lib/chatter/getters.go @@ -115,6 +115,19 @@ func (ct *Chatter) GetAllPrivateChats() ([]dbmapping.Chat, bool) { return privateChats, true } +// GetLeaguePrivateChats returns all private chats which profiles are in our league +func (ct *Chatter) GetLeaguePrivateChats() ([]dbmapping.Chat, bool) { + privateChats := []dbmapping.Chat{} + + err := c.Db.Select(&privateChats, "SELECT c.* FROM chats c, players p WHERE c.chat_type='private' AND p.telegram_id = c.telegram_id AND p.league_id = 1") + if err != nil { + c.Log.Error(err) + return privateChats, false + } + + return privateChats, true +} + // GetAllGroupChats returns all group chats func (ct *Chatter) GetAllGroupChats() ([]dbmapping.Chat, bool) { groupChats := []dbmapping.Chat{} @@ -126,4 +139,4 @@ func (ct *Chatter) GetAllGroupChats() ([]dbmapping.Chat, bool) { } return groupChats, true -} \ No newline at end of file +} diff --git a/lib/forwarder/forwarder.go b/lib/forwarder/forwarder.go index d7ee650..d5277aa 100644 --- a/lib/forwarder/forwarder.go +++ b/lib/forwarder/forwarder.go @@ -22,8 +22,7 @@ func (f *Forwarder) ProcessForward(update *tgbotapi.Update, playerRaw *dbmapping if playerRaw.LeagueID == 1 { return c.Pokedexer.ParsePokememe(update, playerRaw) } else { - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) } case profileMsg.MatchString(text): c.Log.Debug("Profile posted!") diff --git a/lib/router/private_request.go b/lib/router/private_request.go index fef6e4a..0a4e704 100644 --- a/lib/router/private_request.go +++ b/lib/router/private_request.go @@ -26,15 +26,14 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi if playerRaw.ID != 0 { c.Forwarder.ProcessForward(update, playerRaw) } else { - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) } } } else { if update.Message.IsCommand() { switch { case update.Message.Command() == "start": - if playerRaw.ID != 0 { + if playerRaw.LeagueID != 0 { c.Welcomer.PrivateWelcomeMessageAuthorized(update, playerRaw) return "ok" } @@ -56,8 +55,7 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi return "ok" } - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) case update.Message.Command() == "best": c.Pokedexer.BestPokememesList(update, playerRaw) return "ok" @@ -67,24 +65,28 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi return "ok" } - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) + case update.Message.Command() == "send_league": + if c.Users.PlayerBetterThan(playerRaw, "admin") { + c.Broadcaster.AdminBroadcastMessageCompose(update, playerRaw) + return "ok" + } + + return c.Talkers.AnyMessageUnauthorized(update) case update.Message.Command() == "send_confirm": if c.Users.PlayerBetterThan(playerRaw, "admin") { c.Broadcaster.AdminBroadcastMessageSend(update, playerRaw) return "ok" } - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) case update.Message.Command() == "group_chats": if c.Users.PlayerBetterThan(playerRaw, "admin") { c.Chatter.GroupsList(update) return "ok" } - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) case update.Message.Command() == "squads": return c.Squader.SquadsList(update, playerRaw) case update.Message.Command() == "make_squad": @@ -92,23 +94,20 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi return c.Squader.CreateSquad(update) } - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) case update.Message.Command() == "pin": if c.Users.PlayerBetterThan(playerRaw, "admin") { return c.Pinner.PinMessageToAllChats(update) } - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) case usersMsg.MatchString(text): if c.Users.PlayerBetterThan(playerRaw, "admin") { return c.Users.UsersList(update) } - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) case update.Message.Command() == "squad_add_user": return c.Squader.AddUserToSquad(update, playerRaw) diff --git a/lib/squader/responders.go b/lib/squader/responders.go index bd7db92..6ba42e1 100644 --- a/lib/squader/responders.go +++ b/lib/squader/responders.go @@ -14,8 +14,7 @@ import ( func (s *Squader) SquadsList(update *tgbotapi.Update, playerRaw *dbmapping.Player) string { if !c.Users.PlayerBetterThan(playerRaw, "admin") { if s.isUserAnyCommander(playerRaw.ID) { - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) } } squads, ok := s.getAllSquadsWithChats() @@ -53,15 +52,13 @@ func (s *Squader) SquadInfo(update *tgbotapi.Update, playerRaw *dbmapping.Player if !c.Users.PlayerBetterThan(playerRaw, "admin") { if s.getUserRoleForSquad(squadID, playerRaw.ID) != "commander" { - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) } } squad, ok := s.GetSquadByID(squadID) if !ok { - c.Talkers.BotError(update) - return "fail" + return c.Talkers.BotError(update) } message := "*Информация об отряде* _" + squad.Chat.Name + "_*:*\n" diff --git a/lib/squader/squader.go b/lib/squader/squader.go index 9447a2d..49f2136 100644 --- a/lib/squader/squader.go +++ b/lib/squader/squader.go @@ -292,13 +292,11 @@ func (s *Squader) AddUserToSquad(update *tgbotapi.Update, adderRaw *dbmapping.Pl if !c.Users.PlayerBetterThan(adderRaw, "admin") { if userType == "commander" { - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) } if s.getUserRoleForSquad(squadRaw.ID, adderRaw.ID) != "commander" { - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) } } diff --git a/lib/talkers/errors.go b/lib/talkers/errors.go index 7799e1d..16523b6 100644 --- a/lib/talkers/errors.go +++ b/lib/talkers/errors.go @@ -8,7 +8,7 @@ import ( ) // AnyMessageUnauthorized throws when user can't do something -func (t *Talkers) AnyMessageUnauthorized(update *tgbotapi.Update) { +func (t *Talkers) AnyMessageUnauthorized(update *tgbotapi.Update) string { message := "Извини, действие для тебя недоступно. Возможно, у меня нет твоего профиля или же твои права недостаточны для совершения данного действия\n\n" message += "Если тебе кажется, что это ошибка, пиши @fat0troll.\n" @@ -16,10 +16,12 @@ func (t *Talkers) AnyMessageUnauthorized(update *tgbotapi.Update) { msg.ParseMode = "Markdown" c.Bot.Send(msg) + + return "fail" } // BotError throws when bot can't do something -func (t *Talkers) BotError(update *tgbotapi.Update) { +func (t *Talkers) BotError(update *tgbotapi.Update) string { message := "Ой, внутренняя ошибка в боте :(\n\n" message += "Напиши @fat0troll, приложив форвардом последние сообщения до этого.\n" @@ -27,4 +29,6 @@ func (t *Talkers) BotError(update *tgbotapi.Update) { msg.ParseMode = "Markdown" c.Bot.Send(msg) + + return "fail" } diff --git a/lib/talkers/help.go b/lib/talkers/help.go index 6480d7e..9b73a73 100644 --- a/lib/talkers/help.go +++ b/lib/talkers/help.go @@ -19,6 +19,7 @@ func (t *Talkers) HelpMessage(update *tgbotapi.Update, playerRaw *dbmapping.Play message += "+ /pokedeks – получить список известных боту покемемов\n" if c.Users.PlayerBetterThan(playerRaw, "admin") { message += "+ /send\\_all _текст_ — отправить сообщение всем пользователям бота\n" + message += "+ /send\\_league _текст_ — отправить сообщение всем пользователям бота, у которых профиль лиги Инстинкт\n" message += "+ /group\\_chats — получить список групп, в которых работает бот.\n" message += "+ /squads — получить список отрядов.\n" message += "+ /pin _текст_ — отправить сообщение во все группы, где находится бот. Сообщение будет автоматически запинено.\n" diff --git a/lib/talkers/talkersinterface/talkersinterface.go b/lib/talkers/talkersinterface/talkersinterface.go index f795d11..a8c8961 100644 --- a/lib/talkers/talkersinterface/talkersinterface.go +++ b/lib/talkers/talkersinterface/talkersinterface.go @@ -13,8 +13,8 @@ type TalkersInterface interface { Init() HelpMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) - AnyMessageUnauthorized(update *tgbotapi.Update) - BotError(update *tgbotapi.Update) + AnyMessageUnauthorized(update *tgbotapi.Update) string + BotError(update *tgbotapi.Update) string DurakMessage(update *tgbotapi.Update) MatMessage(update *tgbotapi.Update) diff --git a/lib/users/responders.go b/lib/users/responders.go index 4b432c7..9fb3350 100644 --- a/lib/users/responders.go +++ b/lib/users/responders.go @@ -14,8 +14,7 @@ import ( func (u *Users) ProfileMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) string { profileRaw, ok := u.GetProfile(playerRaw.ID) if !ok { - c.Talkers.AnyMessageUnauthorized(update) - return "fail" + return c.Talkers.AnyMessageUnauthorized(update) } league := dbmapping.League{} err := c.Db.Get(&league, c.Db.Rebind("SELECT * FROM leagues WHERE id=?"), playerRaw.LeagueID) @@ -124,8 +123,7 @@ func (u *Users) UsersList(update *tgbotapi.Update) string { } usersArray, ok := u.getUsersWithProfiles() if !ok { - c.Talkers.BotError(update) - return "fail" + return c.Talkers.BotError(update) } else { u.usersList(update, page, usersArray) return "ok"