2021-12-03 14:30:10 +03:00
|
|
|
package kicker
|
2021-12-03 12:19:55 +03:00
|
|
|
|
|
|
|
import (
|
2022-11-09 00:45:08 +03:00
|
|
|
"context"
|
2023-09-07 01:10:30 +03:00
|
|
|
"fmt"
|
2022-11-09 00:45:08 +03:00
|
|
|
"kickerbot/db"
|
2021-12-03 12:19:55 +03:00
|
|
|
"log"
|
2023-09-07 01:10:30 +03:00
|
|
|
"regexp"
|
2023-09-13 22:33:53 +03:00
|
|
|
"strconv"
|
2022-11-09 00:45:08 +03:00
|
|
|
"strings"
|
2021-12-03 12:19:55 +03:00
|
|
|
"time"
|
|
|
|
|
2023-02-14 00:50:21 +03:00
|
|
|
"git.nefrace.ru/nefrace/tongo"
|
|
|
|
"github.com/NicoNex/echotron/v3"
|
2021-12-03 12:19:55 +03:00
|
|
|
)
|
|
|
|
|
2023-02-14 00:50:21 +03:00
|
|
|
var Client *tongo.Database
|
|
|
|
|
2022-11-09 00:45:08 +03:00
|
|
|
type bot struct {
|
|
|
|
chatID int64
|
|
|
|
CaptchaTopic int64
|
2023-02-14 00:50:21 +03:00
|
|
|
Me *echotron.User
|
|
|
|
echotron.API
|
2022-11-09 00:45:08 +03:00
|
|
|
}
|
|
|
|
|
2023-02-14 00:50:21 +03:00
|
|
|
func (b *bot) Update(update *echotron.Update) {
|
2022-11-09 01:23:32 +03:00
|
|
|
if update.Message != nil {
|
|
|
|
if len(update.Message.NewChatMembers) != 0 {
|
|
|
|
for _, user := range update.Message.NewChatMembers {
|
|
|
|
if user.ID == b.Me.ID {
|
|
|
|
botAdded(b, update)
|
|
|
|
}
|
2022-11-09 00:45:08 +03:00
|
|
|
}
|
2022-11-09 01:23:32 +03:00
|
|
|
userJoined(b, update)
|
|
|
|
return
|
2022-11-09 00:45:08 +03:00
|
|
|
}
|
2022-11-09 01:23:32 +03:00
|
|
|
if update.Message.LeftChatMember != nil {
|
|
|
|
userLeft(b, update)
|
2022-11-09 00:45:08 +03:00
|
|
|
return
|
|
|
|
}
|
2022-11-09 01:23:32 +03:00
|
|
|
if update.Message.Text != "" {
|
2023-09-13 22:33:53 +03:00
|
|
|
res, err := b.GetChatMember(update.ChatID(), update.Message.From.ID)
|
|
|
|
if err != nil {
|
|
|
|
log.Println("Kicker 44: can't get user member: ", err)
|
2022-11-09 01:23:32 +03:00
|
|
|
return
|
|
|
|
}
|
2023-09-13 22:33:53 +03:00
|
|
|
if res.Result.Status == "administrator" || res.Result.Status == "creator" {
|
|
|
|
if update.Message.Text == "/settopic" {
|
|
|
|
setTopic(b, update)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if update.Message.Text == "/admin" {
|
|
|
|
setAdminTopic(b, update, true)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if update.Message.Text == "/unadmin" {
|
|
|
|
setAdminTopic(b, update, false)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if strings.HasPrefix(update.Message.Text, "/mute") {
|
|
|
|
muteUser(b, update)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2022-11-09 01:23:32 +03:00
|
|
|
checkCaptcha(b, update)
|
|
|
|
}
|
2023-09-13 22:33:53 +03:00
|
|
|
checkAdminTopics(b, update)
|
2022-11-09 00:45:08 +03:00
|
|
|
}
|
2023-09-10 02:48:59 +03:00
|
|
|
if update.ChatMember != nil {
|
|
|
|
m := update.ChatMember.NewChatMember
|
|
|
|
if m.Status == "kicked" {
|
|
|
|
userBanned(b, update)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2021-12-03 12:19:55 +03:00
|
|
|
}
|
|
|
|
|
2021-12-03 14:35:07 +03:00
|
|
|
// Базовая структура для бота
|
2021-12-03 14:30:10 +03:00
|
|
|
type Kicker struct {
|
2022-11-09 00:45:08 +03:00
|
|
|
Token string
|
2023-02-14 00:50:21 +03:00
|
|
|
Dispatcher *echotron.Dispatcher
|
2021-12-03 12:19:55 +03:00
|
|
|
}
|
|
|
|
|
2023-02-14 00:50:21 +03:00
|
|
|
func (b *Kicker) NewBot(chatID int64) echotron.Bot {
|
2023-02-14 01:15:00 +03:00
|
|
|
store := tongo.NewStore[db.Chat](Client)
|
2022-11-09 00:45:08 +03:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
|
|
defer cancel()
|
2023-02-14 11:16:17 +03:00
|
|
|
|
|
|
|
chat, err := store.GetOne(ctx, tongo.E("chat_id", chatID))
|
|
|
|
if err != nil {
|
|
|
|
chat = &db.Chat{
|
|
|
|
Item: tongo.NewID(),
|
|
|
|
ChatId: chatID,
|
|
|
|
Title: "",
|
|
|
|
TopicId: 0,
|
|
|
|
}
|
|
|
|
if _, err := store.InsertOne(ctx, chat); err != nil {
|
2022-11-09 00:45:08 +03:00
|
|
|
return &bot{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CaptchaTopic := chat.TopicId
|
|
|
|
result := &bot{
|
|
|
|
chatID,
|
|
|
|
CaptchaTopic,
|
|
|
|
nil,
|
2023-02-14 00:50:21 +03:00
|
|
|
echotron.NewAPI(b.Token),
|
2022-11-09 00:45:08 +03:00
|
|
|
}
|
2023-02-14 11:17:01 +03:00
|
|
|
log.Println("New bot created with CaptchaTopic", result.CaptchaTopic)
|
2022-11-09 00:45:08 +03:00
|
|
|
me, err := result.GetMe()
|
2021-12-03 12:19:55 +03:00
|
|
|
if err != nil {
|
2022-11-09 00:45:08 +03:00
|
|
|
log.Println(err)
|
2021-12-03 12:19:55 +03:00
|
|
|
}
|
2022-11-09 00:45:08 +03:00
|
|
|
result.Me = me.Result
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize bot with token
|
|
|
|
func (b *Kicker) Init() error {
|
2023-02-14 00:50:21 +03:00
|
|
|
dsp := echotron.NewDispatcher(b.Token, b.NewBot)
|
2022-11-09 00:45:08 +03:00
|
|
|
b.Dispatcher = dsp
|
2021-12-03 12:19:55 +03:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-11-09 00:45:08 +03:00
|
|
|
func (b *Kicker) Start() error {
|
2023-09-10 02:48:59 +03:00
|
|
|
return b.Dispatcher.PollOptions(true, echotron.UpdateOptions{
|
|
|
|
Timeout: 120,
|
|
|
|
AllowedUpdates: []echotron.UpdateType{
|
|
|
|
echotron.MessageUpdate,
|
|
|
|
echotron.ChatMemberUpdate,
|
|
|
|
echotron.MyChatMemberUpdate,
|
|
|
|
echotron.CallbackQueryUpdate,
|
|
|
|
},
|
|
|
|
})
|
2022-11-09 00:45:08 +03:00
|
|
|
}
|
|
|
|
|
2023-02-14 00:50:21 +03:00
|
|
|
func EscapeText(parseMode echotron.ParseMode, text string) string {
|
2022-11-09 00:45:08 +03:00
|
|
|
var replacer *strings.Replacer
|
|
|
|
|
2023-02-14 00:50:21 +03:00
|
|
|
if parseMode == echotron.HTML {
|
2022-11-09 00:45:08 +03:00
|
|
|
replacer = strings.NewReplacer("<", "<", ">", ">", "&", "&")
|
2023-02-14 00:50:21 +03:00
|
|
|
} else if parseMode == echotron.Markdown {
|
2022-11-09 00:45:08 +03:00
|
|
|
replacer = strings.NewReplacer("_", "\\_", "*", "\\*", "`", "\\`", "[", "\\[")
|
2023-02-14 00:50:21 +03:00
|
|
|
} else if parseMode == echotron.MarkdownV2 {
|
2022-11-09 00:45:08 +03:00
|
|
|
replacer = strings.NewReplacer(
|
|
|
|
"_", "\\_", "*", "\\*", "[", "\\[", "]", "\\]", "(",
|
|
|
|
"\\(", ")", "\\)", "~", "\\~", "`", "\\`", ">", "\\>",
|
|
|
|
"#", "\\#", "+", "\\+", "-", "\\-", "=", "\\=", "|",
|
|
|
|
"\\|", "{", "\\{", "}", "\\}", ".", "\\.", "!", "\\!",
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
return ""
|
2021-12-03 12:19:55 +03:00
|
|
|
}
|
2022-11-09 00:45:08 +03:00
|
|
|
|
|
|
|
return replacer.Replace(text)
|
2021-12-03 12:19:55 +03:00
|
|
|
}
|
2023-02-14 00:50:21 +03:00
|
|
|
|
|
|
|
func waitAndDelete(b *echotron.API, message *echotron.Message, t time.Duration) {
|
|
|
|
time.Sleep(t)
|
2023-09-07 01:10:30 +03:00
|
|
|
if _, err := b.DeleteMessage(message.Chat.ID, message.ID); err != nil {
|
|
|
|
log.Printf("Can't delay-delete message: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func MentionUser(user *echotron.User) string {
|
|
|
|
return fmt.Sprintf("[%s](tg://user?id=%d)", EscapeText(echotron.MarkdownV2, user.FirstName), user.ID)
|
|
|
|
}
|
|
|
|
|
|
|
|
var chars = []string{"_", "\\*", "\\[", "\\]", "\\(", "\\)", "~", "`", ">", "#", "\\+", "\\-", "=", "|", "{", "}", "\\.", "!"}
|
|
|
|
var r = strings.Join(chars, "")
|
|
|
|
var reg = regexp.MustCompile("[" + r + "]+")
|
|
|
|
|
|
|
|
func EscapeMd2(s string) string {
|
|
|
|
return reg.ReplaceAllString(s, "\\$0")
|
|
|
|
}
|
|
|
|
|
|
|
|
func Mention(name string, id int64) string {
|
|
|
|
return fmt.Sprintf("[%s](tg://user?id=%d)", EscapeMd2(name), id)
|
|
|
|
}
|
|
|
|
|
|
|
|
func UserMention(u *echotron.User) string {
|
|
|
|
return Mention(u.FirstName, u.ID)
|
|
|
|
}
|
|
|
|
|
|
|
|
func UserMentionDB(u *db.User) string {
|
|
|
|
return Mention(u.FirstName, u.UserId)
|
2023-02-14 00:50:21 +03:00
|
|
|
}
|
2023-09-13 22:33:53 +03:00
|
|
|
|
|
|
|
func pluralRu(n int, single string, double string, five string) string {
|
|
|
|
switch n {
|
|
|
|
case 10, 11, 12, 13, 14, 15, 16, 17, 18, 19:
|
|
|
|
return five
|
|
|
|
default:
|
|
|
|
s := []rune(strconv.Itoa(n))
|
|
|
|
switch s[len(s)-1] {
|
|
|
|
case '1':
|
|
|
|
return single
|
|
|
|
case '2', '3', '4':
|
|
|
|
return double
|
|
|
|
default:
|
|
|
|
return five
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func transformChatID(id int64) int64 {
|
|
|
|
return -id - 1000000000000
|
|
|
|
|
|
|
|
}
|