Ban method. Needs testing.
This commit is contained in:
parent
0e19fb532b
commit
cb030a60d1
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"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})
|
||||
}
|
||||
|
||||
func IsAdmin(member models.ChatMember) bool {
|
||||
func IsMemberAdmin(member models.ChatMember) bool {
|
||||
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)
|
||||
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 ''
|
||||
);
|
||||
|
||||
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
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
chat_id INTEGER,
|
||||
user_id INTEGER,
|
||||
reason TEXT NOT NULL,
|
||||
chat_id INTEGER NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
text TEXT DEFAULT '',
|
||||
reason TEXT DEFAULT '',
|
||||
ban_date INTEGER NOT NULL,
|
||||
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
|
||||
|
@ -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"`
|
||||
Name string `json:"name" db:"name"`
|
||||
Username string `json:"username" db:"username"`
|
||||
|
@ -104,7 +115,7 @@ func InitDb() error {
|
|||
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)
|
||||
return err
|
||||
}
|
||||
|
@ -128,8 +139,8 @@ func IsChatActive(id int64) bool {
|
|||
return active
|
||||
}
|
||||
|
||||
func GetChatById(id int64) (ChatSchema, error) {
|
||||
c := ChatSchema{}
|
||||
func GetChatById(id int64) (Chat, error) {
|
||||
c := Chat{}
|
||||
err := db.Get(&c, `select * from chats where id = $1`, id)
|
||||
return c, err
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ func registerChat(ctx context.Context, b *bot.Bot, update *models.Update) {
|
|||
log.Println("registering", msg.Chat.ID)
|
||||
m, err := FetchMemberFromChat(ctx, b, msg.Chat.ID, msg.From.ID)
|
||||
if err == nil {
|
||||
if !IsAdmin(*m) {
|
||||
if !IsMemberAdmin(*m) {
|
||||
log.Println("register: user is not admin")
|
||||
return
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ func unregisterChat(ctx context.Context, b *bot.Bot, update *models.Update) {
|
|||
log.Println("unregistering", msg.Chat.ID)
|
||||
m, err := FetchMemberFromChat(ctx, b, msg.Chat.ID, msg.From.ID)
|
||||
if err == nil {
|
||||
if !IsAdmin(*m) {
|
||||
if !IsMemberAdmin(*m) {
|
||||
log.Println("register: user is not admin")
|
||||
return
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ var NewUserTemplate = `
|
|||
`
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
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) {
|
||||
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