Switched to Echotron, added topics

This commit is contained in:
2022-11-09 00:45:08 +03:00
parent b221253a6c
commit 43f881178b
9 changed files with 282 additions and 108 deletions

View File

@ -9,19 +9,23 @@ import (
"strconv"
"time"
tb "gopkg.in/tucnak/telebot.v3"
tb "github.com/NicoNex/echotron/v3"
"go.mongodb.org/mongo-driver/bson"
)
func userJoined(c tb.Context) error {
bot := c.Bot()
func userJoined(b *bot, update *tb.Update) error {
captcha := captchagen.GenCaptcha()
reader := captcha.ToReader()
message := c.Message()
bytes, err := captcha.ToBytes()
if err != nil {
fmt.Printf("Error creating captcha bytes: %v", bytes)
b.SendMessage("Не могу создать капчу, @nefrace, проверь логи.", update.Message.From.ID, &tb.MessageOptions{MessageThreadID: update.Message.ThreadID})
}
message := update.Message
user := db.User{
Id: message.Sender.ID,
Username: message.Sender.Username,
FirstName: message.Sender.FirstName,
LastName: message.Sender.LastName,
Id: message.From.ID,
Username: message.From.Username,
FirstName: message.From.FirstName,
LastName: message.From.LastName,
IsBanned: false,
ChatId: message.Chat.ID,
JoinedMessage: message.ID,
@ -33,41 +37,55 @@ func userJoined(c tb.Context) error {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
log.Print(user)
msg := fmt.Sprintf("Приветствую тебя, %v!\nДля подтверждения, что ты человек, выбери логотип движка, которому посвящен данный чат, и отправь его номер сюда.\nЯ дам тебе две минуты на это.", user.FirstName)
photo := tb.Photo{File: tb.FromReader(reader), Caption: msg}
result, err := bot.Send(tb.ChatID(message.Chat.ID), &photo, &tb.SendOptions{ReplyTo: message})
msg := fmt.Sprintf("Приветствую тебя, *[%s](tg://user?id=%d)*\\!\nДля подтверждения, что ты человек, выбери логотип движка, которому посвящен данный чат, и отправь его номер сюда\\.\n*_Я дам тебе две минуты на это\\._*", EscapeText(tb.MarkdownV2, user.FirstName), user.Id)
options := tb.PhotoOptions{
Caption: msg,
ParseMode: tb.MarkdownV2,
}
if message.Chat.IsForum {
options.MessageThreadID = int(b.CaptchaTopic)
}
result, err := b.SendPhoto(tb.NewInputFileBytes("logos.png", *bytes), message.Chat.ID, &options)
if err != nil {
return err
}
user.CaptchaMessage = result.ID
user.CaptchaMessage = result.Result.ID
d.NewUser(ctx, user)
return nil
}
func userLeft(c tb.Context) error {
bot := c.Bot()
message := c.Message()
sender := c.Sender()
func userLeft(b *bot, update *tb.Update) error {
message := update.Message
sender := message.From
d := db.GetDatabase()
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
if user, err := d.GetUser(ctx, db.User{Id: sender.ID, ChatId: message.Chat.ID}); err == nil {
d.RemoveUser(ctx, user)
bot.Delete(&tb.Message{Chat: message.Chat, ID: user.CaptchaMessage})
bot.Delete(&tb.Message{Chat: message.Chat, ID: user.JoinedMessage})
b.DeleteMessage(message.Chat.ID, message.ID)
b.DeleteMessage(message.Chat.ID, user.CaptchaMessage)
}
return nil
}
func checkCaptcha(c tb.Context) error {
sender := c.Sender()
message := c.Message()
bot := c.Bot()
func checkCaptcha(b *bot, update *tb.Update) error {
message := update.Message
sender := message.ForwardFrom
d := db.GetDatabase()
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
if user, err := d.GetUser(ctx, db.User{Id: sender.ID, ChatId: message.Chat.ID}); err == nil {
if message.Chat.IsForum {
chat, err := d.GetChat(ctx, message.Chat.ID)
if err != nil {
return err
}
if message.ThreadID != int(chat.TopicId) {
b.DeleteMessage(message.Chat.ID, message.ID)
return nil
}
}
text_runes := []rune(message.Text)
guess := string(text_runes[0])
solved := false
@ -75,28 +93,30 @@ func checkCaptcha(c tb.Context) error {
if num == int(user.CorrectAnswer) {
_ = d.RemoveUser(ctx, user)
solved = true
bot.Delete(message)
bot.Delete(&tb.Message{Chat: message.Chat, ID: user.CaptchaMessage})
b.DeleteMessage(message.Chat.ID, message.ID)
b.DeleteMessage(message.Chat.ID, user.CaptchaMessage)
}
} else {
log.Print(err)
log.Println(err)
return err
}
if !solved {
bot.Delete(message)
bot.Delete(&tb.Message{Chat: message.Chat, ID: user.CaptchaMessage})
bot.Delete(&tb.Message{Chat: message.Chat, ID: user.JoinedMessage})
bot.Ban(message.Chat, &tb.ChatMember{User: sender})
b.DeleteMessage(message.Chat.ID, message.ID)
b.DeleteMessage(message.Chat.ID, user.CaptchaMessage)
b.DeleteMessage(message.Chat.ID, user.JoinedMessage)
b.BanChatMember(message.Chat.ID, sender.ID, nil)
_ = d.RemoveUser(ctx, user)
}
}
return nil
}
func botAdded(c tb.Context) error {
m := c.Message()
func botAdded(b *bot, update *tb.Update) error {
m := update.Message
chat := db.Chat{
Id: m.Chat.ID,
Title: m.Chat.Title,
Id: m.Chat.ID,
Title: m.Chat.Title,
TopicId: 0,
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
@ -108,22 +128,22 @@ func botAdded(c tb.Context) error {
return nil
}
var HandlersV1 = []Handler{
{
Endpoint: tb.OnText,
Handler: checkCaptcha,
},
{
Endpoint: tb.OnAddedToGroup,
Handler: botAdded,
},
{
Endpoint: tb.OnUserJoined,
Handler: userJoined,
},
{
Endpoint: tb.OnUserLeft,
Handler: userLeft,
},
func setTopic(b *bot, update *tb.Update) error {
m := update.Message
d := db.GetDatabase()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
chat, err := d.GetChat(ctx, m.Chat.ID)
if err != nil {
return err
}
upd := bson.D{{Key: "$set", Value: bson.D{{Key: "topic_id", Value: m.ThreadID}}}}
b.CaptchaTopic = int64(m.ThreadID)
err = d.UpdateChat(ctx, chat, upd)
if err != nil {
return err
}
b.DeleteMessage(m.Chat.ID, m.ID)
b.SendMessage("Данный топик выбран в качестве проверочного для пользователей", m.Chat.ID, &tb.MessageOptions{MessageThreadID: m.ThreadID})
return nil
}

View File

@ -1,45 +1,111 @@
package kicker
import (
"errors"
"context"
"kickerbot/db"
"log"
"strings"
"time"
tb "gopkg.in/tucnak/telebot.v3"
tb "github.com/NicoNex/echotron/v3"
)
type Handler struct {
Endpoint interface{}
Handler tb.HandlerFunc
type bot struct {
chatID int64
CaptchaTopic int64
Me *tb.User
tb.API
}
func (b *bot) Update(update *tb.Update) {
if len(update.Message.NewChatMembers) != 0 {
for _, user := range update.Message.NewChatMembers {
if user.ID == b.Me.ID {
botAdded(b, update)
}
}
userJoined(b, update)
return
}
if update.Message.LeftChatMember != nil {
userLeft(b, update)
return
}
if update.Message.Text != "" {
if update.Message.Text == "/settopic" {
setTopic(b, update)
return
}
checkCaptcha(b, update)
}
}
// Базовая структура для бота
type Kicker struct {
Bot *tb.Bot
Token string
Token string
Dispatcher *tb.Dispatcher
}
func (b *Kicker) NewBot(chatID int64) tb.Bot {
d := db.GetDatabase()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
chat := db.Chat{
Id: chatID,
Title: "",
TopicId: 0,
}
if !d.ChatExists(ctx, chat) {
if err := d.NewChat(ctx, chat); err != nil {
return &bot{}
}
}
chat, _ = d.GetChat(ctx, chatID)
CaptchaTopic := chat.TopicId
result := &bot{
chatID,
CaptchaTopic,
nil,
tb.NewAPI(b.Token),
}
me, err := result.GetMe()
if err != nil {
log.Println(err)
}
result.Me = me.Result
return result
}
// Initialize bot with token
func (b *Kicker) Init() error {
bot, err := tb.NewBot(tb.Settings{
Token: b.Token,
Poller: &tb.LongPoller{Timeout: 10 * time.Second},
})
if err != nil {
log.Print(err)
return err
}
b.Bot = bot
dsp := tb.NewDispatcher(b.Token, b.NewBot)
b.Dispatcher = dsp
return nil
}
// Add handler methods to the bot
func (b *Kicker) AddHandlers(handlers []Handler) error {
if len(handlers) != 0 {
for i := range handlers {
b.Bot.Handle(handlers[i].Endpoint, handlers[i].Handler)
}
return nil
}
return errors.New("no handlers are declared")
func (b *Kicker) Start() error {
return b.Dispatcher.Poll()
}
func EscapeText(parseMode tb.ParseMode, text string) string {
var replacer *strings.Replacer
if parseMode == tb.HTML {
replacer = strings.NewReplacer("<", "&lt;", ">", "&gt;", "&", "&amp;")
} else if parseMode == tb.Markdown {
replacer = strings.NewReplacer("_", "\\_", "*", "\\*", "`", "\\`", "[", "\\[")
} else if parseMode == tb.MarkdownV2 {
replacer = strings.NewReplacer(
"_", "\\_", "*", "\\*", "[", "\\[", "]", "\\]", "(",
"\\(", ")", "\\)", "~", "\\~", "`", "\\`", ">", "\\>",
"#", "\\#", "+", "\\+", "-", "\\-", "=", "\\=", "|",
"\\|", "{", "\\{", "}", "\\}", ".", "\\.", "!", "\\!",
)
} else {
return ""
}
return replacer.Replace(text)
}

View File

@ -6,12 +6,17 @@ import (
"log"
"time"
tb "github.com/NicoNex/echotron/v3"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
tb "gopkg.in/tucnak/telebot.v3"
)
func TaskKickOldUsers(b tb.Bot) {
type TaskBot struct {
Token string
tb.API
}
func TaskKickOldUsers(b *tb.API) {
d := db.GetDatabase()
log.Print("STARTING KICKING TASK")
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
@ -26,14 +31,9 @@ func TaskKickOldUsers(b tb.Bot) {
log.Printf("Error in deleting task: %v", err)
}
for _, user := range users {
chat := tb.Chat{ID: user.ChatId}
tbUser := tb.User{ID: user.Id}
member := tb.ChatMember{User: &tbUser}
message := tb.Message{Chat: &chat, ID: user.CaptchaMessage}
joinMessage := tb.Message{Chat: &chat, ID: user.JoinedMessage}
b.Ban(&chat, &member)
b.Delete(&message)
b.Delete(&joinMessage)
b.BanChatMember(user.ChatId, user.Id, &tb.BanOptions{RevokeMessages: true})
b.DeleteMessage(user.ChatId, user.CaptchaMessage)
b.DeleteMessage(user.ChatId, user.JoinedMessage)
d.RemoveUser(ctx, user)
}
}