1
0
Fork 0
mirror of https://github.com/EDeev/chatping_abobot.git synced 2026-10-07 20:49:45 +03:00
chatping_abobot/code/schema.sql
Egor Deev a2a0adcf8e AboBot 4.0: PostgreSQL, обработчики по роутерам, HTML-разметка, новые команды
База — PostgreSQL (asyncpg) вместо четырёх файлов SQLite с таблицей на каждый чат:
chats, users, members, chat_stats и member_stats с полем «период» — месяцы хранятся, а не
обнуляются; счётчики растут одним запросом без блокировки бота. scripts/migrate_sqlite.py
переносит старые базы со сверкой сумм (проверено на копии рабочих баз: 20 694 пользователя,
45 чатов, 3 142 038 сообщений — совпадает).

Учёт бота в чатах: статус и права бота (событие my_chat_member и сверка с Telegram при
запуске и раз в 6 часов), история изменений в bot_status_history; из чатов, где бота
исключили, данные не удаляются — меняется только статус.

Большие чаты (больше 100 участников): /all — только для админов, раз в 5 минут и только
писавшие за 30 дней; упоминание одного человека по имени — не чаще раза в минуту. В любом
чате /all делится на сообщения до 4096 символов (раньше в чате на 14 тысяч падал).

Новое: /settings (упоминания, имена в голосовых, ивенты, удаление служебных сообщений —
меняют админы), /top, /month (итоги месяца по команде). /stop_bot раньше ничего не
выключал — флаг не проверялся; теперь работает. Участник, вышедший из чата, больше не
упоминается, но его статистика сохраняется. Ошибки — в технический чат DEBUG_CHAT_ID.

Код: handlers.py разбит на роутеры, Markdown заменён на HTML (экранирование через html.escape),
тесты на PostgreSQL (18), CI на Python 3.10 и 3.12.
2026-10-06 11:16:00 +00:00

73 lines
4.5 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Схема AboBot в PostgreSQL. Применяется при каждом запуске (всё IF NOT EXISTS).
CREATE TABLE IF NOT EXISTS chats (
id BIGINT PRIMARY KEY, -- id чата в Telegram
short_id SERIAL UNIQUE, -- внутренний номер («Группа #N» в Metabase)
title TEXT,
events_enabled BOOLEAN NOT NULL DEFAULT TRUE, -- текстовые ивенты (/start_bot, /stop_bot)
mentions_enabled BOOLEAN NOT NULL DEFAULT TRUE, -- упоминания по имени в сообщениях
voice_names BOOLEAN NOT NULL DEFAULT TRUE, -- поиск имён в голосовых (уходят в Google)
delete_service BOOLEAN NOT NULL DEFAULT TRUE, -- удаление служебных сообщений
last_all_at TIMESTAMPTZ, -- последний /all (ограничение в больших чатах)
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
-- бот в чате: статус Telegram (member, administrator, restricted, left, kicked) и права;
-- если бота исключили, данные чата остаются, меняется только статус
bot_status TEXT,
bot_rights JSONB,
bot_status_at TIMESTAMPTZ, -- когда статус изменился
checked_at TIMESTAMPTZ, -- когда статус последний раз сверялся с Telegram
member_count INTEGER, -- участников по Telegram на момент сверки
chat_type TEXT
);
-- история статуса бота в чатах: добавили, повысили до админа, ограничили, исключили
CREATE TABLE IF NOT EXISTS bot_status_history (
id BIGSERIAL PRIMARY KEY,
chat_id BIGINT NOT NULL REFERENCES chats (id) ON DELETE CASCADE ON UPDATE CASCADE,
status TEXT NOT NULL,
rights JSONB,
source TEXT NOT NULL, -- update (событие Telegram) или check (сверка)
changed_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS users (
id BIGINT PRIMARY KEY, -- id пользователя в Telegram
short_id SERIAL UNIQUE
);
CREATE TABLE IF NOT EXISTS members (
chat_id BIGINT NOT NULL REFERENCES chats (id) ON DELETE CASCADE ON UPDATE CASCADE,
user_id BIGINT NOT NULL REFERENCES users (id) ON DELETE CASCADE,
name TEXT NOT NULL DEFAULT '', -- имя для упоминаний (в нижнем регистре)
custom_name BOOLEAN NOT NULL DEFAULT FALSE, -- задано командой /edit, не обновляется само
last_message_at TIMESTAMPTZ,
left_at TIMESTAMPTZ, -- вышел из чата (статистика сохраняется)
PRIMARY KEY (chat_id, user_id)
);
-- период: 'all' — за всё время, 'YYYY-MM' — месяц; месяцы хранятся, а не обнуляются
CREATE TABLE IF NOT EXISTS chat_stats (
chat_id BIGINT NOT NULL REFERENCES chats (id) ON DELETE CASCADE ON UPDATE CASCADE,
period TEXT NOT NULL,
mes INTEGER NOT NULL DEFAULT 0, rep INTEGER NOT NULL DEFAULT 0, com INTEGER NOT NULL DEFAULT 0,
url INTEGER NOT NULL DEFAULT 0, med INTEGER NOT NULL DEFAULT 0, sti INTEGER NOT NULL DEFAULT 0,
voi INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (chat_id, period)
);
CREATE TABLE IF NOT EXISTS member_stats (
chat_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
period TEXT NOT NULL,
mes INTEGER NOT NULL DEFAULT 0, rep INTEGER NOT NULL DEFAULT 0, com INTEGER NOT NULL DEFAULT 0,
url INTEGER NOT NULL DEFAULT 0, med INTEGER NOT NULL DEFAULT 0, sti INTEGER NOT NULL DEFAULT 0,
voi INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (chat_id, user_id, period),
FOREIGN KEY (chat_id, user_id) REFERENCES members (chat_id, user_id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE INDEX IF NOT EXISTS member_stats_period ON member_stats (chat_id, period);
-- бот в чате сейчас (для статистики по действующим группам)
CREATE OR REPLACE VIEW active_chats AS
SELECT * FROM chats WHERE bot_status IN ('member', 'administrator', 'restricted');