diff --git a/cmd/i2_bot/i2_bot.go b/cmd/i2_bot/i2_bot.go index f4e8f4f..3bc6d0e 100644 --- a/cmd/i2_bot/i2_bot.go +++ b/cmd/i2_bot/i2_bot.go @@ -15,6 +15,7 @@ import ( "source.wtfteam.pro/i2_bot/i2_bot/lib/pokedexer" "source.wtfteam.pro/i2_bot/i2_bot/lib/reminder" "source.wtfteam.pro/i2_bot/i2_bot/lib/router" + "source.wtfteam.pro/i2_bot/i2_bot/lib/sender" "source.wtfteam.pro/i2_bot/i2_bot/lib/squader" "source.wtfteam.pro/i2_bot/i2_bot/lib/statistics" "source.wtfteam.pro/i2_bot/i2_bot/lib/talkers" @@ -34,6 +35,7 @@ func main() { migrations.New(c) c.RunDatabaseMigrations() datacache.New(c) + sender.New(c) forwarder.New(c) pokedexer.New(c) pinner.New(c) diff --git a/lib/appcontext/appcontext.go b/lib/appcontext/appcontext.go index 08ce47a..b8b92e4 100644 --- a/lib/appcontext/appcontext.go +++ b/lib/appcontext/appcontext.go @@ -1,16 +1,18 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package appcontext import ( + "net/http" + "os" + "time" + "bitbucket.org/pztrn/flagger" "bitbucket.org/pztrn/mogrus" "github.com/go-telegram-bot-api/telegram-bot-api" "github.com/jmoiron/sqlx" "github.com/robfig/cron" - "net/http" - "os" "source.wtfteam.pro/i2_bot/i2_bot/lib/broadcaster/broadcasterinterface" "source.wtfteam.pro/i2_bot/i2_bot/lib/chatter/chatterinterface" "source.wtfteam.pro/i2_bot/i2_bot/lib/config" @@ -23,12 +25,12 @@ import ( "source.wtfteam.pro/i2_bot/i2_bot/lib/pokedexer/pokedexerinterface" "source.wtfteam.pro/i2_bot/i2_bot/lib/reminder/reminderinterface" "source.wtfteam.pro/i2_bot/i2_bot/lib/router/routerinterface" + "source.wtfteam.pro/i2_bot/i2_bot/lib/sender/senderinterface" "source.wtfteam.pro/i2_bot/i2_bot/lib/squader/squaderinterface" "source.wtfteam.pro/i2_bot/i2_bot/lib/statistics/statisticsinterface" "source.wtfteam.pro/i2_bot/i2_bot/lib/talkers/talkersinterface" "source.wtfteam.pro/i2_bot/i2_bot/lib/users/usersinterface" "source.wtfteam.pro/i2_bot/i2_bot/lib/welcomer/welcomerinterface" - "time" ) // Context is an application context struct @@ -50,6 +52,7 @@ type Context struct { Pinner pinnerinterface.PinnerInterface Reminder reminderinterface.ReminderInterface Chatter chatterinterface.ChatterInterface + Sender senderinterface.SenderInterface Squader squaderinterface.SquaderInterface Users usersinterface.UsersInterface Statistics statisticsinterface.StatisticsInterface @@ -89,7 +92,7 @@ func (c *Context) Init() { c.Cfg = config.New() c.Cfg.Init(c.Log, configPath) - logFile, err := os.OpenFile(c.Cfg.Logs.LogPath, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0660) + logFile, err := os.OpenFile(c.Cfg.Logs.LogPath, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0600) if err != nil { log.Fatalln(err) } @@ -161,6 +164,12 @@ func (c *Context) RegisterRouterInterface(ri routerinterface.RouterInterface) { c.Router.Init() } +// RegisterSenderInterface registering sender interface in application +func (c *Context) RegisterSenderInterface(si senderinterface.SenderInterface) { + c.Sender = si + c.Sender.Init() +} + // RegisterStatisticsInterface registers statistics interface in application func (c *Context) RegisterStatisticsInterface(si statisticsinterface.StatisticsInterface) { c.Statistics = si @@ -193,8 +202,14 @@ func (c *Context) RegisterUsersInterface(ui usersinterface.UsersInterface) { // RunDatabaseMigrations applies migrations on bot's startup func (c *Context) RunDatabaseMigrations() { - c.Migrations.SetDialect("mysql") - c.Migrations.Migrate() + err := c.Migrations.SetDialect("mysql") + if err != nil { + c.Log.Fatal(err.Error()) + } + err = c.Migrations.Migrate() + if err != nil { + c.Log.Fatal(err.Error()) + } } // StartBot starts listening for Telegram updates @@ -205,7 +220,12 @@ func (c *Context) StartBot() { } updates := c.Bot.ListenForWebhook("/" + c.Bot.Token) - go http.ListenAndServe(c.Cfg.Telegram.ListenAddress, nil) + go func() { + err = http.ListenAndServe(c.Cfg.Telegram.ListenAddress, nil) + }() + if err != nil { + c.Log.Fatal(err.Error()) + } c.Log.Info("Listening on " + c.Cfg.Telegram.ListenAddress) c.Log.Info("Webhook URL: " + c.Cfg.Telegram.WebHookDomain + c.Bot.Token) @@ -214,13 +234,13 @@ func (c *Context) StartBot() { if update.Message != nil { if update.Message.From != nil { if update.Message.Date > (int(time.Now().Unix()) - 5) { - go c.Router.RouteRequest(&update) + go c.Router.RouteRequest(update) } } } else if update.InlineQuery != nil { - c.Router.RouteInline(&update) + c.Router.RouteInline(update) } else if update.CallbackQuery != nil { - c.Router.RouteCallback(&update) + c.Router.RouteCallback(update) } else if update.ChosenInlineResult != nil { c.Log.Debug(update.ChosenInlineResult.ResultID) } else { diff --git a/lib/appcontext/exported.go b/lib/appcontext/exported.go index 7ed4c2d..c746d3f 100644 --- a/lib/appcontext/exported.go +++ b/lib/appcontext/exported.go @@ -1,12 +1,8 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package appcontext -var ( - a *Context -) - // New is a Context creation function func New() *Context { c := &Context{} diff --git a/lib/broadcaster/responders.go b/lib/broadcaster/responders.go index a27759d..e37ecb3 100644 --- a/lib/broadcaster/responders.go +++ b/lib/broadcaster/responders.go @@ -1,48 +1,41 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package broadcaster import ( + "strconv" + "github.com/go-telegram-bot-api/telegram-bot-api" "source.wtfteam.pro/i2_bot/i2_bot/lib/dbmapping" - "strconv" ) // AdminBroadcastMessageCompose saves message for future broadcast func (b *Broadcaster) AdminBroadcastMessageCompose(update *tgbotapi.Update, playerRaw *dbmapping.Player) string { broadcastingMessageBody := update.Message.CommandArguments() - messageRaw, ok := dbmapping.Broadcast{}, false - + messageMode := "none" switch update.Message.Command() { case "send_all": - messageRaw, ok = b.createBroadcastMessage(playerRaw, broadcastingMessageBody, "all") - if !ok { - return "fail" - } + messageMode = "all" case "send_league": - messageRaw, ok = b.createBroadcastMessage(playerRaw, broadcastingMessageBody, "league") - if !ok { - return "fail" - } + messageMode = "league" + } + + messageRaw, ok := b.createBroadcastMessage(playerRaw, broadcastingMessageBody, messageMode) + if !ok { + return "fail" } message := "Сообщение сохранено в базу.\n" message += "Выглядеть оно будет так:" - msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) - msg.ParseMode = "Markdown" - - c.Bot.Send(msg) + c.Sender.SendMarkdownAnswer(update, message) broadcastingMessage := "*Привет, %username%!*\n\n" broadcastingMessage += "*Важное сообщение от администратора " + update.Message.From.FirstName + " " + update.Message.From.LastName + "* (@" + update.Message.From.UserName + ")\n\n" broadcastingMessage += messageRaw.Text - msg = tgbotapi.NewMessage(update.Message.Chat.ID, broadcastingMessage) - msg.ParseMode = "Markdown" - - c.Bot.Send(msg) + c.Sender.SendMarkdownAnswer(update, broadcastingMessage) switch update.Message.Command() { case "send_all": @@ -51,10 +44,7 @@ func (b *Broadcaster) AdminBroadcastMessageCompose(update *tgbotapi.Update, play message = "Чтобы отправить сообщение всем игрокам лиги Инстинкт, отправь команду /send\\_confirm " + strconv.Itoa(messageRaw.ID) } - msg = tgbotapi.NewMessage(update.Message.Chat.ID, message) - msg.ParseMode = "Markdown" - - c.Bot.Send(msg) + c.Sender.SendMarkdownAnswer(update, message) return "ok" } diff --git a/lib/broadcaster/sender.go b/lib/broadcaster/sender.go index 4cfa5d4..3b1deb0 100644 --- a/lib/broadcaster/sender.go +++ b/lib/broadcaster/sender.go @@ -1,12 +1,14 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package broadcaster import ( - "github.com/go-telegram-bot-api/telegram-bot-api" - "source.wtfteam.pro/i2_bot/i2_bot/lib/dbmapping" "strconv" + + "github.com/go-telegram-bot-api/telegram-bot-api" + "source.wtfteam.pro/i2_bot/i2_bot/lib/constants" + "source.wtfteam.pro/i2_bot/i2_bot/lib/dbmapping" ) // AdminBroadcastMessageSend sends saved message to all private chats @@ -15,13 +17,13 @@ func (b *Broadcaster) AdminBroadcastMessageSend(update *tgbotapi.Update, playerR messageNumInt, _ := strconv.Atoi(messageNum) messageRaw, ok := b.getBroadcastMessageByID(messageNumInt) if !ok { - return "fail" + return constants.BotError } if messageRaw.AuthorID != playerRaw.ID { - return "fail" + return constants.UserRequestForbidden } if messageRaw.Status != "new" { - return "fail" + return constants.UserRequestFailed } broadcastingMessageBody := messageRaw.Text @@ -29,7 +31,7 @@ func (b *Broadcaster) AdminBroadcastMessageSend(update *tgbotapi.Update, playerR profileRaw, err := c.DataCache.GetProfileByPlayerID(playerRaw.ID) if err != nil { c.Log.Error(err.Error()) - return "fail" + return constants.UserRequestFailed } prettyName := profileRaw.Nickname + " (@" + profileRaw.TelegramNickname + ")" @@ -48,22 +50,17 @@ func (b *Broadcaster) AdminBroadcastMessageSend(update *tgbotapi.Update, playerR broadcastingMessage += "*Важное сообщение от администратора *" + prettyName + "\n\n" broadcastingMessage += broadcastingMessageBody - msg := tgbotapi.NewMessage(int64(chat.TelegramID), broadcastingMessage) - msg.ParseMode = "Markdown" - c.Bot.Send(msg) + c.Sender.SendMarkdownMessageToChatID(chat.TelegramID, broadcastingMessage) } messageRaw, ok = b.updateBroadcastMessageStatus(messageRaw.ID, "sent") if !ok { - return "fail" + return constants.BotError } message := "Сообщение отправлено. Надеюсь, пользователи бота за него тебя не убьют.\n" - msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) - msg.ParseMode = "Markdown" + c.Sender.SendMarkdownAnswer(update, message) - c.Bot.Send(msg) - - return "ok" + return constants.UserRequestSuccess } diff --git a/lib/constants/constants.go b/lib/constants/constants.go new file mode 100644 index 0000000..1cd6306 --- /dev/null +++ b/lib/constants/constants.go @@ -0,0 +1,15 @@ +// i2_bot – Instinct PokememBro Bot +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov + +package constants + +const ( + // BotError is return value, if something went wrong with bot's internal data handling + BotError = "bot_error" + // UserRequestFailed is return value, if something went wrong with user input + UserRequestFailed = "fail" + // UserRequestSuccess is success return value + UserRequestSuccess = "ok" + // UserRequestForbidden is return value, if user can't perform some action + UserRequestForbidden = "forbidden" +) diff --git a/lib/migrations/10_update_leagues.go b/lib/migrations/10_update_leagues.go index 3cc4b4c..f124d7d 100644 --- a/lib/migrations/10_update_leagues.go +++ b/lib/migrations/10_update_leagues.go @@ -1,5 +1,5 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package migrations @@ -9,36 +9,30 @@ import ( // UpdateLeaguesUp fixes some fuckup with leagues' emoji func UpdateLeaguesUp(tx *sql.Tx) error { - _, err := tx.Exec("UPDATE `leagues` SET symbol='🈸' WHERE symbol=':u7533:';") + _, err := tx.Exec("UPDATE `leagues` SET symbol='🈸' WHERE symbol=':u7533:'") if err != nil { return err } - _, err = tx.Exec("UPDATE `leagues` SET symbol='🈳 ' WHERE symbol=':u6e80';") - if err != nil { - return err - } - _, err = tx.Exec("UPDATE `leagues` SET symbol='🈵' WHERE symbol=':u7a7a:';") + _, err = tx.Exec("UPDATE `leagues` SET symbol='🈳 ' WHERE symbol=':u6e80'") if err != nil { return err } + _, err = tx.Exec("UPDATE `leagues` SET symbol='🈵' WHERE symbol=':u7a7a:'") - return nil + return err } // UpdateLeaguesDown returns leagues emoji fuckup for sanity purposes func UpdateLeaguesDown(tx *sql.Tx) error { - _, err := tx.Exec("UPDATE `leagues` SET symbol=':u7533:' WHERE symbol='🈸';") + _, err := tx.Exec("UPDATE `leagues` SET symbol=':u7533:' WHERE symbol='🈸'") if err != nil { return err } - _, err = tx.Exec("UPDATE `leagues` SET symbol=':u6e80' WHERE symbol='🈳 ';") - if err != nil { - return err - } - _, err = tx.Exec("UPDATE `leagues` SET symbol=':u7a7a:' WHERE symbol='🈵';") + _, err = tx.Exec("UPDATE `leagues` SET symbol=':u6e80' WHERE symbol='🈳 '") if err != nil { return err } + _, err = tx.Exec("UPDATE `leagues` SET symbol=':u7a7a:' WHERE symbol='🈵'") - return nil + return err } diff --git a/lib/migrations/11_profile_data_additions.go b/lib/migrations/11_profile_data_additions.go index 16dda35..6918286 100644 --- a/lib/migrations/11_profile_data_additions.go +++ b/lib/migrations/11_profile_data_additions.go @@ -9,7 +9,7 @@ import ( // ProfileDataAdditionsUp creates some helping databases for profiles func ProfileDataAdditionsUp(tx *sql.Tx) error { - _, err := tx.Exec("ALTER TABLE `profiles` ADD `pokeballs` INT(11) DEFAULT 5 NOT NULL COMMENT 'Покеболы' AFTER `level_id`;") + _, err := tx.Exec("ALTER TABLE `profiles` ADD `pokeballs` INT(11) DEFAULT 5 NOT NULL COMMENT 'Покеболы' AFTER `level_id`") if err != nil { return err } @@ -22,64 +22,58 @@ func ProfileDataAdditionsUp(tx *sql.Tx) error { request += "PRIMARY KEY (`id`)," request += "UNIQUE KEY `id` (`id`)," request += "KEY `levels_created_at` (`created_at`)" - request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Уровни';" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Уровни'" _, err = tx.Exec(request) if err != nil { return err } // Insert levels - _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 200, 6, NOW());") + _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 200, 6, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 400, 12, NOW());") + _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 400, 12, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 800, 24, NOW());") + _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 800, 24, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 1600, 48, NOW());") + _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 1600, 48, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 3200, 96, NOW());") + _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 3200, 96, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 6400, 192, NOW());") + _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 6400, 192, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 12800, 384, NOW());") + _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 12800, 384, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 25600, 768, NOW());") - if err != nil { - return err - } - _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 51200, 1536, NOW());") + _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 25600, 768, NOW())") if err != nil { return err } + _, err = tx.Exec("INSERT INTO `levels` VALUES(NULL, 51200, 1536, NOW())") - return nil + return err } // ProfileDataAdditionsDown drops `levels` table and `pokeballs` column of `profiles` table func ProfileDataAdditionsDown(tx *sql.Tx) error { - _, err := tx.Exec("ALTER TABLE `profiles` DROP COLUMN `pokeballs`;") + _, err := tx.Exec("ALTER TABLE `profiles` DROP COLUMN `pokeballs`") if err != nil { return err } - _, err = tx.Exec("DROP TABLE `levels`;") - if err != nil { - return err - } + _, err = tx.Exec("DROP TABLE `levels`") - return nil + return err } diff --git a/lib/migrations/2_create_players.go b/lib/migrations/2_create_players.go index 5c85a53..000d15d 100644 --- a/lib/migrations/2_create_players.go +++ b/lib/migrations/2_create_players.go @@ -1,5 +1,5 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package migrations @@ -21,19 +21,16 @@ func CreatePlayersUp(tx *sql.Tx) error { request += "UNIQUE KEY `id` (`id`)," request += "KEY `players_created_at` (`created_at`)," request += "KEY `players_updated_at` (`updated_at`)" - request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Зарегистрированные игроки';" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Зарегистрированные игроки'" + _, err := tx.Exec(request) - if err != nil { - return err - } - return nil + + return err } // CreatePlayersDown drops `players` table func CreatePlayersDown(tx *sql.Tx) error { _, err := tx.Exec("DROP TABLE `players`;") - if err != nil { - return err - } - return nil + + return err } diff --git a/lib/migrations/3_create_profiles.go b/lib/migrations/3_create_profiles.go index 4e852b3..1b9dee0 100644 --- a/lib/migrations/3_create_profiles.go +++ b/lib/migrations/3_create_profiles.go @@ -1,5 +1,5 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package migrations @@ -25,19 +25,16 @@ func CreateProfilesUp(tx *sql.Tx) error { request += "UNIQUE KEY `id` (`id`)," request += "KEY `profiles_created_at` (`created_at`)," request += "KEY `profiles_nickname` (`nickname`)" - request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Профили зарегистрированных игроков';" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Профили зарегистрированных игроков'" + _, err := tx.Exec(request) - if err != nil { - return err - } - return nil + + return err } // CreateProfilesDown drops `profiles` table func CreateProfilesDown(tx *sql.Tx) error { - _, err := tx.Exec("DROP TABLE `profiles`;") - if err != nil { - return err - } - return nil + _, err := tx.Exec("DROP TABLE `profiles`") + + return err } diff --git a/lib/migrations/4_create_pokememes.go b/lib/migrations/4_create_pokememes.go index c25e9d4..b49cf28 100644 --- a/lib/migrations/4_create_pokememes.go +++ b/lib/migrations/4_create_pokememes.go @@ -1,5 +1,5 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package migrations @@ -27,19 +27,16 @@ func CreatePokememesUp(tx *sql.Tx) error { request += "UNIQUE KEY `id` (`id`)," request += "KEY `pokememes_created_at` (`created_at`)," request += "KEY `pokememes_player_id` (`player_id`)" - request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Покемемы';" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Покемемы'" + _, err := tx.Exec(request) - if err != nil { - return err - } - return nil + + return err } // CreatePokememesDown drops `pokememes` table func CreatePokememesDown(tx *sql.Tx) error { - _, err := tx.Exec("DROP TABLE `pokememes`;") - if err != nil { - return err - } - return nil + _, err := tx.Exec("DROP TABLE `pokememes`") + + return err } diff --git a/lib/migrations/5_create_locations.go b/lib/migrations/5_create_locations.go index 76df703..d25c98c 100644 --- a/lib/migrations/5_create_locations.go +++ b/lib/migrations/5_create_locations.go @@ -1,5 +1,5 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package migrations @@ -17,46 +17,41 @@ func CreateLocationsUp(tx *sql.Tx) error { request += "PRIMARY KEY (`id`)," request += "UNIQUE KEY `id` (`id`)," request += "KEY `locations_created_at` (`created_at`)" - request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Локации';" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Локации'" _, err := tx.Exec(request) if err != nil { return err } // Insert locations - _, err = tx.Exec("INSERT INTO `locations` VALUES(NULL, ':evergreen_tree:', 'Лес', NOW());") + _, err = tx.Exec("INSERT INTO `locations` VALUES(NULL, ':evergreen_tree:', 'Лес', NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `locations` VALUES(NULL, '⛰', 'Горы', NOW());") + _, err = tx.Exec("INSERT INTO `locations` VALUES(NULL, '⛰', 'Горы', NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `locations` VALUES(NULL, ':rowboat:', 'Озеро', NOW());") + _, err = tx.Exec("INSERT INTO `locations` VALUES(NULL, ':rowboat:', 'Озеро', NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `locations` VALUES(NULL, '🏙', 'Город', NOW());") + _, err = tx.Exec("INSERT INTO `locations` VALUES(NULL, '🏙', 'Город', NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `locations` VALUES(NULL, '🏛', 'Катакомбы', NOW());") - if err != nil { - return err - } - _, err = tx.Exec("INSERT INTO `locations` VALUES(NULL, ':church:', 'Кладбище', NOW());") + _, err = tx.Exec("INSERT INTO `locations` VALUES(NULL, '🏛', 'Катакомбы', NOW())") if err != nil { return err } + _, err = tx.Exec("INSERT INTO `locations` VALUES(NULL, ':church:', 'Кладбище', NOW())") - return nil + return err } // CreateLocationsDown drops `locations` table func CreateLocationsDown(tx *sql.Tx) error { - _, err := tx.Exec("DROP TABLE `locations`;") - if err != nil { - return err - } - return nil + _, err := tx.Exec("DROP TABLE `locations`") + + return err } diff --git a/lib/migrations/6_create_elements.go b/lib/migrations/6_create_elements.go index 57fe9c8..4b44b08 100644 --- a/lib/migrations/6_create_elements.go +++ b/lib/migrations/6_create_elements.go @@ -1,5 +1,5 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package migrations @@ -18,70 +18,65 @@ func CreateElementsUp(tx *sql.Tx) error { request += "PRIMARY KEY (`id`)," request += "UNIQUE KEY `id` (`id`)," request += "KEY `elements_created_at` (`created_at`)" - request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Элементы';" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Элементы'" _, err := tx.Exec(request) if err != nil { return err } // Insert elements - _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '👊', 'Боевой', 1, NOW());") + _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '👊', 'Боевой', 1, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '🌀', 'Летающий', 1, NOW());") + _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '🌀', 'Летающий', 1, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '💀', 'Ядовитый', 1, NOW());") + _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '💀', 'Ядовитый', 1, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '🗿', 'Каменный', 1, NOW());") + _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '🗿', 'Каменный', 1, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '🔥', 'Огненный', 2, NOW());") + _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '🔥', 'Огненный', 2, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '⚡', 'Электрический', 2, NOW());") + _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '⚡', 'Электрический', 2, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '💧', 'Водяной', 2, NOW());") + _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '💧', 'Водяной', 2, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '🍀', 'Травяной', 2, NOW());") + _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '🍀', 'Травяной', 2, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '💩', 'Шоколадный', 3, NOW());") + _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '💩', 'Шоколадный', 3, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '👁', 'Психический', 3, NOW());") + _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '👁', 'Психический', 3, NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '👿', 'Темный', 3, NOW());") - if err != nil { - return err - } - _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '⌛', 'Времени', 1, NOW());") + _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '👿', 'Темный', 3, NOW())") if err != nil { return err } + _, err = tx.Exec("INSERT INTO `elements` VALUES(NULL, '⌛', 'Времени', 1, NOW())") - return nil + return err } // CreateElementsDown drops `elements` table func CreateElementsDown(tx *sql.Tx) error { - _, err := tx.Exec("DROP TABLE `elements`;") - if err != nil { - return err - } - return nil + _, err := tx.Exec("DROP TABLE `elements`") + + return err } diff --git a/lib/migrations/7_create_leagues.go b/lib/migrations/7_create_leagues.go index 412a469..44eabf8 100644 --- a/lib/migrations/7_create_leagues.go +++ b/lib/migrations/7_create_leagues.go @@ -1,5 +1,5 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package migrations @@ -17,34 +17,29 @@ func CreateLeaguesUp(tx *sql.Tx) error { request += "PRIMARY KEY (`id`)," request += "UNIQUE KEY `id` (`id`)," request += "KEY `leagues_created_at` (`created_at`)" - request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Лиги';" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Лиги'" _, err := tx.Exec(request) if err != nil { return err } // Insert locations - _, err = tx.Exec("INSERT INTO `leagues` VALUES(NULL, ':u7533:', 'ИНСТИНКТ', NOW());") + _, err = tx.Exec("INSERT INTO `leagues` VALUES(NULL, ':u7533:', 'ИНСТИНКТ', NOW())") if err != nil { return err } - _, err = tx.Exec("INSERT INTO `leagues` VALUES(NULL, ':u6e80', 'ОТВАГА', NOW());") - if err != nil { - return err - } - _, err = tx.Exec("INSERT INTO `leagues` VALUES(NULL, ':u7a7a:', 'МИСТИКА', NOW());") + _, err = tx.Exec("INSERT INTO `leagues` VALUES(NULL, ':u6e80', 'ОТВАГА', NOW())") if err != nil { return err } + _, err = tx.Exec("INSERT INTO `leagues` VALUES(NULL, ':u7a7a:', 'МИСТИКА', NOW())") - return nil + return err } // CreateLeaguesDown drops `leagues` table func CreateLeaguesDown(tx *sql.Tx) error { - _, err := tx.Exec("DROP TABLE `leagues`;") - if err != nil { - return err - } - return nil + _, err := tx.Exec("DROP TABLE `leagues`") + + return err } diff --git a/lib/migrations/8_create_relations.go b/lib/migrations/8_create_relations.go index 609da89..a183397 100644 --- a/lib/migrations/8_create_relations.go +++ b/lib/migrations/8_create_relations.go @@ -1,5 +1,5 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package migrations @@ -17,7 +17,7 @@ func CreateRelationsUp(tx *sql.Tx) error { request += "PRIMARY KEY (`id`)," request += "UNIQUE KEY `id` (`id`)," request += "KEY `pokememes_locations_created_at` (`created_at`)" - request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Покемемы-Локации';" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Покемемы-Локации'" _, err := tx.Exec(request) if err != nil { return err @@ -31,23 +31,19 @@ func CreateRelationsUp(tx *sql.Tx) error { request += "PRIMARY KEY (`id`)," request += "UNIQUE KEY `id` (`id`)," request += "KEY `pokememes_elements_created_at` (`created_at`)" - request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Покемемы-Элементы';" - _, err2 := tx.Exec(request) - if err2 != nil { - return err2 - } - return nil + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Покемемы-Элементы'" + _, err = tx.Exec(request) + + return err } // CreateRelationsDown drops pokememe-* relations tables func CreateRelationsDown(tx *sql.Tx) error { - _, err := tx.Exec("DROP TABLE `pokememes_locations`;") + _, err := tx.Exec("DROP TABLE `pokememes_locations`") if err != nil { return err } - _, err2 := tx.Exec("DROP TABLE `pokememes_elements`;") - if err2 != nil { - return err2 - } - return nil + _, err = tx.Exec("DROP TABLE `pokememes_elements`;") + + return err } diff --git a/lib/migrations/9_update_locations.go b/lib/migrations/9_update_locations.go index 9f0f029..4ba19df 100644 --- a/lib/migrations/9_update_locations.go +++ b/lib/migrations/9_update_locations.go @@ -1,5 +1,5 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package migrations @@ -9,36 +9,30 @@ import ( // UpdateLocationsUp fixes some fuckup with locations' emoji func UpdateLocationsUp(tx *sql.Tx) error { - _, err := tx.Exec("UPDATE `locations` SET symbol='⛪' WHERE symbol=':church:';") + _, err := tx.Exec("UPDATE `locations` SET symbol='⛪' WHERE symbol=':church:'") if err != nil { return err } - _, err = tx.Exec("UPDATE `locations` SET symbol='🌲' WHERE symbol=':evergreen_tree:';") - if err != nil { - return err - } - _, err = tx.Exec("UPDATE `locations` SET symbol='🚣' WHERE symbol=':rowboat:';") + _, err = tx.Exec("UPDATE `locations` SET symbol='🌲' WHERE symbol=':evergreen_tree:'") if err != nil { return err } + _, err = tx.Exec("UPDATE `locations` SET symbol='🚣' WHERE symbol=':rowboat:'") - return nil + return err } // UpdateLocationsDown returns location emoji fuckup for sanity purposes func UpdateLocationsDown(tx *sql.Tx) error { - _, err := tx.Exec("UPDATE `locations` SET symbol=':church:' WHERE symbol='⛪'';") + _, err := tx.Exec("UPDATE `locations` SET symbol=':church:' WHERE symbol='⛪''") if err != nil { return err } - _, err = tx.Exec("UPDATE `locations` SET symbol=':evergreen_tree:' WHERE symbol='🌲';") - if err != nil { - return err - } - _, err = tx.Exec("UPDATE `locations` SET symbol=':rowboat:' WHERE symbol='🚣';") + _, err = tx.Exec("UPDATE `locations` SET symbol=':evergreen_tree:' WHERE symbol='🌲'") if err != nil { return err } + _, err = tx.Exec("UPDATE `locations` SET symbol=':rowboat:' WHERE symbol='🚣'") - return nil + return err } diff --git a/lib/router/callback_request.go b/lib/router/callback_request.go index 56a8152..31000eb 100644 --- a/lib/router/callback_request.go +++ b/lib/router/callback_request.go @@ -4,12 +4,13 @@ package router import ( - "github.com/go-telegram-bot-api/telegram-bot-api" "regexp" + + "github.com/go-telegram-bot-api/telegram-bot-api" ) // RouteCallback routes inline requests to bot -func (r *Router) RouteCallback(update *tgbotapi.Update) string { +func (r *Router) RouteCallback(update tgbotapi.Update) string { playerRaw, err := c.DataCache.GetOrCreatePlayerByTelegramID(update.CallbackQuery.From.ID) if err != nil { c.Log.Error(err.Error()) @@ -17,7 +18,7 @@ func (r *Router) RouteCallback(update *tgbotapi.Update) string { } if playerRaw.Status == "banned" { - return c.Talkers.BanError(update) + return c.Talkers.BanError(&update) } var enableAlarmCallback = regexp.MustCompile("enable_reminder_(\\d+)\\z") @@ -25,9 +26,9 @@ func (r *Router) RouteCallback(update *tgbotapi.Update) string { switch { case enableAlarmCallback.MatchString(update.CallbackQuery.Data): - return c.Reminder.CreateAlarmSetting(update, playerRaw) + return c.Reminder.CreateAlarmSetting(&update, playerRaw) case disableAlarmCallback.MatchString(update.CallbackQuery.Data): - return c.Reminder.DestroyAlarmSetting(update, playerRaw) + return c.Reminder.DestroyAlarmSetting(&update, playerRaw) } return "ok" diff --git a/lib/router/group_request.go b/lib/router/group_request.go index a1b04ad..065c847 100644 --- a/lib/router/group_request.go +++ b/lib/router/group_request.go @@ -4,13 +4,14 @@ package router import ( - "github.com/go-telegram-bot-api/telegram-bot-api" "math/rand" "regexp" + + "github.com/go-telegram-bot-api/telegram-bot-api" "source.wtfteam.pro/i2_bot/i2_bot/lib/dbmapping" ) -func (r *Router) routeGroupRequest(update *tgbotapi.Update, playerRaw *dbmapping.Player, chatRaw *dbmapping.Chat) string { +func (r *Router) routeGroupRequest(update tgbotapi.Update, playerRaw *dbmapping.Player, chatRaw *dbmapping.Chat) string { text := update.Message.Text // Regular expressions var durakMsg = regexp.MustCompile("(Д|д)(У|у)(Р|р)(А|а|Е|е|О|о)") @@ -19,7 +20,7 @@ func (r *Router) routeGroupRequest(update *tgbotapi.Update, playerRaw *dbmapping var ebMsg = regexp.MustCompile("(\\s|^|ЗА|За|зА|за)(Е|е|Ё|ё)(Б|б)(\\s|Л|л|А|а|Т|т|У|у|Е|е|Ё|ё|И|и)") var piMsg = regexp.MustCompile("(П|п)(И|и)(З|з)(Д|д)") - restrictionStatus := c.Chatter.ProtectChat(update, playerRaw, chatRaw) + restrictionStatus := c.Chatter.ProtectChat(&update, playerRaw, chatRaw) if restrictionStatus != "protection_passed" { return restrictionStatus } @@ -28,7 +29,7 @@ func (r *Router) routeGroupRequest(update *tgbotapi.Update, playerRaw *dbmapping if update.Message.NewChatMembers != nil { newUsers := *update.Message.NewChatMembers if len(newUsers) > 0 { - return c.Welcomer.GroupWelcomeMessage(update) + return c.Welcomer.GroupWelcomeMessage(&update) } } // New chat names @@ -47,21 +48,21 @@ func (r *Router) routeGroupRequest(update *tgbotapi.Update, playerRaw *dbmapping if trigger == 4 { switch { case huMsg.MatchString(text): - return c.Talkers.MatMessage(update) + return c.Talkers.MatMessage(&update) case blMsg.MatchString(text): - return c.Talkers.MatMessage(update) + return c.Talkers.MatMessage(&update) case ebMsg.MatchString(text): - return c.Talkers.MatMessage(update) + return c.Talkers.MatMessage(&update) case piMsg.MatchString(text): - return c.Talkers.MatMessage(update) + return c.Talkers.MatMessage(&update) case durakMsg.MatchString(text): - return c.Talkers.DurakMessage(update) + return c.Talkers.DurakMessage(&update) } } switch { case update.Message.Command() == "long": - return c.Talkers.LongMessage(update) + return c.Talkers.LongMessage(&update) } // Ah, we're still here diff --git a/lib/router/inline.go b/lib/router/inline.go index fffc722..8cd13fb 100644 --- a/lib/router/inline.go +++ b/lib/router/inline.go @@ -4,13 +4,14 @@ package router import ( - "github.com/go-telegram-bot-api/telegram-bot-api" "strconv" "strings" + + "github.com/go-telegram-bot-api/telegram-bot-api" ) // RouteInline routes inline requests to bot -func (r *Router) RouteInline(update *tgbotapi.Update) string { +func (r *Router) RouteInline(update tgbotapi.Update) string { playerRaw, err := c.DataCache.GetOrCreatePlayerByTelegramID(update.InlineQuery.From.ID) if err != nil { c.Log.Error(err.Error()) diff --git a/lib/router/private_request.go b/lib/router/private_request.go index c530504..c706feb 100644 --- a/lib/router/private_request.go +++ b/lib/router/private_request.go @@ -4,12 +4,13 @@ package router import ( - "github.com/go-telegram-bot-api/telegram-bot-api" "regexp" + + "github.com/go-telegram-bot-api/telegram-bot-api" "source.wtfteam.pro/i2_bot/i2_bot/lib/dbmapping" ) -func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmapping.Player, chatRaw *dbmapping.Chat) string { +func (r *Router) routePrivateRequest(update tgbotapi.Update, playerRaw *dbmapping.Player, chatRaw *dbmapping.Chat) string { text := update.Message.Text // Commands with regexps @@ -21,7 +22,7 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi var orderSendMsg = regexp.MustCompile("/send_order(\\d+)\\z") if playerRaw.Status == "banned" { - return c.Talkers.BanError(update) + return c.Talkers.BanError(&update) } if update.Message.ForwardFrom != nil { @@ -30,9 +31,9 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi } else { c.Log.Info("Forward from PokememBro bot! Processing...") if playerRaw.ID != 0 { - c.Forwarder.ProcessForward(update, playerRaw) + c.Forwarder.ProcessForward(&update, playerRaw) } else { - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) } } } else { @@ -41,181 +42,174 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi case update.Message.Command() == "start": if playerRaw.LeagueID != 0 { if playerRaw.Status == "special" { - c.Welcomer.PrivateWelcomeMessageSpecial(update, playerRaw) + c.Welcomer.PrivateWelcomeMessageSpecial(&update, playerRaw) return "ok" } - c.Welcomer.PrivateWelcomeMessageAuthorized(update, playerRaw) + c.Welcomer.PrivateWelcomeMessageAuthorized(&update, playerRaw) return "ok" } - c.Welcomer.PrivateWelcomeMessageUnauthorized(update) + c.Welcomer.PrivateWelcomeMessageUnauthorized(&update) return "ok" case update.Message.Command() == "help": - c.Talkers.HelpMessage(update, playerRaw) + c.Talkers.HelpMessage(&update, playerRaw) return "ok" case update.Message.Command() == "faq": - return c.Talkers.FAQMessage(update) + return c.Talkers.FAQMessage(&update) case update.Message.Command() == "academy": - c.Talkers.AcademyMessage(update, playerRaw) + c.Talkers.AcademyMessage(&update, playerRaw) return "ok" case update.Message.Command() == "bastion": - c.Talkers.BastionMessage(update, playerRaw) + c.Talkers.BastionMessage(&update, playerRaw) return "ok" case pokedexMsg.MatchString(text): - c.Pokedexer.PokememesList(update) + c.Pokedexer.PokememesList(&update) return "ok" case pokememeInfoMsg.MatchString(text): - c.Pokedexer.PokememeInfo(update, playerRaw) + c.Pokedexer.PokememeInfo(&update, playerRaw) return "ok" case update.Message.Command() == "delete_pokememe": if c.Users.PlayerBetterThan(playerRaw, "owner") { - return c.Pokedexer.DeletePokememe(update) + return c.Pokedexer.DeletePokememe(&update) } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "me": if playerRaw.ID != 0 { - c.Users.ProfileMessage(update, playerRaw) + c.Users.ProfileMessage(&update, playerRaw) return "ok" } case update.Message.Command() == "top": if playerRaw.ID != 0 { - return c.Statistics.TopList(update, playerRaw) + return c.Statistics.TopList(&update, playerRaw) } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "top_my": if playerRaw.ID != 0 { - return c.Statistics.TopList(update, playerRaw) + return c.Statistics.TopList(&update, playerRaw) } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "best": - c.Pokedexer.AdvicePokememesList(update, playerRaw) + c.Pokedexer.AdvicePokememesList(&update, playerRaw) return "ok" case update.Message.Command() == "advice": - c.Pokedexer.AdvicePokememesList(update, playerRaw) + c.Pokedexer.AdvicePokememesList(&update, playerRaw) return "ok" case update.Message.Command() == "best_all": - c.Pokedexer.AdvicePokememesList(update, playerRaw) + c.Pokedexer.AdvicePokememesList(&update, playerRaw) return "ok" case update.Message.Command() == "advice_all": - c.Pokedexer.AdvicePokememesList(update, playerRaw) + c.Pokedexer.AdvicePokememesList(&update, playerRaw) return "ok" case update.Message.Command() == "best_nofilter": - c.Pokedexer.AdvicePokememesList(update, playerRaw) + c.Pokedexer.AdvicePokememesList(&update, playerRaw) return "ok" case update.Message.Command() == "reminders": - return c.Reminder.AlarmsList(update, playerRaw) + return c.Reminder.AlarmsList(&update, playerRaw) case update.Message.Command() == "send_all": if c.Users.PlayerBetterThan(playerRaw, "admin") { - c.Broadcaster.AdminBroadcastMessageCompose(update, playerRaw) + c.Broadcaster.AdminBroadcastMessageCompose(&update, playerRaw) return "ok" } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "send_league": if c.Users.PlayerBetterThan(playerRaw, "admin") { - c.Broadcaster.AdminBroadcastMessageCompose(update, playerRaw) + c.Broadcaster.AdminBroadcastMessageCompose(&update, playerRaw) return "ok" } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "send_confirm": if c.Users.PlayerBetterThan(playerRaw, "admin") { - go c.Broadcaster.AdminBroadcastMessageSend(update, playerRaw) + go c.Broadcaster.AdminBroadcastMessageSend(&update, playerRaw) return "ok" } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "chats": if c.Users.PlayerBetterThan(playerRaw, "admin") { - c.Chatter.GroupsList(update) + c.Chatter.GroupsList(&update) return "ok" } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "squads": - return c.Squader.SquadsList(update, playerRaw) + return c.Squader.SquadsList(&update, playerRaw) case update.Message.Command() == "pin": if c.Users.PlayerBetterThan(playerRaw, "admin") { - return c.Pinner.PinMessageToSomeChats(update) + return c.Pinner.PinMessageToSomeChats(&update) } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "pin_all": if c.Users.PlayerBetterThan(playerRaw, "admin") { - return c.Pinner.PinMessageToAllChats(update) + return c.Pinner.PinMessageToAllChats(&update) } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "orders": if c.Users.PlayerBetterThan(playerRaw, "admin") { - return c.Orders.ListAllOrders(update) + return c.Orders.ListAllOrders(&update) } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case orderSendMsg.MatchString(text): if c.Users.PlayerBetterThan(playerRaw, "admin") { - return c.Orders.SendOrder(update) + return c.Orders.SendOrder(&update) } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case usersMsg.MatchString(text): if c.Users.PlayerBetterThan(playerRaw, "academic") { - return c.Users.UsersList(update) + return c.Users.UsersList(&update) } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case profileMsg.MatchString(text): if c.Users.PlayerBetterThan(playerRaw, "academic") { - return c.Users.ForeignProfileMessage(update) + return c.Users.ForeignProfileMessage(&update) } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "find_level": if c.Users.PlayerBetterThan(playerRaw, "academic") { - return c.Users.FindByLevel(update) + return c.Users.FindByLevel(&update) } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "find_user": if c.Users.PlayerBetterThan(playerRaw, "academic") { - return c.Users.FindByName(update) + return c.Users.FindByName(&update) } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "find_top_attack": if c.Users.PlayerBetterThan(playerRaw, "academic") { - return c.Users.FindByTopAttack(update) + return c.Users.FindByTopAttack(&update) } - return c.Talkers.AnyMessageUnauthorized(update) + return c.Talkers.AnyMessageUnauthorized(&update) case update.Message.Command() == "squad_add_user": - return c.Squader.AddUserToSquad(update, playerRaw) + return c.Squader.AddUserToSquad(&update, playerRaw) case update.Message.Command() == "squad_add_commander": - return c.Squader.AddUserToSquad(update, playerRaw) + return c.Squader.AddUserToSquad(&update, playerRaw) case squadInfoMsg.MatchString(text): - return c.Squader.SquadInfo(update, playerRaw) - - case update.Message.Command() == "five_offer": - if c.Users.PlayerBetterThan(playerRaw, "admin") { - return c.Talkers.FiveOffer(update) - } - - return c.Talkers.AnyMessageUnauthorized(update) + return c.Squader.SquadInfo(&update, playerRaw) } } } diff --git a/lib/router/router.go b/lib/router/router.go index 2505ba9..c352180 100644 --- a/lib/router/router.go +++ b/lib/router/router.go @@ -1,5 +1,5 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package router @@ -8,7 +8,7 @@ import ( ) // RouteRequest decides, what to do with user input -func (r *Router) RouteRequest(update *tgbotapi.Update) string { +func (r *Router) RouteRequest(update tgbotapi.Update) string { c.Log.Debugln(update) playerRaw, err := c.DataCache.GetOrCreatePlayerByTelegramID(update.Message.From.ID) if err != nil { @@ -18,7 +18,7 @@ func (r *Router) RouteRequest(update *tgbotapi.Update) string { } c.Log.Debug("Getting chat...") - chatRaw, err := c.DataCache.GetOrCreateChat(update) + chatRaw, err := c.DataCache.GetOrCreateChat(&update) if err != nil { c.Log.Error(err.Error()) return "fail" diff --git a/lib/router/routerinterface/routerinterface.go b/lib/router/routerinterface/routerinterface.go index 8d8da4b..0c5446c 100644 --- a/lib/router/routerinterface/routerinterface.go +++ b/lib/router/routerinterface/routerinterface.go @@ -1,5 +1,5 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package routerinterface @@ -11,7 +11,7 @@ import ( type RouterInterface interface { Init() - RouteCallback(update *tgbotapi.Update) string - RouteInline(update *tgbotapi.Update) string - RouteRequest(update *tgbotapi.Update) string + RouteCallback(update tgbotapi.Update) string + RouteInline(update tgbotapi.Update) string + RouteRequest(update tgbotapi.Update) string } diff --git a/lib/sender/exported.go b/lib/sender/exported.go new file mode 100644 index 0000000..fa7bc50 --- /dev/null +++ b/lib/sender/exported.go @@ -0,0 +1,28 @@ +// i2_bot – Instinct PokememBro Bot +// Copyright (c) 2018 Vladimir "fat0troll" Hodakov + +package sender + +import ( + "source.wtfteam.pro/i2_bot/i2_bot/lib/appcontext" + "source.wtfteam.pro/i2_bot/i2_bot/lib/sender/senderinterface" +) + +var ( + c *appcontext.Context +) + +// Sender is a function-handling struct for sender +type Sender struct{} + +// New is a appcontext initialization function +func New(ac *appcontext.Context) { + c = ac + s := &Sender{} + c.RegisterSenderInterface(senderinterface.SenderInterface(s)) +} + +// Init is an initialization function for sender +func (s *Sender) Init() { + c.Log.Info("Initializing Sender...") +} diff --git a/lib/sender/sender.go b/lib/sender/sender.go new file mode 100644 index 0000000..03dc583 --- /dev/null +++ b/lib/sender/sender.go @@ -0,0 +1,30 @@ +// i2_bot – Instinct PokememBro Bot +// Copyright (c) 2018 Vladimir "fat0troll" Hodakov + +package sender + +import ( + "github.com/go-telegram-bot-api/telegram-bot-api" +) + +// SendMarkdownAnswer sends markdown-powered message as reply +func (s *Sender) SendMarkdownAnswer(update *tgbotapi.Update, message string) { + msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) + msg.ParseMode = "Markdown" + + _, err := c.Bot.Send(msg) + if err != nil { + c.Log.Error(err.Error()) + } +} + +// SendMarkdownMessageToChatID sends markdown-powered message to specified chat +func (s *Sender) SendMarkdownMessageToChatID(chatID int64, message string) { + msg := tgbotapi.NewMessage(chatID, message) + msg.ParseMode = "Markdown" + + _, err := c.Bot.Send(msg) + if err != nil { + c.Log.Error(err.Error()) + } +} diff --git a/lib/sender/senderinterface/senderinterface.go b/lib/sender/senderinterface/senderinterface.go new file mode 100644 index 0000000..4e3348c --- /dev/null +++ b/lib/sender/senderinterface/senderinterface.go @@ -0,0 +1,16 @@ +// i2_bot – Instinct PokememBro Bot +// Copyright (c) 2018 Vladimir "fat0troll" Hodakov + +package senderinterface + +import ( + "github.com/go-telegram-bot-api/telegram-bot-api" +) + +// SenderInterface implements Sender for importing via appcontext +type SenderInterface interface { + Init() + + SendMarkdownAnswer(update *tgbotapi.Update, message string) + SendMarkdownMessageToChatID(chatID int64, message string) +} diff --git a/lib/talkers/easter.go b/lib/talkers/easter.go index 02afdef..82db7ca 100644 --- a/lib/talkers/easter.go +++ b/lib/talkers/easter.go @@ -1,13 +1,14 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package talkers import ( - "github.com/go-telegram-bot-api/telegram-bot-api" "math/rand" "strconv" "time" + + "github.com/go-telegram-bot-api/telegram-bot-api" ) // LongMessage is an easter egg @@ -20,10 +21,7 @@ func (t *Talkers) LongMessage(update *tgbotapi.Update) string { } } - msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) - msg.ReplyToMessageID = update.Message.MessageID - - c.Bot.Send(msg) + c.Sender.SendMarkdownAnswer(update, message) return "ok" } @@ -42,6 +40,7 @@ func (t *Talkers) DurakMessage(update *tgbotapi.Update) string { if update.Message.From.ID == 324205150 { message = "Молодец, Яру. Возьми с полки пирожок." } + msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) msg.ReplyToMessageID = update.Message.MessageID diff --git a/lib/talkers/errors.go b/lib/talkers/errors.go index d1f2066..ad07712 100644 --- a/lib/talkers/errors.go +++ b/lib/talkers/errors.go @@ -12,10 +12,7 @@ func (t *Talkers) AnyMessageUnauthorized(update *tgbotapi.Update) string { message := "Извини, действие для тебя недоступно. Возможно, у меня нет твоего профиля или же твои права недостаточны для совершения данного действия\n\n" message += "Техническая поддержка бота: https://t.me/joinchat/AAkt5EgFBU9Q9iXJMvDG6A.\n" - msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) - msg.ParseMode = "Markdown" - - c.Bot.Send(msg) + c.Sender.SendMarkdownAnswer(update, message) return "fail" } @@ -24,10 +21,7 @@ func (t *Talkers) AnyMessageUnauthorized(update *tgbotapi.Update) string { func (t *Talkers) BanError(update *tgbotapi.Update) string { message := "Вам здесь не рады. Использование бота для вас запрещено." - msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) - msg.ParseMode = "Markdown" - - c.Bot.Send(msg) + c.Sender.SendMarkdownAnswer(update, message) return "fail" } @@ -37,10 +31,7 @@ func (t *Talkers) BotError(update *tgbotapi.Update) string { message := "Ой, внутренняя ошибка в боте :(\n\n" message += "Техническая поддержка бота: https://t.me/joinchat/AAkt5EgFBU9Q9iXJMvDG6A. Напиши сюда, приложив скриншоты с перепиской бота.\n" - msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) - msg.ParseMode = "Markdown" - - c.Bot.Send(msg) + c.Sender.SendMarkdownAnswer(update, message) return "fail" } diff --git a/lib/talkers/help.go b/lib/talkers/help.go index e50f0bc..8608d41 100644 --- a/lib/talkers/help.go +++ b/lib/talkers/help.go @@ -1,13 +1,14 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package talkers import ( + "time" + "github.com/go-telegram-bot-api/telegram-bot-api" "source.wtfteam.pro/i2_bot/i2_bot/lib/config" "source.wtfteam.pro/i2_bot/i2_bot/lib/dbmapping" - "time" ) // AcademyMessage gives user link to Bastion @@ -42,10 +43,7 @@ func (t *Talkers) BastionMessage(update *tgbotapi.Update, playerRaw *dbmapping.P message += "Общий чат лиги расположен по ссылке: https://t.me/joinchat/G2vME0mIX-QHjjxE\\_JBzoQ" } - msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) - msg.ParseMode = "Markdown" - - c.Bot.Send(msg) + c.Sender.SendMarkdownAnswer(update, message) } // HelpMessage gives user all available commands @@ -96,10 +94,7 @@ func (t *Talkers) HelpMessage(update *tgbotapi.Update, playerRaw *dbmapping.Play message += "Выразить благодарность и попасть в список: 4377 7300 0246 7362\n" message += "_Топ ранжируется по размеру благодарности. Здесь может быть ваша реклама!_" - msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) - msg.ParseMode = "Markdown" - - c.Bot.Send(msg) + c.Sender.SendMarkdownAnswer(update, message) } // FAQMessage prints frequently asked questions @@ -142,39 +137,7 @@ func (t *Talkers) FAQMessage(update *tgbotapi.Update) string { message += "_Если не открывать 🥚яйцо, когда оно наберется до нужного количества, оно не будет дальше расти?_\n" message += "Не будет." - msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) - msg.ParseMode = "Markdown" - - c.Bot.Send(msg) - - return "ok" -} - -// FiveOffer sends all users with 5 pokeballs limit offer for increasing pokeballs limit -func (t *Talkers) FiveOffer(update *tgbotapi.Update) string { - players := []dbmapping.Player{} - - err := c.Db.Select(&players, "SELECT p.* FROM players p, profiles pp WHERE p.id = pp.player_id AND pp.pokeballs = 5") - if err != nil { - c.Log.Error(err.Error()) - return "fail" - } - - for i := range players { - message := "Псст, я тут заметил, что у тебя всего 5 покеболов? Хочешь увеличить их лимит на 2 или даже больше? У всех игроков есть возможность получить бонус!\n\n1. Перейти по ссылке: https://telegram.me/storebot?start=pokemembrobot\n2. Нажать Start\n3. Выбрать ⭐️⭐️⭐️⭐️⭐️\n4. ОБЯЗАТЕЛЬНО написать, что вам нравится в игре (на русском языке). Оставьте большой и красочный отзыв!\n5. Переслать переписку с @storebot в тех поддержку игры @PBhelp<— только ему! и больше никому! (с текстом вашего отзыва)\n6. После проверки получить бонус 🎁 +2 к лимиту ⭕️ А если отзыв понравится админам (и это бывает очень часто), то бонус будет больше!\n7. Проверка - может занять некоторое время. Админы обязательно ответят вам о результатах проверки." - - msg := tgbotapi.NewMessage(int64(players[i].TelegramID), message) - msg.ParseMode = "Markdown" - - c.Bot.Send(msg) - } - - message := "Enlarge your pokeballs! Сообщение отправлено." - - msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) - msg.ParseMode = "Markdown" - - c.Bot.Send(msg) + c.Sender.SendMarkdownAnswer(update, message) return "ok" } diff --git a/lib/talkers/talkersinterface/talkersinterface.go b/lib/talkers/talkersinterface/talkersinterface.go index 0b8730b..ce88f7e 100644 --- a/lib/talkers/talkersinterface/talkersinterface.go +++ b/lib/talkers/talkersinterface/talkersinterface.go @@ -1,5 +1,5 @@ // i2_bot – Instinct PokememBro Bot -// Copyright (c) 2017 Vladimir "fat0troll" Hodakov +// Copyright (c) 2017-2018 Vladimir "fat0troll" Hodakov package talkersinterface @@ -16,7 +16,6 @@ type TalkersInterface interface { BastionMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) HelpMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) FAQMessage(update *tgbotapi.Update) string - FiveOffer(update *tgbotapi.Update) string AnyMessageUnauthorized(update *tgbotapi.Update) string BanError(update *tgbotapi.Update) string