Compare commits
3 Commits
312153ad34
...
e54144d716
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e54144d716 | ||
|
|
2bf30fc346 | ||
|
|
abbf2ca145 |
33
TODO.md
33
TODO.md
@@ -5,32 +5,45 @@
|
||||
Для реализации телеграммного фронтэнда нам надо сделать:
|
||||
|
||||
0. Парсер конфига.
|
||||
|
||||
[V] Реализован начальный вариант парсера конфига.
|
||||
|
||||
1. Разгребальщик апдейтов и формирователь redis-ных сообщений.
|
||||
|
||||
[ ] Написана заглушка для парсера апдейтов bot api телеграма
|
||||
|
||||
2. Разгребальщик редисных сообщений и формирователь запросов в tg bot api.
|
||||
|
||||
[ ] Написан черновой вариант рагребателя
|
||||
|
||||
3. Обработчик группы команд admin, сохранение настроек в pebbledb.
|
||||
|
||||
1 цензор сообщений определённого типа.
|
||||
1 [V] [V] цензор сообщений определённого типа.
|
||||
|
||||
2 фортунка каждое утро. (+ добавить время, относительно gmt, когда показывать фортунку).
|
||||
2 [ ] [V] фортунка каждое утро. (+ добавить время, относительно gmt, когда показывать фортунку).
|
||||
|
||||
3 Приветствие новых участников
|
||||
3 [V] [V] Приветствие новых участников
|
||||
|
||||
4 oboobs
|
||||
4 [V] [ ] Прощание с теми, кто ушёл
|
||||
|
||||
5 obutts
|
||||
4 [ ] [ ] oboobs
|
||||
|
||||
6 chan_msg
|
||||
5 [ ] [ ] obutts
|
||||
|
||||
7 user ban
|
||||
6 [V] [ ] chan_msg
|
||||
|
||||
8 user mute
|
||||
7 [ ] [ ] user ban
|
||||
|
||||
4. help
|
||||
8 [ ] [ ] user mute
|
||||
|
||||
5. Readme.txt
|
||||
4. [V] help
|
||||
|
||||
5. [V] help admin
|
||||
|
||||
6. [ ] Readme
|
||||
|
||||
7. [ ] Поддержать миграцию групп в супергруппы (итд, там меняется id и надо перекидывать настройки на новый id)
|
||||
|
||||
8. [ ] Поддержать парсинг ошибок отправки сообщений в телегу
|
||||
|
||||
9. [ ] Поддержать leaveChat(), чтобы бот мог легально и самостоятельно покинуть чят.
|
||||
|
||||
@@ -33,4 +33,13 @@ var settingsDB = make(map[string]*pebble.DB)
|
||||
|
||||
var tg echotron.API
|
||||
|
||||
// Приветсвенные фразы для новых участников чата.
|
||||
var introduceGreet = [...]string{
|
||||
"Дратути",
|
||||
"Дарована",
|
||||
"Доброе утро, день или вечер",
|
||||
"Добро пожаловать в наше скромное коммунити",
|
||||
"Наше вам с кисточкой тут, на канальчике",
|
||||
}
|
||||
|
||||
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||
|
||||
136
msg-parsers.go
136
msg-parsers.go
@@ -3,8 +3,10 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand/v2"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/NicoNex/echotron/v3"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
@@ -124,40 +126,13 @@ func telegramMsgParser(msg *echotron.Update) {
|
||||
if (msg.Message.MigrateFromChatID < 0) && (msg.Message.MigrateToChatID < 0) { //nolint: revive,staticcheck
|
||||
// TODO: поддержать миграцию настроек чата на новый chatId.
|
||||
// TODO: подумать, что можно сделать с настройками бэкэндов. Кажись, ничего, но надо глянуть.
|
||||
}
|
||||
|
||||
// Люди пришли в чят.
|
||||
if msg.Message.NewChatMembers != nil { //nolint: revive,staticcheck
|
||||
// TODO: проверить, надо ли приветствовать, выбрать одну из приветственных фраз, потянуть время, типа, мы пишем
|
||||
// текст и поприветствовать вновь прибывшего.
|
||||
}
|
||||
|
||||
// Человек ушёл из чата.
|
||||
if msg.Message.LeftChatMember != nil {
|
||||
if GetSetting(fmt.Sprintf("%d", msg.Message.Chat.ID), "GoodbyeMsg") == "1" {
|
||||
user := ConstructUserFirstLastName(msg.Message.From)
|
||||
|
||||
goodbye := fmt.Sprintf("Прощаемся с %s", user)
|
||||
|
||||
opts := echotron.MessageOptions{DisableNotification: true, ParseMode: "MarkdownV2"}
|
||||
|
||||
if msg.Message.ThreadID != 0 {
|
||||
opts.MessageThreadID = int64(msg.Message.ThreadID)
|
||||
}
|
||||
|
||||
if res, err := tg.SendMessage(goodbye, msg.Message.Chat.ID, &opts); err != nil {
|
||||
log.Errorf("Unable to send message to telegram api: %s", err)
|
||||
} else if !res.Ok {
|
||||
log.Errorf("Unable to send message to telegram api: %s", res.Description)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Если сообщение было зацензурено, то дальше его обрабатывать не надо.
|
||||
if Censor(msg) {
|
||||
return
|
||||
}
|
||||
|
||||
// Здесь начинается парсинг, подразумевающий какие-то сообщения бота в чат, поэтому с этой точки можно/нужно
|
||||
// получить информацию о самом боте.
|
||||
// TODO: пораскинуть, можно ли как-то кэшировать эту информацию, чтобы не дёргать api по чём зря.
|
||||
var (
|
||||
rmsg rMsg
|
||||
errorOccured bool
|
||||
@@ -182,6 +157,100 @@ func telegramMsgParser(msg *echotron.Update) {
|
||||
return
|
||||
}
|
||||
|
||||
// Люди пришли в чят.
|
||||
if msg.Message.NewChatMembers != nil { //nolint: revive,staticcheck
|
||||
// TODO: проверить, надо ли приветствовать, выбрать одну из приветственных фраз, потянуть время, типа, мы пишем
|
||||
// текст и поприветствовать вновь прибывшего.
|
||||
if GetSetting(fmt.Sprintf("%d", msg.Message.Chat.ID), "GreetMsg") == "1" {
|
||||
// Пользователи, которых мы приветсвуем, одной строкой.
|
||||
var users string
|
||||
|
||||
if len(msg.Message.NewChatMembers) > 1 {
|
||||
lastOne := msg.Message.NewChatMembers[len(msg.Message.NewChatMembers)-1]
|
||||
theRest := msg.Message.NewChatMembers[:len(msg.Message.NewChatMembers)-1]
|
||||
var usersSlice []string
|
||||
|
||||
for _, user := range theRest {
|
||||
usersSlice = append(usersSlice, ConstructTelegramHighlightName(user))
|
||||
}
|
||||
|
||||
users = strings.Join(usersSlice, ", ")
|
||||
users += fmt.Sprintf(" and %s", ConstructTelegramHighlightName(lastOne))
|
||||
} else {
|
||||
users = ConstructTelegramHighlightName(msg.Message.NewChatMembers[0])
|
||||
}
|
||||
|
||||
phrase := fmt.Sprintf(
|
||||
"%s, %s. Представьтес, пожалуйста, и расскажите, что вас сюда привело.",
|
||||
introduceGreet[rand.IntN(len(introduceGreet))],
|
||||
users,
|
||||
)
|
||||
|
||||
// Потянуть время, изобразить настоящего человека.
|
||||
resp, err := tg.SendChatAction(
|
||||
echotron.Typing,
|
||||
msg.Message.From.ID,
|
||||
&echotron.ChatActionOptions{MessageThreadID: int(msg.Message.ThreadID)},
|
||||
)
|
||||
|
||||
// TODO: вероятно, ошибку надо засылать в обработчик ошибок, так как в ней может быть миграция чятика или
|
||||
// что-то, что тоже надо хэндлить.
|
||||
if err != nil || !resp.Ok {
|
||||
log.Errorf(
|
||||
"unable to send message to telegram api: %s\nResponse dump: %s",
|
||||
err,
|
||||
spew.Sdump(resp),
|
||||
)
|
||||
}
|
||||
|
||||
resp1, err := tg.SendMessage(
|
||||
phrase,
|
||||
msg.Message.Chat.ID,
|
||||
&echotron.MessageOptions{ParseMode: "MarkdownV2", MessageThreadID: int64(msg.Message.ThreadID)},
|
||||
)
|
||||
|
||||
// TODO: вероятно, ошибку надо засылать в обработчик ошибок, так как в ней может быть миграция чятика или
|
||||
// что-то, что тоже надо хэндлить.
|
||||
if err != nil || !resp1.Ok {
|
||||
log.Errorf(
|
||||
"unable to send message to telegram api: %s\nResponse dump: %s",
|
||||
err,
|
||||
spew.Sdump(resp1),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Человек ушёл из чата.
|
||||
if msg.Message.LeftChatMember != nil {
|
||||
if GetSetting(fmt.Sprintf("%d", msg.Message.Chat.ID), "GoodbyeMsg") == "1" {
|
||||
user := ConstructUserFirstLastName(msg.Message.From)
|
||||
|
||||
goodbye := fmt.Sprintf("Прощаемся с %s", user)
|
||||
|
||||
opts := echotron.MessageOptions{DisableNotification: true, ParseMode: "MarkdownV2"}
|
||||
|
||||
if msg.Message.ThreadID != 0 {
|
||||
opts.MessageThreadID = int64(msg.Message.ThreadID)
|
||||
}
|
||||
|
||||
if res, err := tg.SendMessage(goodbye, msg.Message.Chat.ID, &opts); err != nil {
|
||||
log.Errorf("Unable to send message to telegram api: %s", err)
|
||||
} else if !res.Ok {
|
||||
log.Errorf("Unable to send message to telegram api: %s", res.Description)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Если сообщение было зацензурено, то дальше его обрабатывать не надо.
|
||||
if Censor(msg) {
|
||||
return
|
||||
}
|
||||
|
||||
switch msg.Message.Chat.Type {
|
||||
case "private":
|
||||
// Всё что можно было похэндлить, что не содержало текста, считаем, что обработали.
|
||||
@@ -287,9 +356,10 @@ func telegramMsgParser(msg *echotron.Update) {
|
||||
msg.Message.Text = m.ReplaceAllString(msg.Message.Text, "")
|
||||
}
|
||||
|
||||
// TODO: обращение может содержать знаки препинания, пробелы перед, пробелы после. Надо бы это поддержать.
|
||||
// TODO: обращение может содержать знаки препинания, пробелы перед, пробелы после имени бота. Надо бы это поддержать.
|
||||
// TODO: унести вырезание имени бота в отдельную процедуру.
|
||||
switch {
|
||||
// Если у на есть и имя и фамилия бота, то попробуем их слепить вместе, через "1 и более" пробел и вырезать
|
||||
// Если у нас есть и имя и фамилия бота, то попробуем их слепить вместе, через "1 и более" пробел и вырезать
|
||||
// полученное из входящей фразы.
|
||||
case quotedBotFirstName != "" && quotedBotLastName != "":
|
||||
messageContainsBotName, err := regexp.MatchString(
|
||||
@@ -1090,7 +1160,7 @@ func Admin(msg *echotron.Update) (bool, error) {
|
||||
answer += "Не будем приветствовать вновьприбывших участников чата"
|
||||
|
||||
default:
|
||||
answer += "Не понимаю о чём ты."
|
||||
answer += "Не понимаю, о чём ты."
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ func ConstructPartialChatUsername(c *echotron.Chat) string {
|
||||
}
|
||||
|
||||
// ConstructUserFirstLastName Пытается найти и вытащить first name и last name пользователя, если не получается, то
|
||||
// вначале пытается фоллбэчиться на first name, потом на last name, потом на username.
|
||||
// вначале пытается фоллбэчится на first name, потом на last name, потом на username.
|
||||
func ConstructUserFirstLastName(u *echotron.User) string {
|
||||
var user string
|
||||
|
||||
@@ -131,7 +131,7 @@ func ConstructUserFirstLastName(u *echotron.User) string {
|
||||
return user
|
||||
}
|
||||
|
||||
// ConstructTelegramHighlightName генерирует имя пользователя, которое триггерит на стороне клиент ивент меншена
|
||||
// ConstructTelegramHighlightName генерирует имя пользователя, которое триггерит на стороне клиента ивент меншена
|
||||
// определённого пользователя.
|
||||
func ConstructTelegramHighlightName(u *echotron.User) string {
|
||||
var (
|
||||
|
||||
Reference in New Issue
Block a user