Broadcast messages are now stored in database
This commit is contained in:
parent
7975ea54c1
commit
c676fb780d
19
lib/dbmapping/broadcast.go
Normal file
19
lib/dbmapping/broadcast.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// i2_bot – Instinct PokememBro Bot
|
||||||
|
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||||
|
|
||||||
|
package dbmapping
|
||||||
|
|
||||||
|
import (
|
||||||
|
// stdlib
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Broadcast is a struct, which represents `broadcast` table item in databse.
|
||||||
|
type Broadcast struct {
|
||||||
|
ID int `db:"id"`
|
||||||
|
Text string `db:"text"`
|
||||||
|
BroadcastType string `db:"broadcast_type"`
|
||||||
|
Status string `db:"status"`
|
||||||
|
AuthorID int `db:"author_id"`
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
}
|
69
lib/getters/broadcasts.go
Normal file
69
lib/getters/broadcasts.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// i2_bot – Instinct PokememBro Bot
|
||||||
|
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||||
|
|
||||||
|
package getters
|
||||||
|
|
||||||
|
import (
|
||||||
|
// stdlib
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
// local
|
||||||
|
"../dbmapping"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateBroadcastMessage creates broadcast message item in database
|
||||||
|
func (g *Getters) CreateBroadcastMessage(playerRaw *dbmapping.Player, messageBody string, broadcastType string) (dbmapping.Broadcast, bool) {
|
||||||
|
messageRaw := dbmapping.Broadcast{}
|
||||||
|
messageRaw.Text = messageBody
|
||||||
|
messageRaw.Status = "new"
|
||||||
|
messageRaw.BroadcastType = broadcastType
|
||||||
|
messageRaw.AuthorID = playerRaw.ID
|
||||||
|
messageRaw.CreatedAt = time.Now().UTC()
|
||||||
|
_, err := c.Db.NamedExec("INSERT INTO broadcasts VALUES(NULL, :text, :broadcast_type, :status, :author_id, :created_at)", &messageRaw)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(err.Error())
|
||||||
|
return messageRaw, false
|
||||||
|
}
|
||||||
|
err2 := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE author_id=? AND text=?"), messageRaw.AuthorID, messageRaw.Text)
|
||||||
|
if err2 != nil {
|
||||||
|
log.Println(err2)
|
||||||
|
return messageRaw, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return messageRaw, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBroadcastMessageByID returns dbmapping.Broadcast instance with given ID.
|
||||||
|
func (g *Getters) GetBroadcastMessageByID(messageID int) (dbmapping.Broadcast, bool) {
|
||||||
|
messageRaw := dbmapping.Broadcast{}
|
||||||
|
err := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE id=?"), messageID)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return messageRaw, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return messageRaw, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateBroadcastMessageStatus updates broadcast message status
|
||||||
|
func (g *Getters) UpdateBroadcastMessageStatus(messageID int, messageStatus string) (dbmapping.Broadcast, bool) {
|
||||||
|
messageRaw := dbmapping.Broadcast{}
|
||||||
|
err := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE id=?"), messageID)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return messageRaw, false
|
||||||
|
}
|
||||||
|
messageRaw.Status = messageStatus
|
||||||
|
_, err = c.Db.NamedExec("UPDATE broadcasts SET status=:status WHERE id=:id", &messageRaw)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(err.Error())
|
||||||
|
return messageRaw, false
|
||||||
|
}
|
||||||
|
err = c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE author_id=? AND text=?"), messageRaw.AuthorID, messageRaw.Text)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return messageRaw, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return messageRaw, true
|
||||||
|
}
|
@ -13,6 +13,9 @@ import (
|
|||||||
// GettersInterface implements Getters for importing via appcontext.
|
// GettersInterface implements Getters for importing via appcontext.
|
||||||
type GettersInterface interface {
|
type GettersInterface interface {
|
||||||
Init()
|
Init()
|
||||||
|
CreateBroadcastMessage(playerRaw *dbmapping.Player, messageBody string, broadcastType string) (dbmapping.Broadcast, bool)
|
||||||
|
GetBroadcastMessageByID(messageID int) (dbmapping.Broadcast, bool)
|
||||||
|
UpdateBroadcastMessageStatus(messageID int, messageStatus string) (dbmapping.Broadcast, bool)
|
||||||
GetOrCreateChat(update *tgbotapi.Update) (dbmapping.Chat, bool)
|
GetOrCreateChat(update *tgbotapi.Update) (dbmapping.Chat, bool)
|
||||||
GetChatByID(chatID int) (dbmapping.Chat, bool)
|
GetChatByID(chatID int) (dbmapping.Chat, bool)
|
||||||
GetAllPrivateChats() ([]dbmapping.Chat, bool)
|
GetAllPrivateChats() ([]dbmapping.Chat, bool)
|
||||||
|
37
lib/migrations/19_create_broadcasts.go
Normal file
37
lib/migrations/19_create_broadcasts.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// i2_bot – Instinct PokememBro Bot
|
||||||
|
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||||
|
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
// stdlib
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreateBroadcastsUp(tx *sql.Tx) error {
|
||||||
|
request := "CREATE TABLE `broadcasts` ("
|
||||||
|
request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID сообщения',"
|
||||||
|
request += "`text` text NOT NULL COMMENT 'Тело сообщения',"
|
||||||
|
request += "`broadcast_type` varchar(191) NOT NULL 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 `broadcasts_created_at` (`created_at`)"
|
||||||
|
request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Широковещательные сообщения';"
|
||||||
|
_, err := tx.Exec(request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateBroadcastsDown(tx *sql.Tx) error {
|
||||||
|
_, err := tx.Exec("DROP TABLE `broadcasts`;")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -33,6 +33,7 @@ func (m *Migrations) Init() {
|
|||||||
goose.AddNamedMigration("16_change_chat_type_column.go", ChangeChatTypeColumnUp, ChangeChatTypeColumnDown)
|
goose.AddNamedMigration("16_change_chat_type_column.go", ChangeChatTypeColumnUp, ChangeChatTypeColumnDown)
|
||||||
goose.AddNamedMigration("17_change_profile_pokememes_columns.go", ChangeProfilePokememesColumnsUp, ChangeProfilePokememesColumnsDown)
|
goose.AddNamedMigration("17_change_profile_pokememes_columns.go", ChangeProfilePokememesColumnsUp, ChangeProfilePokememesColumnsDown)
|
||||||
goose.AddNamedMigration("18_add_pokememes_wealth.go", AddPokememesWealthUp, AddPokememesWealthDown)
|
goose.AddNamedMigration("18_add_pokememes_wealth.go", AddPokememesWealthUp, AddPokememesWealthDown)
|
||||||
|
goose.AddNamedMigration("19_create_broadcasts.go", CreateBroadcastsUp, CreateBroadcastsDown)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Migrations) Migrate() error {
|
func (m *Migrations) Migrate() error {
|
||||||
|
@ -50,6 +50,7 @@ func (r *Router) RouteRequest(update tgbotapi.Update) string {
|
|||||||
|
|
||||||
// Owner commands
|
// Owner commands
|
||||||
var sendAllMsg = regexp.MustCompile("/send_all(.+)")
|
var sendAllMsg = regexp.MustCompile("/send_all(.+)")
|
||||||
|
var sendConfirmMsg = regexp.MustCompile(`/send_confirm(\s)(\d+)`)
|
||||||
|
|
||||||
// Forwards
|
// Forwards
|
||||||
var pokememeMsg = regexp.MustCompile("(Уровень)(.+)(Опыт)(.+)\n(Элементы:)(.+)\n(.+)(💙MP)")
|
var pokememeMsg = regexp.MustCompile("(Уровень)(.+)(Опыт)(.+)\n(Элементы:)(.+)\n(.+)(💙MP)")
|
||||||
@ -131,7 +132,13 @@ func (r *Router) RouteRequest(update tgbotapi.Update) string {
|
|||||||
// Admin commands
|
// Admin commands
|
||||||
case sendAllMsg.MatchString(text):
|
case sendAllMsg.MatchString(text):
|
||||||
if c.Getters.PlayerBetterThan(&playerRaw, "admin") {
|
if c.Getters.PlayerBetterThan(&playerRaw, "admin") {
|
||||||
c.Talkers.AdminBroadcastMessage(update)
|
c.Talkers.AdminBroadcastMessageCompose(update, &playerRaw)
|
||||||
|
} else {
|
||||||
|
c.Talkers.AnyMessageUnauthorized(update)
|
||||||
|
}
|
||||||
|
case sendConfirmMsg.MatchString(text):
|
||||||
|
if c.Getters.PlayerBetterThan(&playerRaw, "admin") {
|
||||||
|
c.Talkers.AdminBroadcastMessageSend(update, &playerRaw)
|
||||||
} else {
|
} else {
|
||||||
c.Talkers.AnyMessageUnauthorized(update)
|
c.Talkers.AnyMessageUnauthorized(update)
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,69 @@
|
|||||||
|
|
||||||
package talkers
|
package talkers
|
||||||
|
|
||||||
import ( // stdlib
|
import (
|
||||||
// 3rd party
|
// stdlib
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
// 3rd party
|
||||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||||
|
// local
|
||||||
|
"../dbmapping"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AdminBroadcastMessage sends message to all private chats with bot
|
// AdminBroadcastMessageCompose saves message for future broadcast
|
||||||
func (t *Talkers) AdminBroadcastMessage(update tgbotapi.Update) string {
|
func (t *Talkers) AdminBroadcastMessageCompose(update tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||||
broadcastingMessageBody := strings.Replace(update.Message.Text, "/send_all ", "", 1)
|
broadcastingMessageBody := strings.Replace(update.Message.Text, "/send_all ", "", 1)
|
||||||
|
|
||||||
|
messageRaw, ok := c.Getters.CreateBroadcastMessage(playerRaw, broadcastingMessageBody, "all")
|
||||||
|
if !ok {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
|
||||||
|
message := "Сообщение сохранено в базу.\n"
|
||||||
|
message += "Выглядеть оно будет так:"
|
||||||
|
|
||||||
|
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||||
|
msg.ParseMode = "Markdown"
|
||||||
|
|
||||||
|
c.Bot.Send(msg)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
message = "Чтобы отправить сообщение всем, отправь команду /send\\_confirm " + strconv.Itoa(messageRaw.ID)
|
||||||
|
|
||||||
|
msg = tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||||
|
msg.ParseMode = "Markdown"
|
||||||
|
|
||||||
|
c.Bot.Send(msg)
|
||||||
|
|
||||||
|
return "ok"
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdminBroadcastMessageSend sends saved message to all private chats
|
||||||
|
func (t *Talkers) AdminBroadcastMessageSend(update tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||||
|
messageNum := strings.Replace(update.Message.Text, "/send_confirm ", "", 1)
|
||||||
|
messageNumInt, _ := strconv.Atoi(messageNum)
|
||||||
|
messageRaw, ok := c.Getters.GetBroadcastMessageByID(messageNumInt)
|
||||||
|
if !ok {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
if messageRaw.AuthorID != playerRaw.ID {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
if messageRaw.Status != "new" {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
|
||||||
|
broadcastingMessageBody := messageRaw.Text
|
||||||
|
|
||||||
privateChats, ok := c.Getters.GetAllPrivateChats()
|
privateChats, ok := c.Getters.GetAllPrivateChats()
|
||||||
if !ok {
|
if !ok {
|
||||||
return "fail"
|
return "fail"
|
||||||
@ -30,6 +82,11 @@ func (t *Talkers) AdminBroadcastMessage(update tgbotapi.Update) string {
|
|||||||
c.Bot.Send(msg)
|
c.Bot.Send(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
messageRaw, ok = c.Getters.UpdateBroadcastMessageStatus(messageRaw.ID, "sent")
|
||||||
|
if !ok {
|
||||||
|
return "fail"
|
||||||
|
}
|
||||||
|
|
||||||
message := "Сообщение всем отправлено. Надеюсь, пользователи бота за него тебя не убьют.\n"
|
message := "Сообщение всем отправлено. Надеюсь, пользователи бота за него тебя не убьют.\n"
|
||||||
|
|
||||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||||
|
@ -30,7 +30,8 @@ type TalkersInterface interface {
|
|||||||
AnyMessageUnauthorized(update tgbotapi.Update)
|
AnyMessageUnauthorized(update tgbotapi.Update)
|
||||||
GetterError(update tgbotapi.Update)
|
GetterError(update tgbotapi.Update)
|
||||||
|
|
||||||
AdminBroadcastMessage(update tgbotapi.Update) string
|
AdminBroadcastMessageCompose(update tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||||
|
AdminBroadcastMessageSend(update tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||||
|
|
||||||
DurakMessage(update tgbotapi.Update)
|
DurakMessage(update tgbotapi.Update)
|
||||||
MatMessage(update tgbotapi.Update)
|
MatMessage(update tgbotapi.Update)
|
||||||
|
Reference in New Issue
Block a user