Compare commits
	
		
			14 Commits
		
	
	
		
			echotron
			...
			bb0862ba8b
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bb0862ba8b | |||
| 1c4a0adb61 | |||
| 75454a3233 | |||
| 23d4e9893e | |||
| 8f661d68a1 | |||
| 7ac170ce04 | |||
| 7fba6ddb93 | |||
| 765be0673b | |||
| 15a27af994 | |||
| 7e8b026c5e | |||
| 919b341fc1 | |||
| e02e879378 | |||
| 49147208d1 | |||
| 90617d751d | 
@ -1,20 +1,33 @@
 | 
				
			|||||||
package db
 | 
					package db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"git.nefrace.ru/nefrace/tongo"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Chat struct {
 | 
					type Chat struct {
 | 
				
			||||||
	Id      int64
 | 
						tongo.Item `bson:",inline"`
 | 
				
			||||||
	Title   string
 | 
						ChatId     int64 `bson:"chat_id"`
 | 
				
			||||||
	TopicId int64 `bson:"topic_id"`
 | 
						Title      string
 | 
				
			||||||
 | 
						TopicId    int64 `bson:"topic_id"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (Chat) Coll() string { return "chats" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type User struct {
 | 
					type User struct {
 | 
				
			||||||
	Id             int64
 | 
						tongo.Item       `bson:",inline"`
 | 
				
			||||||
	ChatId         int64  `bson:"chat_id"`
 | 
						UserId           int64     `bson:"user_id"`
 | 
				
			||||||
	Username       string `bson:"username"`
 | 
						ChatId           int64     `bson:"chat_id"`
 | 
				
			||||||
	FirstName      string `bson:"first_name"`
 | 
						Username         string    `bson:"username"`
 | 
				
			||||||
	LastName       string `bson:"last_name"`
 | 
						FirstName        string    `bson:"first_name"`
 | 
				
			||||||
	CorrectAnswer  int8   `bson:"correct_answer"`
 | 
						LastName         string    `bson:"last_name"`
 | 
				
			||||||
	CaptchaMessage int    `bson:"captcha_message"`
 | 
						CorrectAnswer    int8      `bson:"correct_answer"`
 | 
				
			||||||
	IsBanned       bool   `bson:"is_banned"`
 | 
						CaptchaMessage   int       `bson:"captcha_message"`
 | 
				
			||||||
	DateJoined     int64  `bson:"date_joined"`
 | 
						IsBanned         bool      `bson:"is_banned"`
 | 
				
			||||||
	JoinedMessage  int    `bson:"joined_message"`
 | 
						DateJoined       time.Time `bson:"date_joined"`
 | 
				
			||||||
 | 
						JoinedMessage    int       `bson:"joined_message"`
 | 
				
			||||||
 | 
						LastNotification time.Time `bson:"last_notification"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (User) Coll() string { return "users" }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							@ -11,6 +11,7 @@ require (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
 | 
						git.nefrace.ru/nefrace/tongo v0.0.0-20230124201743-e58da1b7d030
 | 
				
			||||||
	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
 | 
						github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
 | 
				
			||||||
	github.com/golang/snappy v0.0.4 // indirect
 | 
						github.com/golang/snappy v0.0.4 // indirect
 | 
				
			||||||
	github.com/klauspost/compress v1.15.13 // indirect
 | 
						github.com/klauspost/compress v1.15.13 // indirect
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					git.nefrace.ru/nefrace/tongo v0.0.0-20230124201743-e58da1b7d030 h1:s/T9bu8B/JQihx7HVj0Z7MG+veTAV97vEvNGfak+Wxo=
 | 
				
			||||||
 | 
					git.nefrace.ru/nefrace/tongo v0.0.0-20230124201743-e58da1b7d030/go.mod h1:I6AwXVmI+xC2kZ4TriUXK2Jchni1MZfiQQ4IWQBwC88=
 | 
				
			||||||
github.com/NicoNex/echotron/v3 v3.21.0 h1:6YDSYA/AGlPxWoUdOIRrBvUZ0RhRa2W4taS4eSrbdXw=
 | 
					github.com/NicoNex/echotron/v3 v3.21.0 h1:6YDSYA/AGlPxWoUdOIRrBvUZ0RhRa2W4taS4eSrbdXw=
 | 
				
			||||||
github.com/NicoNex/echotron/v3 v3.21.0/go.mod h1:LpP5IyHw0y+DZUZMBgXEDAF9O8feXrQu7w7nlJzzoZI=
 | 
					github.com/NicoNex/echotron/v3 v3.21.0/go.mod h1:LpP5IyHw0y+DZUZMBgXEDAF9O8feXrQu7w7nlJzzoZI=
 | 
				
			||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
					github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
 | 
				
			|||||||
@ -9,11 +9,11 @@ import (
 | 
				
			|||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tb "github.com/NicoNex/echotron/v3"
 | 
						"git.nefrace.ru/nefrace/tongo"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson"
 | 
						"github.com/NicoNex/echotron/v3"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func userJoined(b *bot, update *tb.Update) error {
 | 
					func userJoined(b *bot, update *echotron.Update) error {
 | 
				
			||||||
	captcha := captchagen.GenCaptcha()
 | 
						captcha := captchagen.GenCaptcha()
 | 
				
			||||||
	_, err := b.DeleteMessage(update.Message.Chat.ID, update.Message.ID)
 | 
						_, err := b.DeleteMessage(update.Message.Chat.ID, update.Message.ID)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@ -21,12 +21,14 @@ func userJoined(b *bot, update *tb.Update) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	bytes, err := captcha.ToBytes()
 | 
						bytes, err := captcha.ToBytes()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Printf("Error creating captcha bytes: %v", bytes)
 | 
							log.Printf("Error creating captcha bytes: %v", bytes)
 | 
				
			||||||
		b.SendMessage("Не могу создать капчу, @nefrace, проверь логи.", update.Message.From.ID, &tb.MessageOptions{MessageThreadID: update.Message.ThreadID})
 | 
							b.SendMessage("Не могу создать капчу, @nefrace, проверь логи.", update.Message.From.ID, &echotron.MessageOptions{MessageThreadID: update.Message.ThreadID})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	message := update.Message
 | 
						message := update.Message
 | 
				
			||||||
 | 
						store := tongo.NewStore[db.User](Client)
 | 
				
			||||||
	user := db.User{
 | 
						user := db.User{
 | 
				
			||||||
		Id:            message.From.ID,
 | 
							Item:          tongo.NewID(),
 | 
				
			||||||
 | 
							UserId:        message.From.ID,
 | 
				
			||||||
		Username:      message.From.Username,
 | 
							Username:      message.From.Username,
 | 
				
			||||||
		FirstName:     message.From.FirstName,
 | 
							FirstName:     message.From.FirstName,
 | 
				
			||||||
		LastName:      message.From.LastName,
 | 
							LastName:      message.From.LastName,
 | 
				
			||||||
@ -34,59 +36,62 @@ func userJoined(b *bot, update *tb.Update) error {
 | 
				
			|||||||
		ChatId:        message.Chat.ID,
 | 
							ChatId:        message.Chat.ID,
 | 
				
			||||||
		JoinedMessage: message.ID,
 | 
							JoinedMessage: message.ID,
 | 
				
			||||||
		CorrectAnswer: int8(captcha.CorrectAnswer),
 | 
							CorrectAnswer: int8(captcha.CorrectAnswer),
 | 
				
			||||||
		DateJoined:    time.Now().Unix(),
 | 
							DateJoined:    time.Now(),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	user.CorrectAnswer = int8(captcha.CorrectAnswer)
 | 
						// user.CorrectAnswer = int8(captcha.CorrectAnswer)
 | 
				
			||||||
	d := db.GetDatabase()
 | 
					 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
 | 
						ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
 | 
				
			||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	log.Print(user)
 | 
						log.Print(user)
 | 
				
			||||||
	msg := fmt.Sprintf("Приветствую тебя, *[%s](tg://user?id=%d)*\\!\nДля подтверждения, что ты человек, выбери логотип движка, которому посвящен данный чат, и отправь его номер сюда\\.\n*_Я дам тебе две минуты на это\\._*", EscapeText(tb.MarkdownV2, user.FirstName), user.Id)
 | 
						msg := fmt.Sprintf("Приветствую тебя, *[%s](tg://user?id=%d)*\\!\nДля подтверждения, что ты человек, выбери логотип движка, которому посвящен данный чат, и отправь его номер сюда\\.\n*_Я дам тебе десять минут на это\\._*", EscapeText(echotron.MarkdownV2, user.FirstName), user.Id)
 | 
				
			||||||
	options := tb.PhotoOptions{
 | 
						options := echotron.PhotoOptions{
 | 
				
			||||||
		Caption:   msg,
 | 
							Caption:   msg,
 | 
				
			||||||
		ParseMode: tb.MarkdownV2,
 | 
							ParseMode: echotron.MarkdownV2,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if message.Chat.IsForum {
 | 
						if message.Chat.IsForum {
 | 
				
			||||||
		options.MessageThreadID = int(b.CaptchaTopic)
 | 
							options.MessageThreadID = int(b.CaptchaTopic)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	result, err := b.SendPhoto(tb.NewInputFileBytes("logos.png", *bytes), message.Chat.ID, &options)
 | 
						result, err := b.SendPhoto(echotron.NewInputFileBytes("logos.png", *bytes), message.Chat.ID, &options)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	user.CaptchaMessage = result.Result.ID
 | 
						user.CaptchaMessage = result.Result.ID
 | 
				
			||||||
 | 
						store.InsertOne(ctx, &user)
 | 
				
			||||||
	d.NewUser(ctx, user)
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func userLeft(b *bot, update *tb.Update) error {
 | 
					func userLeft(b *bot, update *echotron.Update) error {
 | 
				
			||||||
	message := update.Message
 | 
						message := update.Message
 | 
				
			||||||
	sender := message.From
 | 
						sender := message.From
 | 
				
			||||||
	d := db.GetDatabase()
 | 
						store := tongo.NewStore[db.User](Client)
 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
 | 
						ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
 | 
				
			||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	if user, err := d.GetUser(ctx, db.User{Id: sender.ID, ChatId: message.Chat.ID}); err == nil {
 | 
						if user, err := store.GetOne(ctx, tongo.E("user_id", sender.ID), tongo.E("chat_id", message.Chat.ID)); err == nil { //d.GetUser(ctx, db.User{UserId: sender.ID, ChatId: message.Chat.ID}); err == nil {
 | 
				
			||||||
		d.RemoveUser(ctx, user)
 | 
							store.DeleteByID(ctx, user.Id)
 | 
				
			||||||
		b.DeleteMessage(message.Chat.ID, message.ID)
 | 
							b.DeleteMessage(message.Chat.ID, message.ID)
 | 
				
			||||||
		b.DeleteMessage(message.Chat.ID, user.CaptchaMessage)
 | 
							b.DeleteMessage(message.Chat.ID, user.CaptchaMessage)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func checkCaptcha(b *bot, update *tb.Update) error {
 | 
					func checkCaptcha(b *bot, update *echotron.Update) error {
 | 
				
			||||||
	message := update.Message
 | 
						message := update.Message
 | 
				
			||||||
	sender := message.From
 | 
						sender := message.From
 | 
				
			||||||
	d := db.GetDatabase()
 | 
						store := tongo.NewStore[db.User](Client)
 | 
				
			||||||
 | 
						chatStore := tongo.NewStore[db.Chat](Client)
 | 
				
			||||||
 | 
						// d := db.GetDatabase()
 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
 | 
						ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
 | 
				
			||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	if user, err := d.GetUser(ctx, db.User{Id: sender.ID, ChatId: message.Chat.ID}); err == nil {
 | 
						if user, err := store.GetOne(ctx, tongo.E("user_id", sender.ID), tongo.E("chat_id", message.Chat.ID)); err == nil { //d.GetUser(ctx, db.User{UserId: sender.ID, ChatId: message.Chat.ID}); err == nil {
 | 
				
			||||||
		if message.Chat.IsForum {
 | 
							if message.Chat.IsForum {
 | 
				
			||||||
			chat, err := d.GetChat(ctx, message.Chat.ID)
 | 
								chat, err := chatStore.GetOne(ctx, tongo.E("chat_id", message.Chat.ID))
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if message.ThreadID != int(chat.TopicId) {
 | 
								if message.ThreadID != int(chat.TopicId) {
 | 
				
			||||||
				b.DeleteMessage(message.Chat.ID, message.ID)
 | 
									b.DeleteMessage(message.Chat.ID, message.ID)
 | 
				
			||||||
 | 
									text := fmt.Sprintf("*[%s](tg://user?id=%d)*, сначала пройди капчу\\!", user.FirstName, user.UserId)
 | 
				
			||||||
 | 
									res, _ := b.SendMessage(text, message.Chat.ID, &echotron.MessageOptions{ParseMode: echotron.MarkdownV2, MessageThreadID: message.ThreadID})
 | 
				
			||||||
 | 
									go waitAndDelete(&b.API, res.Result, 10*time.Second)
 | 
				
			||||||
				return nil
 | 
									return nil
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -95,13 +100,13 @@ func checkCaptcha(b *bot, update *tb.Update) error {
 | 
				
			|||||||
		solved := false
 | 
							solved := false
 | 
				
			||||||
		if num, err := strconv.Atoi(guess); err == nil {
 | 
							if num, err := strconv.Atoi(guess); err == nil {
 | 
				
			||||||
			if num == int(user.CorrectAnswer) {
 | 
								if num == int(user.CorrectAnswer) {
 | 
				
			||||||
				_ = d.RemoveUser(ctx, user)
 | 
									_ = store.DeleteByID(ctx, user.Id)
 | 
				
			||||||
				solved = true
 | 
									solved = true
 | 
				
			||||||
				b.DeleteMessage(message.Chat.ID, message.ID)
 | 
									b.DeleteMessage(message.Chat.ID, message.ID)
 | 
				
			||||||
				b.DeleteMessage(message.Chat.ID, user.CaptchaMessage)
 | 
									b.DeleteMessage(message.Chat.ID, user.CaptchaMessage)
 | 
				
			||||||
				msg := fmt.Sprintf("Приветствую тебя, *[%s](tg://user?id=%d)* успешно прошёл капчу\\!", EscapeText(tb.MarkdownV2, user.FirstName), user.Id)
 | 
									msg := fmt.Sprintf("*[%s](tg://user?id=%d)* только что успешно прошёл капчу\\!", EscapeText(echotron.MarkdownV2, user.FirstName), user.Id)
 | 
				
			||||||
				options := tb.MessageOptions{
 | 
									options := echotron.MessageOptions{
 | 
				
			||||||
					ParseMode: tb.MarkdownV2,
 | 
										ParseMode: echotron.MarkdownV2,
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if message.Chat.IsForum {
 | 
									if message.Chat.IsForum {
 | 
				
			||||||
					options.MessageThreadID = int(b.CaptchaTopic)
 | 
										options.MessageThreadID = int(b.CaptchaTopic)
 | 
				
			||||||
@ -110,8 +115,9 @@ func checkCaptcha(b *bot, update *tb.Update) error {
 | 
				
			|||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					log.Printf("Can't send welcome message: %s", err)
 | 
										log.Printf("Can't send welcome message: %s", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				time.Sleep(time.Second * 10)
 | 
									go waitAndDelete(&b.API, res.Result, 10*time.Second)
 | 
				
			||||||
				_, err = b.DeleteMessage(message.Chat.ID, res.Result.ID)
 | 
									// time.Sleep(time.Second * 10)
 | 
				
			||||||
 | 
									// _, err = b.DeleteMessage(message.Chat.ID, res.Result.ID)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					log.Printf("Can't delete welcome message: %s", err)
 | 
										log.Printf("Can't delete welcome message: %s", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -122,45 +128,51 @@ func checkCaptcha(b *bot, update *tb.Update) error {
 | 
				
			|||||||
			b.DeleteMessage(message.Chat.ID, user.CaptchaMessage)
 | 
								b.DeleteMessage(message.Chat.ID, user.CaptchaMessage)
 | 
				
			||||||
			b.DeleteMessage(message.Chat.ID, user.JoinedMessage)
 | 
								b.DeleteMessage(message.Chat.ID, user.JoinedMessage)
 | 
				
			||||||
			b.BanChatMember(message.Chat.ID, sender.ID, nil)
 | 
								b.BanChatMember(message.Chat.ID, sender.ID, nil)
 | 
				
			||||||
			_ = d.RemoveUser(ctx, user)
 | 
								_ = store.DeleteByID(ctx, user.Id)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func botAdded(b *bot, update *tb.Update) error {
 | 
					func botAdded(b *bot, update *echotron.Update) error {
 | 
				
			||||||
	m := update.Message
 | 
						m := update.Message
 | 
				
			||||||
	chat := db.Chat{
 | 
						store := tongo.NewStore[db.Chat](Client)
 | 
				
			||||||
		Id:      m.Chat.ID,
 | 
					 | 
				
			||||||
		Title:   m.Chat.Title,
 | 
					 | 
				
			||||||
		TopicId: 0,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 | 
						ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 | 
				
			||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	d := db.GetDatabase()
 | 
						chat, err := store.GetOne(ctx, tongo.E("chat_id", m.Chat.ID))
 | 
				
			||||||
	err := d.NewChat(ctx, chat)
 | 
						if err != nil {
 | 
				
			||||||
 | 
							chat = &db.Chat{
 | 
				
			||||||
 | 
								Item:    tongo.NewID(),
 | 
				
			||||||
 | 
								ChatId:  m.Chat.ID,
 | 
				
			||||||
 | 
								Title:   m.Chat.Title,
 | 
				
			||||||
 | 
								TopicId: 0,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = store.InsertOne(ctx, chat)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Print(err)
 | 
							log.Print(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func setTopic(b *bot, update *tb.Update) error {
 | 
					func setTopic(b *bot, update *echotron.Update) error {
 | 
				
			||||||
	m := update.Message
 | 
						m := update.Message
 | 
				
			||||||
	d := db.GetDatabase()
 | 
					 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 | 
						ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 | 
				
			||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	chat, err := d.GetChat(ctx, m.Chat.ID)
 | 
						store := tongo.NewStore[db.Chat](Client)
 | 
				
			||||||
 | 
						chat, err := store.GetOne(ctx, tongo.E("chat_id", m.Chat.ID))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	upd := bson.D{{Key: "$set", Value: bson.D{{Key: "topic_id", Value: m.ThreadID}}}}
 | 
						chat.TopicId = int64(m.ThreadID)
 | 
				
			||||||
 | 
						// upd := bson.D{{Key: "$set", Value: bson.D{{Key: "topic_id", Value: m.ThreadID}}}}
 | 
				
			||||||
	b.CaptchaTopic = int64(m.ThreadID)
 | 
						b.CaptchaTopic = int64(m.ThreadID)
 | 
				
			||||||
	err = d.UpdateChat(ctx, chat, upd)
 | 
						err = store.ReplaceItem(ctx, *chat, false)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	b.DeleteMessage(m.Chat.ID, m.ID)
 | 
						b.DeleteMessage(m.Chat.ID, m.ID)
 | 
				
			||||||
	b.SendMessage("Данный топик выбран в качестве проверочного для пользователей", m.Chat.ID, &tb.MessageOptions{MessageThreadID: m.ThreadID})
 | 
						b.SendMessage("Данный топик выбран в качестве проверочного для пользователей", m.Chat.ID, &echotron.MessageOptions{MessageThreadID: m.ThreadID})
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,17 +7,20 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tb "github.com/NicoNex/echotron/v3"
 | 
						"git.nefrace.ru/nefrace/tongo"
 | 
				
			||||||
 | 
						"github.com/NicoNex/echotron/v3"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var Client *tongo.Database
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type bot struct {
 | 
					type bot struct {
 | 
				
			||||||
	chatID       int64
 | 
						chatID       int64
 | 
				
			||||||
	CaptchaTopic int64
 | 
						CaptchaTopic int64
 | 
				
			||||||
	Me           *tb.User
 | 
						Me           *echotron.User
 | 
				
			||||||
	tb.API
 | 
						echotron.API
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *bot) Update(update *tb.Update) {
 | 
					func (b *bot) Update(update *echotron.Update) {
 | 
				
			||||||
	if update.Message != nil {
 | 
						if update.Message != nil {
 | 
				
			||||||
		if len(update.Message.NewChatMembers) != 0 {
 | 
							if len(update.Message.NewChatMembers) != 0 {
 | 
				
			||||||
			for _, user := range update.Message.NewChatMembers {
 | 
								for _, user := range update.Message.NewChatMembers {
 | 
				
			||||||
@ -45,31 +48,34 @@ func (b *bot) Update(update *tb.Update) {
 | 
				
			|||||||
// Базовая структура для бота
 | 
					// Базовая структура для бота
 | 
				
			||||||
type Kicker struct {
 | 
					type Kicker struct {
 | 
				
			||||||
	Token      string
 | 
						Token      string
 | 
				
			||||||
	Dispatcher *tb.Dispatcher
 | 
						Dispatcher *echotron.Dispatcher
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *Kicker) NewBot(chatID int64) tb.Bot {
 | 
					func (b *Kicker) NewBot(chatID int64) echotron.Bot {
 | 
				
			||||||
	d := db.GetDatabase()
 | 
						store := tongo.NewStore[db.Chat](Client)
 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 | 
						ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 | 
				
			||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	chat := db.Chat{
 | 
					
 | 
				
			||||||
		Id:      chatID,
 | 
						chat, err := store.GetOne(ctx, tongo.E("chat_id", chatID))
 | 
				
			||||||
		Title:   "",
 | 
						if err != nil {
 | 
				
			||||||
		TopicId: 0,
 | 
							chat = &db.Chat{
 | 
				
			||||||
	}
 | 
								Item:    tongo.NewID(),
 | 
				
			||||||
	if !d.ChatExists(ctx, chat) {
 | 
								ChatId:  chatID,
 | 
				
			||||||
		if err := d.NewChat(ctx, chat); err != nil {
 | 
								Title:   "",
 | 
				
			||||||
 | 
								TopicId: 0,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if _, err := store.InsertOne(ctx, chat); err != nil {
 | 
				
			||||||
			return &bot{}
 | 
								return &bot{}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	chat, _ = d.GetChat(ctx, chatID)
 | 
					 | 
				
			||||||
	CaptchaTopic := chat.TopicId
 | 
						CaptchaTopic := chat.TopicId
 | 
				
			||||||
	result := &bot{
 | 
						result := &bot{
 | 
				
			||||||
		chatID,
 | 
							chatID,
 | 
				
			||||||
		CaptchaTopic,
 | 
							CaptchaTopic,
 | 
				
			||||||
		nil,
 | 
							nil,
 | 
				
			||||||
		tb.NewAPI(b.Token),
 | 
							echotron.NewAPI(b.Token),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						log.Println("New bot created with CaptchaTopic", result.CaptchaTopic)
 | 
				
			||||||
	me, err := result.GetMe()
 | 
						me, err := result.GetMe()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Println(err)
 | 
							log.Println(err)
 | 
				
			||||||
@ -81,7 +87,7 @@ func (b *Kicker) NewBot(chatID int64) tb.Bot {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Initialize bot with token
 | 
					// Initialize bot with token
 | 
				
			||||||
func (b *Kicker) Init() error {
 | 
					func (b *Kicker) Init() error {
 | 
				
			||||||
	dsp := tb.NewDispatcher(b.Token, b.NewBot)
 | 
						dsp := echotron.NewDispatcher(b.Token, b.NewBot)
 | 
				
			||||||
	b.Dispatcher = dsp
 | 
						b.Dispatcher = dsp
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -90,14 +96,14 @@ func (b *Kicker) Start() error {
 | 
				
			|||||||
	return b.Dispatcher.Poll()
 | 
						return b.Dispatcher.Poll()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func EscapeText(parseMode tb.ParseMode, text string) string {
 | 
					func EscapeText(parseMode echotron.ParseMode, text string) string {
 | 
				
			||||||
	var replacer *strings.Replacer
 | 
						var replacer *strings.Replacer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if parseMode == tb.HTML {
 | 
						if parseMode == echotron.HTML {
 | 
				
			||||||
		replacer = strings.NewReplacer("<", "<", ">", ">", "&", "&")
 | 
							replacer = strings.NewReplacer("<", "<", ">", ">", "&", "&")
 | 
				
			||||||
	} else if parseMode == tb.Markdown {
 | 
						} else if parseMode == echotron.Markdown {
 | 
				
			||||||
		replacer = strings.NewReplacer("_", "\\_", "*", "\\*", "`", "\\`", "[", "\\[")
 | 
							replacer = strings.NewReplacer("_", "\\_", "*", "\\*", "`", "\\`", "[", "\\[")
 | 
				
			||||||
	} else if parseMode == tb.MarkdownV2 {
 | 
						} else if parseMode == echotron.MarkdownV2 {
 | 
				
			||||||
		replacer = strings.NewReplacer(
 | 
							replacer = strings.NewReplacer(
 | 
				
			||||||
			"_", "\\_", "*", "\\*", "[", "\\[", "]", "\\]", "(",
 | 
								"_", "\\_", "*", "\\*", "[", "\\[", "]", "\\]", "(",
 | 
				
			||||||
			"\\(", ")", "\\)", "~", "\\~", "`", "\\`", ">", "\\>",
 | 
								"\\(", ")", "\\)", "~", "\\~", "`", "\\`", ">", "\\>",
 | 
				
			||||||
@ -110,3 +116,8 @@ func EscapeText(parseMode tb.ParseMode, text string) string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return replacer.Replace(text)
 | 
						return replacer.Replace(text)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func waitAndDelete(b *echotron.API, message *echotron.Message, t time.Duration) {
 | 
				
			||||||
 | 
						time.Sleep(t)
 | 
				
			||||||
 | 
						b.DeleteMessage(message.Chat.ID, message.ID)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,43 +2,67 @@ package kicker
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"kickerbot/db"
 | 
						"kickerbot/db"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tb "github.com/NicoNex/echotron/v3"
 | 
						"git.nefrace.ru/nefrace/tongo"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson"
 | 
						"github.com/NicoNex/echotron/v3"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson/primitive"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type TaskBot struct {
 | 
					type TaskBot struct {
 | 
				
			||||||
	Token string
 | 
						Token string
 | 
				
			||||||
	tb.API
 | 
						echotron.API
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TaskKickOldUsers(b *tb.API) {
 | 
					func TaskKickOldUsers(b *echotron.API) {
 | 
				
			||||||
	d := db.GetDatabase()
 | 
					 | 
				
			||||||
	log.Print("STARTING KICKING TASK")
 | 
					 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
 | 
						ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
 | 
				
			||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	now := time.Now().Unix()
 | 
						now := time.Now()
 | 
				
			||||||
	old := now - 120
 | 
						old := now.Add(-10 * time.Minute)
 | 
				
			||||||
	filter := bson.D{
 | 
						store := tongo.NewStore[db.User](Client)
 | 
				
			||||||
		primitive.E{Key: "date_joined", Value: bson.D{bson.E{Key: "$lt", Value: old}}},
 | 
						users, err := store.GetMany(ctx, tongo.E("date_joined", tongo.D(tongo.E("$lt", old))))
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	users, err := d.GetUsers(ctx, filter)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Printf("Error in deleting task: %v", err)
 | 
							log.Printf("Error in deleting task: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, user := range users {
 | 
						for _, user := range users {
 | 
				
			||||||
 | 
							_, err := b.BanChatMember(user.ChatId, user.UserId, &echotron.BanOptions{RevokeMessages: true})
 | 
				
			||||||
		_, err := b.BanChatMember(user.ChatId, user.Id, &tb.BanOptions{RevokeMessages: true})
 | 
					 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.Println("User was not banned: ", err)
 | 
								log.Println("User was not banned: ", err)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							log.Printf("User %s was banned", user.Id)
 | 
				
			||||||
		b.DeleteMessage(user.ChatId, user.CaptchaMessage)
 | 
							b.DeleteMessage(user.ChatId, user.CaptchaMessage)
 | 
				
			||||||
		b.DeleteMessage(user.ChatId, user.JoinedMessage)
 | 
							b.DeleteMessage(user.ChatId, user.JoinedMessage)
 | 
				
			||||||
		d.RemoveUser(ctx, user)
 | 
							store.DeleteByID(ctx, user.Id)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TaskNotifyUsers(b *echotron.API) {
 | 
				
			||||||
 | 
						ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
 | 
				
			||||||
 | 
						defer cancel()
 | 
				
			||||||
 | 
						store := tongo.NewStore[db.User](Client)
 | 
				
			||||||
 | 
						chatStore := tongo.NewStore[db.Chat](Client)
 | 
				
			||||||
 | 
						users, _ := store.GetMany(ctx)
 | 
				
			||||||
 | 
						for _, user := range users {
 | 
				
			||||||
 | 
							if time.Since(user.LastNotification) > 2*time.Minute {
 | 
				
			||||||
 | 
								user.LastNotification = time.Now()
 | 
				
			||||||
 | 
								text := fmt.Sprintf("*[%s](tg://user?id=%d)*, напоминаю, что тебе необходимо пройти капчу\\!", EscapeText(echotron.MarkdownV2, user.FirstName), user.Id)
 | 
				
			||||||
 | 
								store.ReplaceItem(ctx, *user, false)
 | 
				
			||||||
 | 
								chat, err := chatStore.GetOne(ctx, tongo.E("chat_id", user.ChatId))
 | 
				
			||||||
 | 
								topic := 0
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Printf("Can't get chat from user: %s", err)
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									topic = int(chat.TopicId)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								res, err := b.SendMessage(text, user.ChatId, &echotron.MessageOptions{MessageThreadID: topic, ParseMode: echotron.MarkdownV2})
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Printf("Can't send notification to user: %s", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								go waitAndDelete(b, res.Result, 2*time.Minute)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								main.go
									
									
									
									
									
								
							@ -2,17 +2,19 @@ package main
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"kickerbot/captchagen"
 | 
						"kickerbot/captchagen"
 | 
				
			||||||
	"kickerbot/db"
 | 
					 | 
				
			||||||
	"kickerbot/kicker"
 | 
						"kickerbot/kicker"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"git.nefrace.ru/nefrace/tongo"
 | 
				
			||||||
	"github.com/NicoNex/echotron/v3"
 | 
						"github.com/NicoNex/echotron/v3"
 | 
				
			||||||
	"github.com/go-co-op/gocron"
 | 
						"github.com/go-co-op/gocron"
 | 
				
			||||||
	"github.com/joho/godotenv"
 | 
						"github.com/joho/godotenv"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var client *tongo.Database
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	err := godotenv.Load()
 | 
						err := godotenv.Load()
 | 
				
			||||||
	captchagen.Init()
 | 
						captchagen.Init()
 | 
				
			||||||
@ -23,16 +25,19 @@ func main() {
 | 
				
			|||||||
	if !exists {
 | 
						if !exists {
 | 
				
			||||||
		log.Fatal("no token specified")
 | 
							log.Fatal("no token specified")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_, dberr := db.Init(os.Getenv("MONGO_URI"))
 | 
						client, err = tongo.NewConnection(os.Getenv("MONGO_URI"), "godotkicker")
 | 
				
			||||||
	if dberr != nil {
 | 
						// _, dberr := db.Init(os.Getenv("MONGO_URI"))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
		log.Fatal(err)
 | 
							log.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						kicker.Client = client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Bot := kicker.Kicker{Token: token}
 | 
						Bot := kicker.Kicker{Token: token}
 | 
				
			||||||
	Bot.Init()
 | 
						Bot.Init()
 | 
				
			||||||
	scheduler := gocron.NewScheduler(time.UTC)
 | 
						scheduler := gocron.NewScheduler(time.UTC)
 | 
				
			||||||
	tasker := echotron.NewAPI(token)
 | 
						tasker := echotron.NewAPI(token)
 | 
				
			||||||
	scheduler.Every(30).Seconds().Do(func() { kicker.TaskKickOldUsers(&tasker) })
 | 
						scheduler.Every(30).Seconds().Do(func() { kicker.TaskKickOldUsers(&tasker) })
 | 
				
			||||||
 | 
						scheduler.Every(30).Seconds().Do(func() { kicker.TaskNotifyUsers(&tasker) })
 | 
				
			||||||
	scheduler.StartAsync()
 | 
						scheduler.StartAsync()
 | 
				
			||||||
	Bot.Start()
 | 
						Bot.Start()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user