init
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
 | 
			
		||||
bot.db
 | 
			
		||||
.env
 | 
			
		||||
.vscode
 | 
			
		||||
							
								
								
									
										22
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
module nefrace.ru/kickbot.ng
 | 
			
		||||
 | 
			
		||||
go 1.22.5
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/dustin/go-humanize v1.0.1 // indirect
 | 
			
		||||
	github.com/fogleman/gg v1.3.0 // indirect
 | 
			
		||||
	github.com/glebarez/go-sqlite v1.22.0 // indirect
 | 
			
		||||
	github.com/go-telegram/bot v1.5.0 // indirect
 | 
			
		||||
	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
 | 
			
		||||
	github.com/google/uuid v1.5.0 // indirect
 | 
			
		||||
	github.com/jmoiron/sqlx v1.4.0 // indirect
 | 
			
		||||
	github.com/mattn/go-isatty v0.0.20 // indirect
 | 
			
		||||
	github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
 | 
			
		||||
	go.etcd.io/bbolt v1.3.10 // indirect
 | 
			
		||||
	golang.org/x/image v0.18.0 // indirect
 | 
			
		||||
	golang.org/x/sys v0.15.0 // indirect
 | 
			
		||||
	modernc.org/libc v1.37.6 // indirect
 | 
			
		||||
	modernc.org/mathutil v1.6.0 // indirect
 | 
			
		||||
	modernc.org/memory v1.7.2 // indirect
 | 
			
		||||
	modernc.org/sqlite v1.28.0 // indirect
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										39
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
 | 
			
		||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
 | 
			
		||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
 | 
			
		||||
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
 | 
			
		||||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
 | 
			
		||||
github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
 | 
			
		||||
github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=
 | 
			
		||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
 | 
			
		||||
github.com/go-telegram/bot v1.5.0 h1:q31yJ8iajFG54b17TgSs/Brl2YkWziRjf4Au5pe3xV0=
 | 
			
		||||
github.com/go-telegram/bot v1.5.0/go.mod h1:i2TRs7fXWIeaceF3z7KzsMt/he0TwkVC680mvdTFYeM=
 | 
			
		||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
 | 
			
		||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
 | 
			
		||||
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
 | 
			
		||||
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 | 
			
		||||
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
 | 
			
		||||
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
 | 
			
		||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 | 
			
		||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
 | 
			
		||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 | 
			
		||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 | 
			
		||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
 | 
			
		||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
 | 
			
		||||
go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0=
 | 
			
		||||
go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ=
 | 
			
		||||
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
 | 
			
		||||
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
 | 
			
		||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
 | 
			
		||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
 | 
			
		||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
			
		||||
modernc.org/libc v1.37.6 h1:orZH3c5wmhIQFTXF+Nt+eeauyd+ZIt2BX6ARe+kD+aw=
 | 
			
		||||
modernc.org/libc v1.37.6/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE=
 | 
			
		||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
 | 
			
		||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
 | 
			
		||||
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
 | 
			
		||||
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
 | 
			
		||||
modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ=
 | 
			
		||||
modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0=
 | 
			
		||||
							
								
								
									
										40
									
								
								src/botutils.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/botutils.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/go-telegram/bot"
 | 
			
		||||
	"github.com/go-telegram/bot/models"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func GetChatFullName(chat models.Chat) string {
 | 
			
		||||
	if chat.Title != "" {
 | 
			
		||||
		return chat.Title
 | 
			
		||||
	}
 | 
			
		||||
	if chat.FirstName != "" {
 | 
			
		||||
		if chat.LastName != "" {
 | 
			
		||||
			return fmt.Sprint(chat.FirstName, " ", chat.LastName)
 | 
			
		||||
		}
 | 
			
		||||
		return chat.FirstName
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetUserFullName(user models.User) string {
 | 
			
		||||
	if user.FirstName != "" {
 | 
			
		||||
		if user.LastName != "" {
 | 
			
		||||
			return fmt.Sprint(user.FirstName, " ", user.LastName)
 | 
			
		||||
		}
 | 
			
		||||
		return user.FirstName
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func FetchMemberFromChat(ctx context.Context, b *bot.Bot, chatID int64, userID int64) (*models.ChatMember, error) {
 | 
			
		||||
	return b.GetChatMember(ctx, &bot.GetChatMemberParams{ChatID: chatID, UserID: userID})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IsAdmin(member models.ChatMember) bool {
 | 
			
		||||
	return member.Administrator != nil || member.Owner != nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										162
									
								
								src/db.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								src/db.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,162 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"log"
 | 
			
		||||
 | 
			
		||||
	"github.com/jmoiron/sqlx"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var schema = `
 | 
			
		||||
create table if not exists chats
 | 
			
		||||
(
 | 
			
		||||
id INTEGER PRIMARY KEY,
 | 
			
		||||
name TEXT,
 | 
			
		||||
username TEXT,
 | 
			
		||||
topic INTEGER,
 | 
			
		||||
active INTEGER
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
create table if not exists activations
 | 
			
		||||
(
 | 
			
		||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
 | 
			
		||||
code TEXT
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
create table if not exists messagesToDelete
 | 
			
		||||
(
 | 
			
		||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
 | 
			
		||||
message_id INTEGER,
 | 
			
		||||
chat_id INTEGER,
 | 
			
		||||
delete_date INTEGER
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
create table if not exists users
 | 
			
		||||
(
 | 
			
		||||
id INTEGER PRIMARY KEY,
 | 
			
		||||
name TEXT,
 | 
			
		||||
username TEXT
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
create table if not exists bans
 | 
			
		||||
(
 | 
			
		||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
 | 
			
		||||
user_id INTEGER,
 | 
			
		||||
reason TEXT,
 | 
			
		||||
ban_date INTEGER,
 | 
			
		||||
unban_date INTEGER,
 | 
			
		||||
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
create table if not exists captchas
 | 
			
		||||
(
 | 
			
		||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
 | 
			
		||||
user_id INTEGER,
 | 
			
		||||
chat_id INTEGER,
 | 
			
		||||
message_id INTEGER,
 | 
			
		||||
correct_answer INTEGER,
 | 
			
		||||
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
 | 
			
		||||
)
 | 
			
		||||
`
 | 
			
		||||
 | 
			
		||||
type ChatSchema struct {
 | 
			
		||||
	Id       int64  `json:"id" db:"id"`
 | 
			
		||||
	Name     string `json:"name" db:"name"`
 | 
			
		||||
	Username string `json:"username" db:"username"`
 | 
			
		||||
	Topic    int64  `json:"topic" db:"topic"`
 | 
			
		||||
	Active   bool   `json:"active" db:"active"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type MessageToDelete struct {
 | 
			
		||||
	Id         int64 `db:"id"`
 | 
			
		||||
	MessageId  int   `db:"message_id"`
 | 
			
		||||
	ChatId     int64 `db:"chat_id"`
 | 
			
		||||
	DeleteDate int64 `db:"delete_date"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type User struct {
 | 
			
		||||
	Id       int64  `db:"id"`
 | 
			
		||||
	Name     string `db:"name"`
 | 
			
		||||
	Username string `db:"username"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var db *sqlx.DB
 | 
			
		||||
 | 
			
		||||
func InitDb() error {
 | 
			
		||||
	newdb, err := sqlx.Connect("sqlite", "./bot.db?_time_format=sqlite")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	db = newdb
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewChat(chat ChatSchema) error {
 | 
			
		||||
	_, err := db.NamedExec(`insert into chats (id, name, username, topic, active) values (:id, :name, :username, :topic, :active)`, chat)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IsChatExists(id int64) bool {
 | 
			
		||||
	var exists bool
 | 
			
		||||
	err := db.Get(&exists, `SELECT exists(SELECT 1 FROM chats WHERE id = $1);`, id)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Println("Can't check existing of chat", id, err)
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return exists
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IsChatActive(id int64) bool {
 | 
			
		||||
	var active bool
 | 
			
		||||
	err := db.Get(&active, `SELECT active from chats where id = $1`, id)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return active
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetChatById(id int64) (ChatSchema, error) {
 | 
			
		||||
	c := ChatSchema{}
 | 
			
		||||
	err := db.Get(&c, `select * from chats where id = $1`, id)
 | 
			
		||||
	return c, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewActivation(code string) error {
 | 
			
		||||
	_, err := db.Exec(`insert into activations (code) values ($1)`, code)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func UseActivation(code string) bool {
 | 
			
		||||
	_, err := db.Exec(`delete from activations where code = $1`, code)
 | 
			
		||||
	return err == nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ActivateChat(id int64) error {
 | 
			
		||||
	_, err := db.Exec(`update chats set active = 1 where id = $1`, id)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewUser(user User) error {
 | 
			
		||||
	_, err := db.NamedExec(`insert into users (id, name, username) values (:id, :name, :username)`, user)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IsUserExists(id int64) bool {
 | 
			
		||||
	var exists bool
 | 
			
		||||
	err := db.Get(&exists, `SELECT exists(SELECT 1 FROM users WHERE id = $1);`, id)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Println("Can't check existing of chat", id, err)
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return exists
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetUserById(id int64) (User, error) {
 | 
			
		||||
	c := User{}
 | 
			
		||||
	err := db.Get(&c, `select * from users where id = $1`, id)
 | 
			
		||||
	return c, err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								src/handlers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/handlers.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,64 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"log"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/go-telegram/bot"
 | 
			
		||||
	"github.com/go-telegram/bot/models"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func defaultHandler(ctx context.Context, b *bot.Bot, update *models.Update) {
 | 
			
		||||
	// b.SendMessage(ctx, &bot.SendMessageParams{
 | 
			
		||||
	// 	ChatID: update.Message.Chat.ID,
 | 
			
		||||
	// 	Text:   "hello!",
 | 
			
		||||
	// })
 | 
			
		||||
	log.Println(*update)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func registerChat(ctx context.Context, b *bot.Bot, update *models.Update) {
 | 
			
		||||
	msg := update.Message
 | 
			
		||||
	log.Println("registering", msg.Chat.ID)
 | 
			
		||||
	m, err := FetchMemberFromChat(ctx, b, msg.Chat.ID, msg.From.ID)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		if !IsAdmin(*m) {
 | 
			
		||||
			log.Println("register: user is not admin")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		args := strings.Split(msg.Text, " ")
 | 
			
		||||
		if len(args) == 1 {
 | 
			
		||||
			log.Println("register: there's no code")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if !UseActivation(args[1]) {
 | 
			
		||||
			log.Println("register: wrong code")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if err := ActivateChat(msg.Chat.ID); err != nil {
 | 
			
		||||
			log.Println("Error activating chat: ", err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		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()})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Println("register: failed to add to delete", err)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		log.Println("register: error", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handleNewJoined(ctx context.Context, b *bot.Bot, u *models.Update) {
 | 
			
		||||
	for _, user := range u.Message.NewChatMembers {
 | 
			
		||||
		log.Println(user)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func banUser(ctx context.Context, b *bot.Bot, u *models.Update) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								src/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/main.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/signal"
 | 
			
		||||
 | 
			
		||||
	_ "github.com/glebarez/go-sqlite"
 | 
			
		||||
	"github.com/go-telegram/bot"
 | 
			
		||||
	"github.com/go-telegram/bot/models"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
 | 
			
		||||
	defer cancel()
 | 
			
		||||
 | 
			
		||||
	if err := InitDb(); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	defer db.Close()
 | 
			
		||||
 | 
			
		||||
	db.MustExec(schema)
 | 
			
		||||
 | 
			
		||||
	opts := []bot.Option{
 | 
			
		||||
		bot.WithMiddlewares(logChats, logUsers, checkRegistered),
 | 
			
		||||
		bot.WithDefaultHandler(defaultHandler),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b, err := bot.New(os.Getenv("TG_TOKEN"), opts...)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b.RegisterHandler(bot.HandlerTypeMessageText, "/register", bot.MatchTypePrefix, registerChat)
 | 
			
		||||
	b.RegisterHandler(bot.HandlerTypeMessageText, "/ban", bot.MatchTypePrefix, banUser)
 | 
			
		||||
	b.RegisterHandlerMatchFunc(func(update *models.Update) bool {
 | 
			
		||||
		return update.Message != nil && len(update.Message.NewChatMembers) > 0
 | 
			
		||||
	}, handleNewJoined)
 | 
			
		||||
	b.Start(ctx)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								src/middleware.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/middleware.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"log"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/go-telegram/bot"
 | 
			
		||||
	"github.com/go-telegram/bot/models"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func checkRegistered(next bot.HandlerFunc) bot.HandlerFunc {
 | 
			
		||||
	return func(ctx context.Context, b *bot.Bot, update *models.Update) {
 | 
			
		||||
		if update.Message == nil {
 | 
			
		||||
			next(ctx, b, update)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		chat := update.Message.Chat
 | 
			
		||||
		if chat.Type == "private" {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if !IsChatActive(chat.ID) && !strings.HasPrefix(update.Message.Text, "/register") {
 | 
			
		||||
			log.Println("checkRegistered: not registered", chat.ID)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		next(ctx, b, update)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func logChats(next bot.HandlerFunc) bot.HandlerFunc {
 | 
			
		||||
	return func(ctx context.Context, b *bot.Bot, update *models.Update) {
 | 
			
		||||
		if update.Message == nil {
 | 
			
		||||
			next(ctx, b, update)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		chat := update.Message.Chat
 | 
			
		||||
		chatName := GetChatFullName(chat)
 | 
			
		||||
		if !IsChatExists(chat.ID) {
 | 
			
		||||
			db.MustExec(`insert into chats (id, username, name, topic, active) values ($1, $2, $3, $4, $5);`, chat.ID, chat.Username, chatName, 0, false)
 | 
			
		||||
		} else {
 | 
			
		||||
			db.MustExec(`update chats set username = $2, name = $3 where id = $1;`, chat.ID, chat.Username, chatName)
 | 
			
		||||
		}
 | 
			
		||||
		next(ctx, b, update)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func logUsers(next bot.HandlerFunc) bot.HandlerFunc {
 | 
			
		||||
	return func(ctx context.Context, b *bot.Bot, update *models.Update) {
 | 
			
		||||
		if update.Message == nil {
 | 
			
		||||
			next(ctx, b, update)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		user := update.Message.From
 | 
			
		||||
		userFullName := GetUserFullName(*user)
 | 
			
		||||
		if !IsUserExists(user.ID) {
 | 
			
		||||
			db.MustExec(`insert into users (id, username, name) values ($1, $2, $3);`, user.ID, user.Username, userFullName, 0, false)
 | 
			
		||||
		} else {
 | 
			
		||||
			db.MustExec(`update users set username = $2, name = $3 where id = $1;`, user.ID, user.Username, userFullName)
 | 
			
		||||
		}
 | 
			
		||||
		next(ctx, b, update)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user