Switched to Echotron, added topics
This commit is contained in:
@ -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
|
||||
}
|
||||
|
116
kicker/kicker.go
116
kicker/kicker.go
@ -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("<", "<", ">", ">", "&", "&")
|
||||
} else if parseMode == tb.Markdown {
|
||||
replacer = strings.NewReplacer("_", "\\_", "*", "\\*", "`", "\\`", "[", "\\[")
|
||||
} else if parseMode == tb.MarkdownV2 {
|
||||
replacer = strings.NewReplacer(
|
||||
"_", "\\_", "*", "\\*", "[", "\\[", "]", "\\]", "(",
|
||||
"\\(", ")", "\\)", "~", "\\~", "`", "\\`", ">", "\\>",
|
||||
"#", "\\#", "+", "\\+", "-", "\\-", "=", "\\=", "|",
|
||||
"\\|", "{", "\\{", "}", "\\}", ".", "\\.", "!", "\\!",
|
||||
)
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
return replacer.Replace(text)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user