1
0
Fork 0
mirror of https://github.com/EDeev/chatping_abobot.git synced 2026-10-07 20:49:45 +03:00

README: версия 4 — PostgreSQL, ограничения больших чатов, /settings, /top, /month, учёт бота в группах, развёртывание

This commit is contained in:
Деев Егор Викторович 2026-10-06 11:26:12 +00:00
parent a2a0adcf8e
commit af372fbdf0
2 changed files with 104 additions and 48 deletions

View file

@ -18,16 +18,22 @@ The bot speaks Russian.
**Status:** personal project, running since 2021 · bot [@chat_abobot](https://t.me/chat_abobot) · over
20,000 users from 45 chats in the bot's database (October 2026)
**Stack:** Python 3.12 · aiogram 3 · pymorphy3 · pyenchant · SpeechRecognition · gTTS · SQLite · Docker
**Stack:** Python 3.10+ · aiogram 3 · PostgreSQL (asyncpg) · pymorphy3 · pyenchant · SpeechRecognition · gTTS · Docker
## Features
- **Name mentions.** Words of a message are reduced to their base form (pymorphy3) and compared with
members' names, so any grammatical case of a name mentions the right person. A custom name can be set with `/edit`. Names are also found
in voice notes up to a minute long.
- **`/all`** mentions every member.
- **`/all`** mentions every member. A long list is split into several messages.
- **Big chats (over 100 members).**
- `/all` is for admins only, at most once in 5 minutes, and only for people who wrote in the last 30 days.
- The same person is mentioned by name at most once a minute.
- **All-time and monthly statistics** (`/stat_group`, `/stat_user`): messages, replies, commands, links,
media, stickers, voice and video notes. Monthly numbers reset at the start of each month.
media, stickers, voice and video notes. Months are kept, so `/month 2026-09` shows any month's summary
and `/top` shows the most active members for the month or all time (`/top all`).
- **`/settings`** — per-chat switches: name mentions, names in voice notes (audio goes to Google), text
events, deleting service messages. Admins can change them.
- **Wrong keyboard layout.** A message like `ghbdtn` is repeated as «привет». English words are recognized
with a dictionary (pyenchant) and left alone.
- **Voice.** `/recognize` as a reply to a voice note transcribes it; «Озвучь - текст» turns text into a
@ -39,37 +45,56 @@ The bot speaks Russian.
- mock fights;
- picture reactions.
Turned off with `/stop_bot`.
Turned off with `/stop_bot` or in `/settings`.
- Deleting service messages (joins, leaves, title and photo changes) when the bot is an admin.
- **Tracking the bot in groups.** The bot records which groups it is in and with which rights: Telegram
events plus a check on start and every 6 hours. Changes are kept as history. If the bot is removed, the
group's statistics stay; only the mark that the bot is no longer there changes.
## Running
```bash
git clone https://github.com/EDeev/chatping_abobot.git && cd chatping_abobot
cp .env.example .env # BOT_TOKEN from @BotFather
docker compose up -d
docker compose up -d # the bot and PostgreSQL
```
Prebuilt image: `docker pull ghcr.io/edeev/chatping_abobot` or `docker pull dcr.deev.su/edeev/chatping_abobot`.
The SQLite databases are created on first start.
Tables are created on first start (`code/schema.sql`).
Without Docker you need Python 3.12, the enchant system library and an English dictionary
(`apt install libenchant-2-2 hunspell-en-us`). Then: `pip install -r requirements.txt` and
`cd code && BOT_TOKEN=… python bot.py`.
Without Docker you need:
- Python 3.10+;
- PostgreSQL;
- the enchant system library with an English dictionary (`apt install libenchant-2-2 hunspell-en-us`).
Then: `pip install -r requirements.txt` and `cd code && BOT_TOKEN=… DATABASE_URL=postgresql://… python bot.py`.
Migrating data from the old version (four SQLite databases):
`python scripts/migrate_sqlite.py --sqlite-dir path/to/db --dsn postgresql://…`. The script checks the
totals after the transfer.
## Deployment
[@chat_abobot](https://t.me/chat_abobot) runs on a home server as a systemd service: its own venv, settings in
`/etc/abobot.env`, PostgreSQL on the same server. The nightly backup dumps the database, and the statistics
feed a Metabase dashboard.
## How it works
```
code/bot.py entry point and monthly statistics reset
code/handlers.py message, command, voice and event handlers
code/script.py statistics, name lookup, keyboard layout, text reversal
code/sql.py four SQLite databases: groups, users, all-time and monthly statistics
data/ event pictures and the greeting
code/bot.py entry point, error reports to a tech chat, checking the bot's status in groups
code/handlers/ routers: help, settings, stats, mentions, voice, events, chat (bot in groups, service messages)
code/db.py PostgreSQL queries
code/schema.sql schema: chats, users, members, chat_stats and member_stats by period, bot_status_history
code/nlp.py base forms of names, keyboard layout, reversal, escaping
scripts/ migration from SQLite
data/ event pictures and the greeting
```
Member statistics live in a separate table per chat — that is how the bot's production databases are
built. Counters are incremented in a single query, so simultaneous messages are not lost. Speech recognition
and synthesis (Google Web Speech and gTTS) run in a separate thread, so the bot never freezes.
All-time and current-month counters grow in a single query (`INSERT … ON CONFLICT DO UPDATE`), so
simultaneous messages are not lost. Database calls are asynchronous and speech recognition and synthesis
(Google Web Speech and gTTS) run in a separate thread, so the bot never freezes. Messages use HTML markup and
user text is escaped.
## Development
@ -78,12 +103,15 @@ pip install -r requirements-dev.txt
ruff check --select E9,F,B code tests && pytest
```
What the tests cover:
- statistics counters;
- mentions and `/all`;
- the monthly reset;
- keyboard layout, reversal and escaping;
- loading of the bot's handlers.
The tests need PostgreSQL (`TEST_DATABASE_URL`). What they cover:
- counters by period;
- mentions and big-chat limits;
- splitting `/all`;
- the bot's status in groups and its history;
- migration from SQLite;
- keyboard layout and escaping.
CI runs them on Python 3.10 and 3.12.
The Docker image is built on `v*` tags and published to GitHub Packages and `dcr.deev.su`.

View file

@ -13,19 +13,25 @@ Telegram-бот для групповых чатов. Он:
- распознаёт и озвучивает голосовые;
- устраивает шуточные ивенты.
**Статус:** личный проект, работает с 2021 года · бот [@chat_abobot](https://t.me/chat_abobot) · в базе
**Статус:** личный проект, работает с 2021 года, версия 4 · бот [@chat_abobot](https://t.me/chat_abobot) · в базе
бота больше 20 000 пользователей из 45 чатов (октябрь 2026)
**Стек:** Python 3.12 · aiogram 3 · pymorphy3 · pyenchant · SpeechRecognition · gTTS · SQLite · Docker
**Стек:** Python 3.10+ · aiogram 3 · PostgreSQL (asyncpg) · pymorphy3 · pyenchant · SpeechRecognition · gTTS · Docker
## Возможности
- **Упоминания по имени.** Слова сообщения приводятся к начальной форме (pymorphy3) и сравниваются с
именами участников, поэтому участницу Машу позовут и «Маша», и «позови Машу», и «с Машей». Своё имя
для упоминаний можно задать командой `/edit`. Имена ищутся и в голосовых до минуты.
- **`/all`** — упомянуть всех участников.
- **Статистика за всё время и за месяц** (`/stat_group`, `/stat_user`): сообщения, ответы, команды,
ссылки, медиа, стикеры, голосовые и кружочки. Месячная обнуляется в начале месяца.
- **`/all`** — упомянуть всех участников. Длинный список делится на несколько сообщений.
- **Большие чаты (больше 100 участников).**
- `/all` — только для администраторов, не чаще раза в 5 минут и только для писавших за 30 дней.
- Одного человека по имени бот зовёт не чаще раза в минуту.
- **Статистика за всё время и по месяцам** (`/stat_group`, `/stat_user`): сообщения, ответы, команды,
ссылки, медиа, стикеры, голосовые и кружочки. Месяцы хранятся, поэтому `/month 2026-09` покажет итоги
любого месяца, а `/top` — самых активных за месяц или за всё время (`/top all`).
- **`/settings`** — переключатели для чата: упоминания по имени, поиск имён в голосовых (голос уходит в
Google), текстовые ивенты, удаление служебных сообщений. Менять могут администраторы.
- **Неправильная раскладка.** Сообщение вида `ghbdtn` бот повторит как «привет». Английские слова он
отличает по словарю (pyenchant) и не трогает.
- **Голос.** `/recognize` ответом на голосовое — расшифровка; «Озвучь - текст» — голосовое из текста.
@ -36,37 +42,56 @@ Telegram-бот для групповых чатов. Он:
- «Подраться с …»;
- «Чмокнуть» и другие действия с картинками.
Отключаются командой `/stop_bot`.
Отключаются командой `/stop_bot` или в `/settings`.
- Удаление служебных сообщений (вход, выход, смена названия и фото) — если у бота права администратора.
- **Учёт бота в группах.** Бот записывает, в каких группах состоит и с какими правами: события Telegram
плюс сверка при запуске и раз в 6 часов. История изменений хранится. Если бота исключили, статистика
группы не удаляется — меняется только отметка, что бота там больше нет.
## Запуск
```bash
git clone https://github.com/EDeev/chatping_abobot.git && cd chatping_abobot
cp .env.example .env # BOT_TOKEN от @BotFather
docker compose up -d
docker compose up -d # бот и PostgreSQL
```
Готовый образ: `docker pull ghcr.io/edeev/chatping_abobot` или `docker pull dcr.deev.su/edeev/chatping_abobot`.
Базы SQLite создаются при первом запуске.
Таблицы создаются при первом запуске (`code/schema.sql`).
Без Docker нужны Python 3.12, системная библиотека enchant и английский словарь
(`apt install libenchant-2-2 hunspell-en-us`). Затем: `pip install -r requirements.txt` и
`cd code && BOT_TOKEN=… python bot.py`.
Без Docker нужны:
- Python 3.10+;
- PostgreSQL;
- системная библиотека enchant с английским словарём (`apt install libenchant-2-2 hunspell-en-us`).
Затем: `pip install -r requirements.txt` и `cd code && BOT_TOKEN=… DATABASE_URL=postgresql://… python bot.py`.
Перенос данных старой версии (четыре базы SQLite):
`python scripts/migrate_sqlite.py --sqlite-dir путь/к/db --dsn postgresql://…`. Скрипт сверяет суммы после
переноса.
## Развёртывание
[@chat_abobot](https://t.me/chat_abobot) работает на домашнем сервере как systemd-служба: свой venv, настройки
в `/etc/abobot.env`, база — PostgreSQL на том же сервере. Ночной бэкап снимает дамп базы, статистика
выводится в дашборд Metabase.
## Как устроено
```
code/bot.py запуск и ежемесячное обнуление статистики
code/handlers.py обработчики сообщений, команд, голосовых и ивентов
code/script.py учёт статистики, поиск имён, раскладка, переворот текста
code/sql.py четыре базы SQLite: группы, пользователи, статистика за всё время и за месяц
data/ картинки ивентов и приветствие
code/bot.py запуск, отправка ошибок в технический чат, сверка статуса бота в группах
code/handlers/ роутеры: help, settings, stats, mentions, voice, events, chat (бот в группах, служебные сообщения)
code/db.py запросы к PostgreSQL
code/schema.sql схема: chats, users, members, chat_stats и member_stats по периодам, bot_status_history
code/nlp.py имена в начальной форме, раскладка, переворот, экранирование
scripts/ перенос данных из SQLite
data/ картинки ивентов и приветствие
```
Статистика участников хранится в отдельной таблице на каждый чат — так устроены рабочие базы бота.
Счётчики увеличиваются одним запросом, поэтому одновременные сообщения не теряются. Распознавание и синтез
речи (Google Web Speech и gTTS) идут в отдельном потоке, чтобы бот не замирал.
Счётчики за всё время и за текущий месяц растут одним запросом (`INSERT … ON CONFLICT DO UPDATE`),
поэтому одновременные сообщения не теряются. Запросы к базе асинхронные, а распознавание и синтез речи
(Google Web Speech и gTTS) идут в отдельном потоке — бот не замирает. Разметка сообщений — HTML,
пользовательский текст экранируется.
## Разработка
@ -75,12 +100,15 @@ pip install -r requirements-dev.txt
ruff check --select E9,F,B code tests && pytest
```
Что проверяют тесты:
- счётчики статистики;
- упоминания и `/all`;
- обнуление месячной статистики;
- раскладку, переворот и экранирование;
- что обработчики бота загружаются.
Тестам нужен PostgreSQL (`TEST_DATABASE_URL`). Что они проверяют:
- счётчики по периодам;
- упоминания и ограничения больших чатов;
- деление `/all` на сообщения;
- статус бота в группах и историю;
- перенос из SQLite;
- раскладку и экранирование.
CI прогоняет их на Python 3.10 и 3.12.
Docker-образ собирается по тегу `v*` и публикуется в GitHub Packages и `dcr.deev.su`.