parent
8368a3c60b
commit
53a99b0ff3
@ -10,6 +10,7 @@ import (
|
|||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/chatter"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/chatter"
|
||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/forwarder"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/forwarder"
|
||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/migrations"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/migrations"
|
||||||
|
"lab.pztrn.name/fat0troll/i2_bot/lib/orders"
|
||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/pinner"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/pinner"
|
||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/pokedexer"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/pokedexer"
|
||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/router"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/router"
|
||||||
@ -42,6 +43,7 @@ func main() {
|
|||||||
squader.New(c)
|
squader.New(c)
|
||||||
users.New(c)
|
users.New(c)
|
||||||
statistics.New(c)
|
statistics.New(c)
|
||||||
|
orders.New(c)
|
||||||
|
|
||||||
c.Log.Info("=======================")
|
c.Log.Info("=======================")
|
||||||
c.Log.Info("= i2_bot initialized. =")
|
c.Log.Info("= i2_bot initialized. =")
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/connections"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/connections"
|
||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/forwarder/forwarderinterface"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/forwarder/forwarderinterface"
|
||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/migrations/migrationsinterface"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/migrations/migrationsinterface"
|
||||||
|
"lab.pztrn.name/fat0troll/i2_bot/lib/orders/ordersinterface"
|
||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/pinner/pinnerinterface"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/pinner/pinnerinterface"
|
||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/pokedexer/pokedexerinterface"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/pokedexer/pokedexerinterface"
|
||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/router/routerinterface"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/router/routerinterface"
|
||||||
@ -46,6 +47,7 @@ type Context struct {
|
|||||||
Squader squaderinterface.SquaderInterface
|
Squader squaderinterface.SquaderInterface
|
||||||
Users usersinterface.UsersInterface
|
Users usersinterface.UsersInterface
|
||||||
Statistics statisticsinterface.StatisticsInterface
|
Statistics statisticsinterface.StatisticsInterface
|
||||||
|
Orders ordersinterface.OrdersInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init is a initialization function for context
|
// Init is a initialization function for context
|
||||||
@ -153,6 +155,12 @@ func (c *Context) RegisterSquaderInterface(si squaderinterface.SquaderInterface)
|
|||||||
c.Squader.Init()
|
c.Squader.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegisterOrdersInterface registers orders interface in application
|
||||||
|
func (c *Context) RegisterOrdersInterface(oi ordersinterface.OrdersInterface) {
|
||||||
|
c.Orders = oi
|
||||||
|
c.Orders.Init()
|
||||||
|
}
|
||||||
|
|
||||||
// RegisterUsersInterface registers users interface in application
|
// RegisterUsersInterface registers users interface in application
|
||||||
func (c *Context) RegisterUsersInterface(ui usersinterface.UsersInterface) {
|
func (c *Context) RegisterUsersInterface(ui usersinterface.UsersInterface) {
|
||||||
c.Users = ui
|
c.Users = ui
|
||||||
|
21
lib/dbmapping/orders.go
Normal file
21
lib/dbmapping/orders.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// i2_bot – Instinct PokememBro Bot
|
||||||
|
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||||
|
|
||||||
|
package dbmapping
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-sql-driver/mysql"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Order is a struct, which represents `orders` table item in databse.
|
||||||
|
type Order struct {
|
||||||
|
ID int `db:"id"`
|
||||||
|
Target string `db:"target"`
|
||||||
|
TargetSquads string `db:"target_squads"`
|
||||||
|
Scheduled bool `db:"scheduled"`
|
||||||
|
ScheduledAt mysql.NullTime `db:"scheduled_at"`
|
||||||
|
Status string `db:"status"`
|
||||||
|
AuthorID int `db:"author_id"`
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
}
|
51
lib/migrations/24_create_orders.go
Normal file
51
lib/migrations/24_create_orders.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// i2_bot – Instinct PokememBro Bot
|
||||||
|
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||||
|
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateOrdersUp creates `orders` table
|
||||||
|
func CreateOrdersUp(tx *sql.Tx) error {
|
||||||
|
request := "CREATE TABLE `orders` ("
|
||||||
|
request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID приказа',"
|
||||||
|
request += "`target` varchar(191) NOT NULL COMMENT 'Цель приказа',"
|
||||||
|
request += "`target_squads` varchar(191) NOT NULL COMMENT 'Отряды, для которых этот приказ действителен',"
|
||||||
|
request += "`scheduled` bool NOT NULL DEFAULT false COMMENT 'Является ли запланированным',"
|
||||||
|
request += "`scheduled_at` datetime COMMENT 'Время запланированного пина',"
|
||||||
|
request += "`reusable` bool NOT NULL DEFAULT true COMMENT 'Можно ли повторить приказ',"
|
||||||
|
request += "`status` varchar(191) NOT NULL DEFAULT 'new' COMMENT 'Статус приказа',"
|
||||||
|
request += "`author_id` int(11) NOT NULL COMMENT 'ID автора приказа',"
|
||||||
|
request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу',"
|
||||||
|
request += "PRIMARY KEY (`id`),"
|
||||||
|
request += "UNIQUE KEY `id` (`id`),"
|
||||||
|
request += "KEY `orders_created_at` (`created_at`)"
|
||||||
|
request += ") ENGINE=InnoDB AUTO_INCREMENT=4201 DEFAULT CHARSET=utf8mb4 COMMENT='Приказы'"
|
||||||
|
_, err := tx.Exec(request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill some default templates to send
|
||||||
|
_, err = tx.Exec("INSERT INTO `orders` VALUES(NULL, 'M', 'all', false, NULL, true, 'new', 1, NOW())")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = tx.Exec("INSERT INTO `orders` VALUES(NULL, 'O', 'all', false, NULL, true, 'new', 1, NOW())")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOrdersDown drops `chats` table
|
||||||
|
func CreateOrdersDown(tx *sql.Tx) error {
|
||||||
|
_, err := tx.Exec("DROP TABLE `orders`")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
29
lib/migrations/25_remove_reusable.go
Normal file
29
lib/migrations/25_remove_reusable.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// i2_bot – Instinct PokememBro Bot
|
||||||
|
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||||
|
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
// stdlib
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RemoveReusableUp removes `reusable` field in `orders` table
|
||||||
|
func RemoveReusableUp(tx *sql.Tx) error {
|
||||||
|
_, err := tx.Exec("ALTER TABLE `orders` DROP COLUMN `reusable`")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveReusableDown reverts `reusable` column
|
||||||
|
func RemoveReusableDown(tx *sql.Tx) error {
|
||||||
|
_, err := tx.Exec("ALTER TABLE `orders` ADD COLUMN `reusable` bool NOT NULL DEFAULT true COMMENT 'Можно ли повторить приказ' AFTER `scheduled_at")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -34,6 +34,8 @@ func (m *Migrations) Init() {
|
|||||||
goose.AddNamedMigration("21_change_telegram_id_column.go", ChangeTelegramIDColumnUp, ChangeTelegramIDColumnDown)
|
goose.AddNamedMigration("21_change_telegram_id_column.go", ChangeTelegramIDColumnUp, ChangeTelegramIDColumnDown)
|
||||||
goose.AddNamedMigration("22_add_flood_chat_id.go", AddFloodChatIDUp, AddFloodChatIDDown)
|
goose.AddNamedMigration("22_add_flood_chat_id.go", AddFloodChatIDUp, AddFloodChatIDDown)
|
||||||
goose.AddNamedMigration("23_add_user_type.go", AddUserTypeUp, AddUserTypeDown)
|
goose.AddNamedMigration("23_add_user_type.go", AddUserTypeUp, AddUserTypeDown)
|
||||||
|
goose.AddNamedMigration("24_create_orders.go", CreateOrdersUp, CreateOrdersDown)
|
||||||
|
goose.AddNamedMigration("25_remove_reusable.go", RemoveReusableUp, RemoveReusableDown)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate migrates database to current version
|
// Migrate migrates database to current version
|
||||||
|
28
lib/orders/exported.go
Normal file
28
lib/orders/exported.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// i2_bot – Instinct PokememBro Bot
|
||||||
|
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||||
|
|
||||||
|
package orders
|
||||||
|
|
||||||
|
import (
|
||||||
|
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
|
||||||
|
"lab.pztrn.name/fat0troll/i2_bot/lib/orders/ordersinterface"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
c *appcontext.Context
|
||||||
|
)
|
||||||
|
|
||||||
|
// Orders is a function-handling struct for package orders.
|
||||||
|
type Orders struct{}
|
||||||
|
|
||||||
|
// New is an initialization function for appcontext
|
||||||
|
func New(ac *appcontext.Context) {
|
||||||
|
c = ac
|
||||||
|
o := &Orders{}
|
||||||
|
c.RegisterOrdersInterface(ordersinterface.OrdersInterface(o))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init is a initialization function for package
|
||||||
|
func (o *Orders) Init() {
|
||||||
|
c.Log.Info("Initializing Orders...")
|
||||||
|
}
|
34
lib/orders/getters.go
Normal file
34
lib/orders/getters.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// i2_bot – Instinct PokememBro Bot
|
||||||
|
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||||
|
|
||||||
|
package orders
|
||||||
|
|
||||||
|
import (
|
||||||
|
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetAllOrders returns all orders in database
|
||||||
|
func (o *Orders) GetAllOrders() ([]dbmapping.Order, bool) {
|
||||||
|
orders := []dbmapping.Order{}
|
||||||
|
|
||||||
|
err := c.Db.Select(&orders, "SELECT * FROM orders ORDER BY created_at asc")
|
||||||
|
if err != nil {
|
||||||
|
c.Log.Error(err)
|
||||||
|
return orders, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return orders, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOrderByID returns single order by ID
|
||||||
|
func (o *Orders) GetOrderByID(orderID int) (dbmapping.Order, bool) {
|
||||||
|
order := dbmapping.Order{}
|
||||||
|
|
||||||
|
err := c.Db.Get(&order, c.Db.Rebind("SELECT * FROM orders WHERE id=?"), orderID)
|
||||||
|
if err != nil {
|
||||||
|
c.Log.Error(err.Error())
|
||||||
|
return order, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return order, true
|
||||||
|
}
|
94
lib/orders/orders.go
Normal file
94
lib/orders/orders.go
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// i2_bot – Instinct PokememBro Bot
|
||||||
|
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||||
|
|
||||||
|
package orders
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||||
|
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Internal functions
|
||||||
|
|
||||||
|
func (o *Orders) getOrderByID(orderID int) (dbmapping.Order, bool) {
|
||||||
|
order := dbmapping.Order{}
|
||||||
|
|
||||||
|
err := c.Db.Get(&order, c.Db.Rebind("SELECT * FROM orders WHERE id=?"), orderID)
|
||||||
|
if err != nil {
|
||||||
|
c.Log.Error(err.Error())
|
||||||
|
return order, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return order, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Orders) sendOrder(order *dbmapping.Order) string {
|
||||||
|
targetChats := []dbmapping.Chat{}
|
||||||
|
ok := false
|
||||||
|
|
||||||
|
if order.TargetSquads == "all" {
|
||||||
|
targetChats, ok = c.Squader.GetAllSquadChats()
|
||||||
|
if !ok {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
targetChats, ok = c.Squader.GetSquadChatsBySquadsIDs(order.TargetSquads)
|
||||||
|
if !ok {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range targetChats {
|
||||||
|
message := "Поступил приказ:"
|
||||||
|
|
||||||
|
msg := tgbotapi.NewMessage(targetChats[i].TelegramID, message)
|
||||||
|
keyboard := tgbotapi.InlineKeyboardMarkup{}
|
||||||
|
var row []tgbotapi.InlineKeyboardButton
|
||||||
|
btn := tgbotapi.NewInlineKeyboardButtonSwitch("В атаку!", strconv.Itoa(order.ID))
|
||||||
|
row = append(row, btn)
|
||||||
|
keyboard.InlineKeyboard = append(keyboard.InlineKeyboard, row)
|
||||||
|
|
||||||
|
msg.ReplyMarkup = keyboard
|
||||||
|
msg.ParseMode = "Markdown"
|
||||||
|
|
||||||
|
pinnableMessage, err := c.Bot.Send(msg)
|
||||||
|
if err != nil {
|
||||||
|
c.Log.Error(err.Error())
|
||||||
|
} else {
|
||||||
|
pinChatMessageConfig := tgbotapi.PinChatMessageConfig{
|
||||||
|
ChatID: pinnableMessage.Chat.ID,
|
||||||
|
MessageID: pinnableMessage.MessageID,
|
||||||
|
DisableNotification: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.Bot.PinChatMessage(pinChatMessageConfig)
|
||||||
|
if err != nil {
|
||||||
|
c.Log.Error(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "ok"
|
||||||
|
}
|
||||||
|
|
||||||
|
// External functions
|
||||||
|
|
||||||
|
// SendOrder sends order to selected or all squads
|
||||||
|
func (o *Orders) SendOrder(update *tgbotapi.Update) string {
|
||||||
|
command := update.Message.Command()
|
||||||
|
orderNumber := strings.TrimPrefix(command, "send_order")
|
||||||
|
orderID, _ := strconv.Atoi(orderNumber)
|
||||||
|
|
||||||
|
if orderID == 0 {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
|
||||||
|
order, ok := o.getOrderByID(orderID)
|
||||||
|
if !ok {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.sendOrder(&order)
|
||||||
|
}
|
21
lib/orders/ordersinterface/ordersinterface.go
Normal file
21
lib/orders/ordersinterface/ordersinterface.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// i2_bot – Instinct PokememBro Bot
|
||||||
|
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||||
|
|
||||||
|
package ordersinterface
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||||
|
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OrdersInterface implements Orders for importing via appcontext.
|
||||||
|
type OrdersInterface interface {
|
||||||
|
Init()
|
||||||
|
|
||||||
|
GetAllOrders() ([]dbmapping.Order, bool)
|
||||||
|
GetOrderByID(orderID int) (dbmapping.Order, bool)
|
||||||
|
|
||||||
|
ListAllOrders(update *tgbotapi.Update) string
|
||||||
|
|
||||||
|
SendOrder(update *tgbotapi.Update) string
|
||||||
|
}
|
44
lib/orders/responders.go
Normal file
44
lib/orders/responders.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// i2_bot – Instinct PokememBro Bot
|
||||||
|
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||||
|
|
||||||
|
package orders
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListAllOrders returns to user all orders in database
|
||||||
|
func (o *Orders) ListAllOrders(update *tgbotapi.Update) string {
|
||||||
|
orders, ok := o.GetAllOrders()
|
||||||
|
if !ok {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
|
||||||
|
message := "*Приказы на атаку*\n"
|
||||||
|
for i := range orders {
|
||||||
|
message += "\\[" + strconv.Itoa(orders[i].ID) + "] " + orders[i].TargetSquads + " → "
|
||||||
|
if orders[i].Target == "M" {
|
||||||
|
message += "🈳 МИСТИКА "
|
||||||
|
} else {
|
||||||
|
message += "🈵 ОТВАГА "
|
||||||
|
}
|
||||||
|
if orders[i].Scheduled {
|
||||||
|
message += "запланировано на "
|
||||||
|
message += orders[i].ScheduledAt.Time.Format("02.01.2006 15:04:05")
|
||||||
|
}
|
||||||
|
if orders[i].Status == "sent" {
|
||||||
|
message += "\nПросмотреть выполнение приказа: /show\\_order" + strconv.Itoa(orders[i].ID)
|
||||||
|
} else {
|
||||||
|
message += "\nОтправить приказ прямо сейчас: /send\\_order" + strconv.Itoa(orders[i].ID)
|
||||||
|
}
|
||||||
|
message += "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||||
|
msg.ParseMode = "Markdown"
|
||||||
|
|
||||||
|
c.Bot.Send(msg)
|
||||||
|
|
||||||
|
return "ok"
|
||||||
|
}
|
@ -5,18 +5,51 @@ package router
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RouteInline routes inline requests to bot
|
// RouteInline routes inline requests to bot
|
||||||
func (r *Router) RouteInline(update *tgbotapi.Update) string {
|
func (r *Router) RouteInline(update *tgbotapi.Update) string {
|
||||||
|
playerRaw, ok := c.Users.GetOrCreatePlayer(update.InlineQuery.From.ID)
|
||||||
|
if !ok {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
|
||||||
|
results := make([]interface{}, 0)
|
||||||
|
|
||||||
|
if playerRaw.LeagueID != 1 {
|
||||||
|
article := tgbotapi.NewInlineQueryResultArticle("0", "Команда боту @PokememBroBot:", "👤Герой")
|
||||||
|
article.Description = "👤Герой"
|
||||||
|
|
||||||
|
results = append(results, article)
|
||||||
|
} else {
|
||||||
|
orderNumber, _ := strconv.Atoi(update.InlineQuery.Query)
|
||||||
|
if orderNumber != 0 {
|
||||||
|
order, ok := c.Orders.GetOrderByID(orderNumber)
|
||||||
|
if !ok {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
|
||||||
|
attackTarget := ""
|
||||||
|
if order.Target == "M" {
|
||||||
|
attackTarget = "⚔ 🈳 МИСТИКА"
|
||||||
|
} else {
|
||||||
|
attackTarget = "⚔ 🈵 ОТВАГА"
|
||||||
|
}
|
||||||
|
|
||||||
|
article := tgbotapi.NewInlineQueryResultArticle(strconv.Itoa(orderNumber), "Выполнить приказ отряда:", attackTarget)
|
||||||
|
article.Description = attackTarget
|
||||||
|
|
||||||
|
results = append(results, article)
|
||||||
|
} else {
|
||||||
availableCommands := make(map[string]string)
|
availableCommands := make(map[string]string)
|
||||||
availableCommands["0"] = "🌲Лес"
|
availableCommands["10"] = "🌲Лес"
|
||||||
availableCommands["1"] = "⛰Горы"
|
availableCommands["11"] = "⛰Горы"
|
||||||
availableCommands["2"] = "🚣Озеро"
|
availableCommands["12"] = "🚣Озеро"
|
||||||
availableCommands["3"] = "🏙Город"
|
availableCommands["13"] = "🏙Город"
|
||||||
availableCommands["4"] = "🏛Катакомбы"
|
availableCommands["14"] = "🏛Катакомбы"
|
||||||
availableCommands["5"] = "⛪️Кладбище"
|
availableCommands["15"] = "⛪️Кладбище"
|
||||||
outputCommands := make(map[string]string)
|
outputCommands := make(map[string]string)
|
||||||
for i, value := range availableCommands {
|
for i, value := range availableCommands {
|
||||||
if strings.Contains(value, update.InlineQuery.Query) {
|
if strings.Contains(value, update.InlineQuery.Query) {
|
||||||
@ -24,13 +57,14 @@ func (r *Router) RouteInline(update *tgbotapi.Update) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
results := make([]interface{}, 0)
|
|
||||||
for i, value := range outputCommands {
|
for i, value := range outputCommands {
|
||||||
article := tgbotapi.NewInlineQueryResultArticle(i, "Команда боту @PokememBroBot:", value)
|
article := tgbotapi.NewInlineQueryResultArticle(i, "Команда боту @PokememBroBot:", value)
|
||||||
article.Description = value
|
article.Description = value
|
||||||
|
|
||||||
results = append(results, article)
|
results = append(results, article)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inlineConf := tgbotapi.InlineConfig{
|
inlineConf := tgbotapi.InlineConfig{
|
||||||
InlineQueryID: update.InlineQuery.ID,
|
InlineQueryID: update.InlineQuery.ID,
|
||||||
@ -44,5 +78,5 @@ func (r *Router) RouteInline(update *tgbotapi.Update) string {
|
|||||||
c.Log.Error(err.Error())
|
c.Log.Error(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return "fail"
|
return "ok"
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi
|
|||||||
var pokememeInfoMsg = regexp.MustCompile("/pk(\\d+)")
|
var pokememeInfoMsg = regexp.MustCompile("/pk(\\d+)")
|
||||||
var usersMsg = regexp.MustCompile("/users\\d?\\z")
|
var usersMsg = regexp.MustCompile("/users\\d?\\z")
|
||||||
var squadInfoMsg = regexp.MustCompile("/show_squad(\\d+)\\z")
|
var squadInfoMsg = regexp.MustCompile("/show_squad(\\d+)\\z")
|
||||||
|
var orderSendMsg = regexp.MustCompile("/send_order(\\d+)\\z")
|
||||||
|
|
||||||
if update.Message.ForwardFrom != nil {
|
if update.Message.ForwardFrom != nil {
|
||||||
if update.Message.ForwardFrom.ID != 360402625 {
|
if update.Message.ForwardFrom.ID != 360402625 {
|
||||||
@ -34,6 +35,11 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi
|
|||||||
switch {
|
switch {
|
||||||
case update.Message.Command() == "start":
|
case update.Message.Command() == "start":
|
||||||
if playerRaw.LeagueID != 0 {
|
if playerRaw.LeagueID != 0 {
|
||||||
|
if playerRaw.Status == "special" {
|
||||||
|
c.Welcomer.PrivateWelcomeMessageSpecial(update, playerRaw)
|
||||||
|
return "ok"
|
||||||
|
}
|
||||||
|
|
||||||
c.Welcomer.PrivateWelcomeMessageAuthorized(update, playerRaw)
|
c.Welcomer.PrivateWelcomeMessageAuthorized(update, playerRaw)
|
||||||
return "ok"
|
return "ok"
|
||||||
}
|
}
|
||||||
@ -108,6 +114,19 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi
|
|||||||
|
|
||||||
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.Talkers.AnyMessageUnauthorized(update)
|
||||||
|
case orderSendMsg.MatchString(text):
|
||||||
|
if c.Users.PlayerBetterThan(playerRaw, "admin") {
|
||||||
|
return c.Orders.SendOrder(update)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Talkers.AnyMessageUnauthorized(update)
|
||||||
|
|
||||||
case usersMsg.MatchString(text):
|
case usersMsg.MatchString(text):
|
||||||
if c.Users.PlayerBetterThan(playerRaw, "admin") {
|
if c.Users.PlayerBetterThan(playerRaw, "admin") {
|
||||||
return c.Users.UsersList(update)
|
return c.Users.UsersList(update)
|
||||||
|
@ -5,6 +5,8 @@ package squader
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetSquadByID returns squad will all support information
|
// GetSquadByID returns squad will all support information
|
||||||
@ -77,6 +79,43 @@ func (s *Squader) GetAllSquadFloodChats() ([]dbmapping.Chat, bool) {
|
|||||||
return groupChats, true
|
return groupChats, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSquadChatsBySquadsIDs returns main squad chats for given squads IDs
|
||||||
|
func (s *Squader) GetSquadChatsBySquadsIDs(squadsIDs string) ([]dbmapping.Chat, bool) {
|
||||||
|
groupChats := []dbmapping.Chat{}
|
||||||
|
|
||||||
|
squadsIDsArray := strings.Split(squadsIDs, ",")
|
||||||
|
if len(squadsIDsArray) < 1 {
|
||||||
|
return groupChats, false
|
||||||
|
}
|
||||||
|
|
||||||
|
sIDs := make([]int, 0)
|
||||||
|
for i := range squadsIDsArray {
|
||||||
|
sID, _ := strconv.Atoi(squadsIDsArray[i])
|
||||||
|
if sID != 0 {
|
||||||
|
sIDs = append(sIDs, sID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(sIDs) < 1 {
|
||||||
|
return groupChats, false
|
||||||
|
}
|
||||||
|
|
||||||
|
queryLine := ""
|
||||||
|
for i := range sIDs {
|
||||||
|
queryLine += strconv.Itoa(sIDs[i])
|
||||||
|
if i < len(sIDs)-1 {
|
||||||
|
queryLine += ","
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err := c.Db.Select(&groupChats, "SELECT ch.* FROM chats ch, squads s WHERE s.chat_id=ch.id AND s.id IN ("+queryLine+")")
|
||||||
|
if err != nil {
|
||||||
|
c.Log.Error(err)
|
||||||
|
return groupChats, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return groupChats, true
|
||||||
|
}
|
||||||
|
|
||||||
// GetUserRolesInSquads lists all user roles
|
// GetUserRolesInSquads lists all user roles
|
||||||
func (s *Squader) GetUserRolesInSquads(playerRaw *dbmapping.Player) ([]dbmapping.SquadPlayerFull, bool) {
|
func (s *Squader) GetUserRolesInSquads(playerRaw *dbmapping.Player) ([]dbmapping.SquadPlayerFull, bool) {
|
||||||
userRoles := []dbmapping.SquadPlayerFull{}
|
userRoles := []dbmapping.SquadPlayerFull{}
|
||||||
|
@ -16,6 +16,7 @@ type SquaderInterface interface {
|
|||||||
GetAllSquadFloodChats() ([]dbmapping.Chat, bool)
|
GetAllSquadFloodChats() ([]dbmapping.Chat, bool)
|
||||||
GetAvailableSquadChatsForUser(playerRaw *dbmapping.Player) ([]dbmapping.Chat, bool)
|
GetAvailableSquadChatsForUser(playerRaw *dbmapping.Player) ([]dbmapping.Chat, bool)
|
||||||
GetSquadByID(squadID int) (dbmapping.SquadChat, bool)
|
GetSquadByID(squadID int) (dbmapping.SquadChat, bool)
|
||||||
|
GetSquadChatsBySquadsIDs(squadsID string) ([]dbmapping.Chat, bool)
|
||||||
GetUserRolesInSquads(playerRaw *dbmapping.Player) ([]dbmapping.SquadPlayerFull, bool)
|
GetUserRolesInSquads(playerRaw *dbmapping.Player) ([]dbmapping.SquadPlayerFull, bool)
|
||||||
IsChatASquadEnabled(chatRaw *dbmapping.Chat) string
|
IsChatASquadEnabled(chatRaw *dbmapping.Chat) string
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ func (t *Talkers) HelpMessage(update *tgbotapi.Update, playerRaw *dbmapping.Play
|
|||||||
message += "+ /squads — получить список отрядов.\n"
|
message += "+ /squads — получить список отрядов.\n"
|
||||||
message += "+ /pin _номера чатов_ _текст_ — отправить сообщение в чаты с номерами. Сообщение будет автоматичекси запинено. Пример: \"/pin 2,3,5 привет мир\". Внимание: между номерами чатов ставятся запятые без пробелов! Всё, что идёт после второго пробела в команде — сообщение\n"
|
message += "+ /pin _номера чатов_ _текст_ — отправить сообщение в чаты с номерами. Сообщение будет автоматичекси запинено. Пример: \"/pin 2,3,5 привет мир\". Внимание: между номерами чатов ставятся запятые без пробелов! Всё, что идёт после второго пробела в команде — сообщение\n"
|
||||||
message += "+ /pin\\_all _текст_ — отправить сообщение во все группы, где находится бот. Сообщение будет автоматически запинено.\n"
|
message += "+ /pin\\_all _текст_ — отправить сообщение во все группы, где находится бот. Сообщение будет автоматически запинено.\n"
|
||||||
|
message += "+ /orders — просмотреть приказы на атаку\n"
|
||||||
message += "+ /users — просмотреть зарегистрированных пользователей бота\n"
|
message += "+ /users — просмотреть зарегистрированных пользователей бота\n"
|
||||||
}
|
}
|
||||||
message += "+ /help – выводит данное сообщение\n"
|
message += "+ /help – выводит данное сообщение\n"
|
||||||
|
@ -64,6 +64,8 @@ func (u *Users) GetOrCreatePlayer(telegramID int) (dbmapping.Player, bool) {
|
|||||||
func (u *Users) PlayerBetterThan(playerRaw *dbmapping.Player, powerLevel string) bool {
|
func (u *Users) PlayerBetterThan(playerRaw *dbmapping.Player, powerLevel string) bool {
|
||||||
var isBetter = false
|
var isBetter = false
|
||||||
switch playerRaw.Status {
|
switch playerRaw.Status {
|
||||||
|
case "special":
|
||||||
|
isBetter = true
|
||||||
case "owner":
|
case "owner":
|
||||||
isBetter = true
|
isBetter = true
|
||||||
case "admin":
|
case "admin":
|
||||||
|
@ -87,6 +87,14 @@ func (u *Users) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Playe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if strings.HasPrefix(currentString, "id: ") {
|
||||||
|
realUserID := strings.TrimPrefix(currentString, "id: ")
|
||||||
|
c.Log.Debug("Profile user ID: " + realUserID)
|
||||||
|
realUID, _ := strconv.Atoi(realUserID)
|
||||||
|
if realUID != playerRaw.TelegramID {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
}
|
||||||
if strings.HasPrefix(currentString, "👤Уровень:") {
|
if strings.HasPrefix(currentString, "👤Уровень:") {
|
||||||
levelRx := regexp.MustCompile("\\d+")
|
levelRx := regexp.MustCompile("\\d+")
|
||||||
levelArray := levelRx.FindAllString(currentString, -1)
|
levelArray := levelRx.FindAllString(currentString, -1)
|
||||||
|
@ -32,6 +32,17 @@ func (w *Welcomer) PrivateWelcomeMessageAuthorized(update *tgbotapi.Update, play
|
|||||||
c.Bot.Send(msg)
|
c.Bot.Send(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrivateWelcomeMessageSpecial greets existing user with `special` access
|
||||||
|
func (w *Welcomer) PrivateWelcomeMessageSpecial(update *tgbotapi.Update, playerRaw *dbmapping.Player) {
|
||||||
|
message := "*Бот Инстинкта приветствует тебя. Снова.*\n\n"
|
||||||
|
message += "Привет, " + update.Message.From.FirstName + " " + update.Message.From.LastName + "!\n"
|
||||||
|
message += "\nБудь аккуратен, суперюзер!"
|
||||||
|
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||||
|
msg.ParseMode = "Markdown"
|
||||||
|
|
||||||
|
c.Bot.Send(msg)
|
||||||
|
}
|
||||||
|
|
||||||
// GroupWelcomeMessage welcomes new user on group or bot itself
|
// GroupWelcomeMessage welcomes new user on group or bot itself
|
||||||
func (w *Welcomer) GroupWelcomeMessage(update *tgbotapi.Update) string {
|
func (w *Welcomer) GroupWelcomeMessage(update *tgbotapi.Update) string {
|
||||||
newUsers := *update.Message.NewChatMembers
|
newUsers := *update.Message.NewChatMembers
|
||||||
|
@ -14,5 +14,6 @@ type WelcomerInterface interface {
|
|||||||
|
|
||||||
PrivateWelcomeMessageUnauthorized(update *tgbotapi.Update)
|
PrivateWelcomeMessageUnauthorized(update *tgbotapi.Update)
|
||||||
PrivateWelcomeMessageAuthorized(update *tgbotapi.Update, playerRaw *dbmapping.Player)
|
PrivateWelcomeMessageAuthorized(update *tgbotapi.Update, playerRaw *dbmapping.Player)
|
||||||
|
PrivateWelcomeMessageSpecial(update *tgbotapi.Update, playerRaw *dbmapping.Player)
|
||||||
GroupWelcomeMessage(update *tgbotapi.Update) string
|
GroupWelcomeMessage(update *tgbotapi.Update) string
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user