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/handlers/help.py
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.7 KiB
Python
Raw Permalink 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.

from aiogram import F, Router
from aiogram.filters import Command, CommandStart
from aiogram.types import CallbackQuery, FSInputFile, InlineKeyboardButton, InlineKeyboardMarkup, Message
from .common import count, in_group
import db
router = Router()
ABOUT = ('<b>-</b> Этот АБОБОТ поможет вам приятно провести время в чате с различными командами, '
'ивентами и удобными функциями, которые облегчают использование чата)\n\n'
'<b>-</b> Также прошу если вам понравился бот, оставить отзыв о его использовании на '
'команду /report)')
@router.message(CommandStart())
@router.message(Command('help'))
async def helps(message: Message):
await db.ensure_user(message.from_user.id)
if in_group(message):
await count(message, 3, 1)
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="КОМАНДЫ", callback_data="com"),
InlineKeyboardButton(text="ИВЕНТЫ", callback_data="even")],
[InlineKeyboardButton(text="АВТОР", callback_data="auth"),
InlineKeyboardButton(text="ФУНКЦИИ", callback_data="fun")]
])
try:
await message.answer_voice(voice=FSInputFile('../data/tts.ogg'), caption=ABOUT, reply_markup=keyboard)
except Exception:
await message.answer(ABOUT, reply_markup=keyboard)
@router.callback_query(F.data == "auth")
async def author(call: CallbackQuery):
await call.message.answer(
'<b>| АВТОР |</b>\n\n<b>>></b> Этот бот, как бы это не печально звучало, но одна из лучших'
' моих работ и если кого-нибудь у меня получится действительно достойный продукт,'
' вы сможете о нём узнать в моём телеграм канале <b>@programium</b>')
@router.callback_query(F.data == "fun")
async def function(call: CallbackQuery):
await call.message.answer(
'<b>| ФУНКЦИИ |</b>\n\n<b>1.</b> Возможность перевода случайно написанного текста на '
'транслите\n<b>2.</b> Ведение обширной статистики сообщений\n<b>3.</b> Упоминание участника '
'при написании его имени в чате\n<b>4.</b> Автоматическое удаление системных сообщений')
@router.callback_query(F.data == "com")
async def commands(call: CallbackQuery):
await call.message.answer(
'<b>| КОМАНДЫ |</b>\n\n<b>/all</b> - упомянуть всех в чате\n<b>/help</b> - полный список функций\n'
'<b>/recognize</b> - транскрипция отмеченного голосового сообщения в текст\n'
'<b>/stat_group</b> - полная статистика группы\n<b>/stat_user</b> - полная статистика '
'отправителя\n<b>/top</b> - самые активные участники (<b>/top all</b> - за всё время)\n'
'<b>/month</b> - итоги месяца (<b>/month 2026-09</b> - за любой месяц)\n'
'<b>/edit и /back_edit</b> - первая команда даёт возможность '
'сменить имя для упоминаний на любое слово, а вторая для возврата динамического '
'имени\n<b>/settings</b> - настройки бота в чате\n'
'<b>/start_bot и /stop_bot</b> - возможность отключения текстовых ивентов')
@router.callback_query(F.data == "even")
async def events(call: CallbackQuery):
await call.message.answer(
'<b>| ИВЕНТЫ |</b>\n\n<b>"Чмокнуть"</b> - сделать кому-нибудь приятно\n<b>"Отмудохать"</b> - '
'выместить злость на кого-нибудь\n<b>"Число от ... до ..."</b> - случайное значение из '
'диапозона\n<b>"Подраться с ..."</b> - повод кого-нибудь побить\n<b>"Переведи (..) - ..."</b> '
'- перевод слова на керпичный язык\n<b>"Дай блять совет!"</b> - даёт рандомный охуенный '
'совет\n<b>"Переверни - ..."</b> - переворачивает слова в предложении\n<b>"Озвучь - ..."</b> '
'- озвучивает написанный текст')