From c5490d64a3053b65f6e3a07b2d324106f6977eb1 Mon Sep 17 00:00:00 2001 From: Nefrace Date: Sun, 25 Aug 2024 13:30:53 +0300 Subject: [PATCH] Allowing resending captcha --- .gitignore | 3 ++- go.mod | 1 + go.sum | 2 ++ src/captcha.go | 10 ++++++++-- src/db.go | 4 +++- src/handlers.go | 50 +++++++++++++++++++++++++++++++++++++++---------- src/main.go | 14 ++++++++++++++ 7 files changed, 70 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index f8b17d8..d71e45a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ bot.db .env -.vscode \ No newline at end of file +.vscode +kickbot diff --git a/go.mod b/go.mod index b121db9..7de66ae 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/google/uuid v1.5.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jmoiron/sqlx v1.4.0 // indirect + github.com/joho/godotenv v1.5.1 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/spf13/cobra v0.0.5 // indirect diff --git a/go.sum b/go.sum index 8013038..d4a590e 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= diff --git a/src/captcha.go b/src/captcha.go index b30353b..c3cf18c 100644 --- a/src/captcha.go +++ b/src/captcha.go @@ -68,7 +68,7 @@ func InitResources() { } -func GenCaptcha() ([]byte, string) { +func GenCaptcha(answer string) ([]byte, string) { width, height := 500.0, 500.0 ctx := gg.NewContext(int(width), int(height)) // Make gradient @@ -91,9 +91,15 @@ func GenCaptcha() ([]byte, string) { items := []Item{} for i, image := range Images { + var code string + if i == CorrectImage { + code = answer + } else { + code = generateRandomDigits(4) + } items = append(items, Item{ img: image, - code: generateRandomDigits(4), + code: code, correct: i == CorrectImage, }) } diff --git a/src/db.go b/src/db.go index 8f4d5cc..8f23492 100644 --- a/src/db.go +++ b/src/db.go @@ -13,7 +13,8 @@ id INTEGER PRIMARY KEY, name TEXT NOT NULL, username TEXT DEFAULT '', topic INTEGER DEFAULT 0, -active INTEGER DEFAULT 0 +active INTEGER DEFAULT 0, +rules_msg TEXT DEFAULT '' ); create table if not exists activations @@ -79,6 +80,7 @@ type Chat struct { Username string `json:"username" db:"username"` Topic int `json:"topic" db:"topic"` Active bool `json:"active" db:"active"` + RulesMsg string `json:"rules_msg" db:"rules_msg"` } type MessageToDelete struct { diff --git a/src/handlers.go b/src/handlers.go index beff811..33c586b 100644 --- a/src/handlers.go +++ b/src/handlers.go @@ -106,6 +106,10 @@ var NewUserTemplate = ` func handleNewJoined(ctx context.Context, b *bot.Bot, u *models.Update) { var chat Chat + b.DeleteMessage(ctx, &bot.DeleteMessageParams{ + ChatID: u.Message.Chat.ID, + MessageID: u.Message.ID, + }) err := db.Get(&chat, "select * from chats where id = $1 and active = 1", u.Message.Chat.ID) if err != nil { log.Println("can't get chat for new joined: ", err) @@ -120,7 +124,7 @@ func handleNewJoined(ctx context.Context, b *bot.Bot, u *models.Update) { ReplyMarkup: models.InlineKeyboardMarkup{ InlineKeyboard: [][]models.InlineKeyboardButton{ { - {URL: fmt.Sprintf("https://t.me/nefrace_php_test_bot?start=cap_%d", u.Message.Chat.ID), Text: "Check"}, + {URL: fmt.Sprintf("https://t.me/%s?start=cap_%d", BOT_NAME, u.Message.Chat.ID), Text: "Check"}, }, }, }, @@ -255,6 +259,7 @@ var NewCaptchaTemplate = ` func handlePrivateStartCaptcha(ctx context.Context, b *bot.Bot, u *models.Update) { args := strings.Split(u.Message.Text, " ") + log.Println(u.Message.From.FirstName, u.Message.Text) userID := u.Message.From.ID chatID := 0 if len(args) > 1 { @@ -307,10 +312,10 @@ WHERE captchas.id = $1`, captcha.Id) } if captcha.CorrectAnswer == "" { - img, answer := GenCaptcha() + img, answer := GenCaptcha(generateRandomDigits(4)) captcha.CorrectAnswer = answer if _, err := b.SendPhoto(ctx, &bot.SendPhotoParams{ - Caption: fmt.Sprintf(NewCaptchaTemplate, userchat.UserName, userchat.ChatName), + Caption: fmt.Sprintf(NewCaptchaTemplate, bot.EscapeMarkdown(userchat.UserName), bot.EscapeMarkdown(userchat.ChatName)), Photo: &models.InputFileUpload{Filename: "captcha.png", Data: bytes.NewReader(img)}, ChatID: u.Message.Chat.ID, ParseMode: models.ParseModeMarkdown, @@ -322,10 +327,15 @@ WHERE captchas.id = $1`, captcha.Id) log.Println("Can't update captcha:", err) } } else { - b.SendMessage(ctx, &bot.SendMessageParams{ - Text: fmt.Sprintf("Я тебе уже выдавал капчу для %d", captcha.ChatID), - ChatID: u.Message.Chat.ID, - }) + img, _ := GenCaptcha(captcha.CorrectAnswer) + if _, err := b.SendPhoto(ctx, &bot.SendPhotoParams{ + Caption: fmt.Sprintf(NewCaptchaTemplate, bot.EscapeMarkdown(userchat.UserName), bot.EscapeMarkdown(userchat.ChatName)), + Photo: &models.InputFileUpload{Filename: "captcha.png", Data: bytes.NewReader(img)}, + ChatID: u.Message.Chat.ID, + ParseMode: models.ParseModeMarkdown, + }); err != nil { + log.Println("can't send private captcha: ", err) + } } } @@ -388,8 +398,28 @@ func handlePrivateCaptcha(ctx context.Context, b *bot.Bot, u *models.Update) { log.Println("Deleting message:", result, err) db.Exec("delete from captchas where id = $1", captcha.Id) - b.SendMessage(ctx, &bot.SendMessageParams{ - Text: "Капча решена! Поздравляю! Теперь можешь вернуться в чат, я вернул тебе возможность отправлять там сообщения.\n\nСоветую ознакомиться с местными правилами, прежде чем что-либо писать!", - ChatID: msg.From.ID, + congrats := ` +Капча решена, поздравляю\! +Теперь можешь вернуться в чат, я вернул тебе возможность отправлять там сообщения\. +` + rulesText := `Советую ознакомиться с местными [правилами](%s), прежде чем что\-либо писать\!` + fullCongrats := congrats + + var chat Chat + err = db.Get(&chat, "select * from chats where id = $1", captcha.ChatID) + if err == nil { + if chat.RulesMsg != "" { + rules := fmt.Sprintf(rulesText, chat.RulesMsg) + fullCongrats = fmt.Sprintf("%s\n\n%s", congrats, rules) + } + } + + _, err = b.SendMessage(ctx, &bot.SendMessageParams{ + Text: fullCongrats, + ParseMode: models.ParseModeMarkdown, + ChatID: msg.From.ID, }) + if err != nil { + log.Println("Can't send congrats: ", err, "\n===\n", fullCongrats) + } } diff --git a/src/main.go b/src/main.go index 89914d8..16b9047 100644 --- a/src/main.go +++ b/src/main.go @@ -11,11 +11,19 @@ import ( _ "github.com/glebarez/go-sqlite" "github.com/go-telegram/bot" "github.com/go-telegram/bot/models" + "github.com/joho/godotenv" ) +var BOT_NAME string + func main() { log.SetFlags(log.Lshortfile + log.Ltime + log.Ldate) InitResources() + err := godotenv.Load() + if err != nil { + log.Println("No .env loaded. Relying on existing variables") + } + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() @@ -35,6 +43,12 @@ func main() { if err != nil { panic(err) } + me, err := b.GetMe(ctx) + if err != nil { + log.Fatalf("Can't get me: %v", err) + } + BOT_NAME = me.Username + log.Println("Using name", BOT_NAME) b.RegisterHandler(bot.HandlerTypeMessageText, "/register", bot.MatchTypePrefix, registerChat) b.RegisterHandler(bot.HandlerTypeMessageText, "/unregister", bot.MatchTypePrefix, unregisterChat)