Scaffolding for new captcha type
This commit is contained in:
parent
aadc6e8a03
commit
beeafa141a
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-telegram/bot"
|
||||
"github.com/go-telegram/bot/models"
|
||||
|
@ -38,3 +39,7 @@ func FetchMemberFromChat(ctx context.Context, b *bot.Bot, chatID int64, userID i
|
|||
func IsAdmin(member models.ChatMember) bool {
|
||||
return member.Administrator != nil || member.Owner != nil
|
||||
}
|
||||
|
||||
func DeleteAfterSeconds(chatID int64, msgID int, seconds int) error {
|
||||
return AddMessageToDelete(MessageToDelete{MessageId: msgID, ChatId: chatID, DeleteDate: time.Now().Add(time.Duration(seconds) * time.Second).Unix(), Tries: 0})
|
||||
}
|
||||
|
|
16
src/db.go
16
src/db.go
|
@ -27,7 +27,8 @@ create table if not exists messagesToDelete
|
|||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
message_id INTEGER,
|
||||
chat_id INTEGER,
|
||||
delete_date INTEGER
|
||||
delete_date INTEGER,
|
||||
tries INTEGER
|
||||
);
|
||||
|
||||
create table if not exists users
|
||||
|
@ -71,6 +72,7 @@ type MessageToDelete struct {
|
|||
MessageId int `db:"message_id"`
|
||||
ChatId int64 `db:"chat_id"`
|
||||
DeleteDate int64 `db:"delete_date"`
|
||||
Tries int `db:"tries"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
|
@ -79,6 +81,14 @@ type User struct {
|
|||
Username string `db:"username"`
|
||||
}
|
||||
|
||||
type Captcha struct {
|
||||
Id int64 `db:"id"`
|
||||
UserID int64 `db:"user_id"`
|
||||
ChatID int64 `db:"chat_id"`
|
||||
MessageID int `db:"message_id"`
|
||||
CorrectAnswer int `db:"correct_answer"`
|
||||
}
|
||||
|
||||
var db *sqlx.DB
|
||||
|
||||
func InitDb() error {
|
||||
|
@ -127,7 +137,7 @@ func NewActivation(code string) error {
|
|||
|
||||
func UseActivation(code string) bool {
|
||||
exists := false
|
||||
err := db.Get(&exists, `SELECT exists(SELECT 1 FROM chats WHERE code = $1);`, code)
|
||||
err := db.Get(&exists, `SELECT exists(SELECT 1 FROM activations WHERE code = $1);`, code)
|
||||
if err != nil || !exists {
|
||||
return false
|
||||
}
|
||||
|
@ -141,7 +151,7 @@ func ActivateChat(id int64) error {
|
|||
}
|
||||
|
||||
func AddMessageToDelete(msg MessageToDelete) error {
|
||||
_, err := db.NamedExec(`insert into messagesToDelete (message_id, chat_id, delete_date) values (:message_id, :chat_id, :delete_date)`, msg)
|
||||
_, err := db.NamedExec(`insert into messagesToDelete (message_id, chat_id, delete_date, tries) values (:message_id, :chat_id, :delete_date, 0)`, msg)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,12 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-telegram/bot"
|
||||
"github.com/go-telegram/bot/models"
|
||||
|
@ -15,6 +18,9 @@ func defaultHandler(ctx context.Context, b *bot.Bot, update *models.Update) {
|
|||
// ChatID: update.Message.Chat.ID,
|
||||
// Text: "hello!",
|
||||
// })
|
||||
if update.Message != nil {
|
||||
log.Println(update.Message.Text)
|
||||
}
|
||||
log.Println(*update)
|
||||
}
|
||||
|
||||
|
@ -33,7 +39,7 @@ func registerChat(ctx context.Context, b *bot.Bot, update *models.Update) {
|
|||
return
|
||||
}
|
||||
if !UseActivation(args[1]) {
|
||||
log.Println("register: wrong code")
|
||||
log.Println("register: wrong code: ", args[1])
|
||||
return
|
||||
}
|
||||
if err := ActivateChat(msg.Chat.ID); err != nil {
|
||||
|
@ -43,7 +49,7 @@ func registerChat(ctx context.Context, b *bot.Bot, update *models.Update) {
|
|||
b.DeleteMessage(ctx, &bot.DeleteMessageParams{ChatID: msg.Chat.ID, MessageID: msg.ID})
|
||||
sent, err := b.SendMessage(ctx, &bot.SendMessageParams{ChatID: msg.Chat.ID, Text: "Чат зарегистрирован", MessageThreadID: msg.MessageThreadID})
|
||||
if err == nil {
|
||||
err := AddMessageToDelete(MessageToDelete{MessageId: sent.ID, ChatId: msg.Chat.ID, DeleteDate: time.Now().Add(1 * time.Minute).Unix()})
|
||||
err := DeleteAfterSeconds(msg.Chat.ID, sent.ID, 60)
|
||||
if err != nil {
|
||||
log.Println("register: failed to add to delete", err)
|
||||
}
|
||||
|
@ -55,10 +61,79 @@ func registerChat(ctx context.Context, b *bot.Bot, update *models.Update) {
|
|||
|
||||
func handleNewJoined(ctx context.Context, b *bot.Bot, u *models.Update) {
|
||||
for _, user := range u.Message.NewChatMembers {
|
||||
log.Println(user)
|
||||
_, err := db.Exec(`INSERT INTO captchas (user_id, chat_id, message_id, correct_answer) values ($1, $2, 0, 0)`, user.ID, u.Message.Chat.ID)
|
||||
if err != nil {
|
||||
log.Println("newusers: can't add to db: ", err)
|
||||
}
|
||||
b.SendMessage(ctx, &bot.SendMessageParams{
|
||||
ChatID: u.Message.Chat.ID,
|
||||
Text: "Check the capthca!",
|
||||
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"},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func banUser(ctx context.Context, b *bot.Bot, u *models.Update) {
|
||||
|
||||
}
|
||||
|
||||
func handlePrivateStartCaptcha(ctx context.Context, b *bot.Bot, u *models.Update) {
|
||||
args := strings.Split(u.Message.Text, " ")
|
||||
userID := u.Message.From.ID
|
||||
chatID := 0
|
||||
if len(args) > 1 {
|
||||
chat_str := strings.TrimPrefix(args[1], "cap_")
|
||||
id, err := strconv.Atoi(chat_str)
|
||||
if err == nil {
|
||||
chatID = id
|
||||
}
|
||||
}
|
||||
|
||||
captcha := Captcha{}
|
||||
var err error
|
||||
if chatID != 0 {
|
||||
err = db.Get(&captcha, `select * from captchas where user_id = $1 and chat_id = $2`, userID, chatID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
b.SendMessage(ctx, &bot.SendMessageParams{
|
||||
Text: " There's no captchas for that chat you came from.",
|
||||
ChatID: u.Message.Chat.ID,
|
||||
})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
err = db.Get(&captcha, `select * from captchas where user_id = $1 and correct_answer != 0`, userID)
|
||||
if err != nil {
|
||||
b.SendMessage(ctx, &bot.SendMessageParams{
|
||||
Text: " There's no captchas for that chat you came from.",
|
||||
ChatID: u.Message.Chat.ID,
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if captcha.CorrectAnswer == 0 {
|
||||
captcha.CorrectAnswer = 42
|
||||
msg, err := b.SendMessage(ctx, &bot.SendMessageParams{
|
||||
Text: "Get me the answer!",
|
||||
ChatID: u.Message.Chat.ID,
|
||||
})
|
||||
if err == nil {
|
||||
captcha.MessageID = msg.ID
|
||||
}
|
||||
_, err = db.NamedExec("update captchas set correct_answer = :correct_answer, message_id = :message_id where id = :id", captcha)
|
||||
if err != nil {
|
||||
log.Println("Can't update captcha:", err)
|
||||
}
|
||||
} else {
|
||||
b.SendMessage(ctx, &bot.SendMessageParams{
|
||||
Text: fmt.Sprintf("You already have captcha for chat %d", captcha.ChatID),
|
||||
ChatID: u.Message.Chat.ID,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
43
src/main.go
43
src/main.go
|
@ -2,8 +2,11 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
_ "github.com/glebarez/go-sqlite"
|
||||
"github.com/go-telegram/bot"
|
||||
|
@ -36,5 +39,45 @@ func main() {
|
|||
b.RegisterHandlerMatchFunc(func(update *models.Update) bool {
|
||||
return update.Message != nil && len(update.Message.NewChatMembers) > 0
|
||||
}, handleNewJoined)
|
||||
b.RegisterHandlerMatchFunc(func(update *models.Update) bool {
|
||||
return update.Message != nil && update.Message.Chat.Type == "private" && strings.HasPrefix(update.Message.Text, "/start")
|
||||
}, handlePrivateStartCaptcha)
|
||||
|
||||
go timedTask(ctx, b)
|
||||
|
||||
b.Start(ctx)
|
||||
}
|
||||
|
||||
func timedTask(ctx context.Context, b *bot.Bot) {
|
||||
timer := time.NewTicker(time.Second * 30)
|
||||
|
||||
task:
|
||||
for {
|
||||
select {
|
||||
case <-timer.C:
|
||||
deleteOldMessages(ctx, b)
|
||||
case <-ctx.Done():
|
||||
break task
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func deleteOldMessages(ctx context.Context, b *bot.Bot) {
|
||||
now := time.Now().Unix()
|
||||
messages := []MessageToDelete{}
|
||||
err := db.Select(&messages, `SELECT * from messagesToDelete WHERE delete_date < $1`, now)
|
||||
if err != nil {
|
||||
log.Println("delete_old: can't get messages: ", err)
|
||||
}
|
||||
for _, message := range messages {
|
||||
success, err := b.DeleteMessage(ctx, &bot.DeleteMessageParams{ChatID: message.ChatId, MessageID: message.MessageId})
|
||||
if !success {
|
||||
log.Println("delete_old, message wasn't deleted: ", message.MessageId, " :: ", err)
|
||||
db.Exec(`UPDATE messagesToDelete set tries = tries + 1 where id = $1`, message.Id)
|
||||
if message.Tries < 3 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
db.Exec(`DELETE FROM messagesToDelete WHERE id = $1`, message.Id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ func checkRegistered(next bot.HandlerFunc) bot.HandlerFunc {
|
|||
}
|
||||
chat := update.Message.Chat
|
||||
if chat.Type == "private" {
|
||||
next(ctx, b, update)
|
||||
return
|
||||
}
|
||||
if !IsChatActive(chat.ID) && !strings.HasPrefix(update.Message.Text, "/register") {
|
||||
|
|
Loading…
Reference in New Issue