Ban method. Needs testing.
This commit is contained in:
parent
0e19fb532b
commit
cb030a60d1
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-telegram/bot"
|
"github.com/go-telegram/bot"
|
||||||
|
@ -37,7 +38,7 @@ func FetchMemberFromChat(ctx context.Context, b *bot.Bot, chatID int64, userID i
|
||||||
return b.GetChatMember(ctx, &bot.GetChatMemberParams{ChatID: chatID, UserID: userID})
|
return b.GetChatMember(ctx, &bot.GetChatMemberParams{ChatID: chatID, UserID: userID})
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsAdmin(member models.ChatMember) bool {
|
func IsMemberAdmin(member models.ChatMember) bool {
|
||||||
return member.Administrator != nil || member.Owner != nil
|
return member.Administrator != nil || member.Owner != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,3 +60,20 @@ func Mention(name string, id int64) string {
|
||||||
text := fmt.Sprintf("[%s](tg://user?id=%d)", bot.EscapeMarkdown(name), id)
|
text := fmt.Sprintf("[%s](tg://user?id=%d)", bot.EscapeMarkdown(name), id)
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func pluralRu(n int, single string, double string, five string) string {
|
||||||
|
switch n {
|
||||||
|
case 10, 11, 12, 13, 14, 15, 16, 17, 18, 19:
|
||||||
|
return five
|
||||||
|
default:
|
||||||
|
s := []rune(strconv.Itoa(n))
|
||||||
|
switch s[len(s)-1] {
|
||||||
|
case '1':
|
||||||
|
return single
|
||||||
|
case '2', '3', '4':
|
||||||
|
return double
|
||||||
|
default:
|
||||||
|
return five
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
27
src/db.go
27
src/db.go
|
@ -38,15 +38,26 @@ name TEXT NOT NULL,
|
||||||
username TEXT DEFAULT ''
|
username TEXT DEFAULT ''
|
||||||
);
|
);
|
||||||
|
|
||||||
|
create table if not exists admins
|
||||||
|
(
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
user_id INTEGER NOT NULL,
|
||||||
|
chat_id INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY (chat_id) REFERENCES chats (id) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
create table if not exists bans
|
create table if not exists bans
|
||||||
(
|
(
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
chat_id INTEGER,
|
chat_id INTEGER NOT NULL,
|
||||||
user_id INTEGER,
|
user_id INTEGER NOT NULL,
|
||||||
reason TEXT NOT NULL,
|
text TEXT DEFAULT '',
|
||||||
|
reason TEXT DEFAULT '',
|
||||||
ban_date INTEGER NOT NULL,
|
ban_date INTEGER NOT NULL,
|
||||||
unban_date INTEGER DEFAULT 0,
|
unban_date INTEGER DEFAULT 0,
|
||||||
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY (chat_id) REFERENCES chats (id) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
create table if not exists captchas
|
create table if not exists captchas
|
||||||
|
@ -62,7 +73,7 @@ FOREIGN KEY (chat_id) REFERENCES chats (id) ON DELETE CASCADE
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
type ChatSchema struct {
|
type Chat struct {
|
||||||
Id int64 `json:"id" db:"id"`
|
Id int64 `json:"id" db:"id"`
|
||||||
Name string `json:"name" db:"name"`
|
Name string `json:"name" db:"name"`
|
||||||
Username string `json:"username" db:"username"`
|
Username string `json:"username" db:"username"`
|
||||||
|
@ -104,7 +115,7 @@ func InitDb() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewChat(chat ChatSchema) error {
|
func NewChat(chat Chat) error {
|
||||||
_, err := db.NamedExec(`insert into chats (id, name, username, topic, active) values (:id, :name, :username, :topic, :active)`, chat)
|
_, err := db.NamedExec(`insert into chats (id, name, username, topic, active) values (:id, :name, :username, :topic, :active)`, chat)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -128,8 +139,8 @@ func IsChatActive(id int64) bool {
|
||||||
return active
|
return active
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetChatById(id int64) (ChatSchema, error) {
|
func GetChatById(id int64) (Chat, error) {
|
||||||
c := ChatSchema{}
|
c := Chat{}
|
||||||
err := db.Get(&c, `select * from chats where id = $1`, id)
|
err := db.Get(&c, `select * from chats where id = $1`, id)
|
||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ func registerChat(ctx context.Context, b *bot.Bot, update *models.Update) {
|
||||||
log.Println("registering", msg.Chat.ID)
|
log.Println("registering", msg.Chat.ID)
|
||||||
m, err := FetchMemberFromChat(ctx, b, msg.Chat.ID, msg.From.ID)
|
m, err := FetchMemberFromChat(ctx, b, msg.Chat.ID, msg.From.ID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if !IsAdmin(*m) {
|
if !IsMemberAdmin(*m) {
|
||||||
log.Println("register: user is not admin")
|
log.Println("register: user is not admin")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ func unregisterChat(ctx context.Context, b *bot.Bot, update *models.Update) {
|
||||||
log.Println("unregistering", msg.Chat.ID)
|
log.Println("unregistering", msg.Chat.ID)
|
||||||
m, err := FetchMemberFromChat(ctx, b, msg.Chat.ID, msg.From.ID)
|
m, err := FetchMemberFromChat(ctx, b, msg.Chat.ID, msg.From.ID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if !IsAdmin(*m) {
|
if !IsMemberAdmin(*m) {
|
||||||
log.Println("register: user is not admin")
|
log.Println("register: user is not admin")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ var NewUserTemplate = `
|
||||||
`
|
`
|
||||||
|
|
||||||
func handleNewJoined(ctx context.Context, b *bot.Bot, u *models.Update) {
|
func handleNewJoined(ctx context.Context, b *bot.Bot, u *models.Update) {
|
||||||
var chat ChatSchema
|
var chat Chat
|
||||||
err := db.Get(&chat, "select * from chats where id = $1 and active = 1", u.Message.Chat.ID)
|
err := db.Get(&chat, "select * from chats where id = $1 and active = 1", u.Message.Chat.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("can't get chat for new joined: ", err)
|
log.Println("can't get chat for new joined: ", err)
|
||||||
|
@ -160,6 +160,89 @@ func handleNewJoined(ctx context.Context, b *bot.Bot, u *models.Update) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func banUser(ctx context.Context, b *bot.Bot, u *models.Update) {
|
func banUser(ctx context.Context, b *bot.Bot, u *models.Update) {
|
||||||
|
msg := u.Message
|
||||||
|
if msg.ReplyToMessage == nil {
|
||||||
|
newMsg, err := b.SendMessage(ctx, &bot.SendMessageParams{
|
||||||
|
Text: "Хочешь себя забанить? 🙃",
|
||||||
|
ReplyParameters: &models.ReplyParameters{
|
||||||
|
ChatID: msg.Chat.ID,
|
||||||
|
MessageID: msg.ID,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err == nil {
|
||||||
|
AddMessageToDelete(MessageToDelete{MessageId: msg.ID, ChatId: msg.Chat.ID, DeleteDate: time.Now().Add(10 * time.Second).Unix()})
|
||||||
|
AddMessageToDelete(MessageToDelete{MessageId: newMsg.ID, ChatId: msg.Chat.ID, DeleteDate: time.Now().Add(10 * time.Second).Unix()})
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reply := msg.ReplyToMessage
|
||||||
|
chatID := msg.Chat.ID
|
||||||
|
sender := msg.From
|
||||||
|
banned := reply.From
|
||||||
|
log.Println("banning user", banned.FirstName, "from", msg.Chat.ID)
|
||||||
|
m, err := FetchMemberFromChat(ctx, b, chatID, sender.ID)
|
||||||
|
if err == nil {
|
||||||
|
if !IsMemberAdmin(*m) {
|
||||||
|
log.Println("register: user is not admin")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
text := reply.Text
|
||||||
|
if text == "" {
|
||||||
|
text = reply.Caption
|
||||||
|
}
|
||||||
|
reason := ""
|
||||||
|
days := 0
|
||||||
|
args := strings.SplitN(msg.Text, " ", 2)
|
||||||
|
if len(args) > 1 {
|
||||||
|
num, err := strconv.Atoi(args[1])
|
||||||
|
if err != nil {
|
||||||
|
reason = args[1]
|
||||||
|
} else {
|
||||||
|
if days > 0 {
|
||||||
|
days = num
|
||||||
|
}
|
||||||
|
if len(args) > 2 {
|
||||||
|
reason = args[2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unbanDate := time.Now().Add(time.Duration(days) * time.Hour * 24).Unix()
|
||||||
|
b.DeleteMessage(ctx, &bot.DeleteMessageParams{
|
||||||
|
ChatID: msg.Chat.ID,
|
||||||
|
MessageID: msg.ID,
|
||||||
|
})
|
||||||
|
_, err := b.BanChatMember(ctx, &bot.BanChatMemberParams{
|
||||||
|
ChatID: chatID,
|
||||||
|
UserID: banned.ID,
|
||||||
|
UntilDate: int(unbanDate),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Println("can't ban user: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
newText := "Пользователь *%s* был забанен %s\\."
|
||||||
|
daysText := "навсегда"
|
||||||
|
if days > 0 {
|
||||||
|
daysText = fmt.Sprintf("на %d %s", days, pluralRu(days, "день", "дня", "дней"))
|
||||||
|
}
|
||||||
|
sent, err := b.SendMessage(ctx, &bot.SendMessageParams{
|
||||||
|
ChatID: msg.Chat.ID,
|
||||||
|
Text: fmt.Sprintf(newText, Mention(banned.FirstName, banned.ID), daysText),
|
||||||
|
MessageThreadID: msg.MessageThreadID,
|
||||||
|
})
|
||||||
|
db.Exec(
|
||||||
|
"insert into bans (chat_id, user_id, text, reason, ban_date, unban_date) values ($1, $2, $3, $4, $5, $6)",
|
||||||
|
chatID, banned.ID, text, reason, time.Now().Unix(), unbanDate,
|
||||||
|
)
|
||||||
|
if err == nil {
|
||||||
|
err := DeleteAfterSeconds(msg.Chat.ID, sent.ID, 60)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("register: failed to add to delete", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Println("register: error", err)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue