Telegram userbot для сбора сообщений из чата и создания саммари через Google Gemini.
Бот умеет:
- собирать сообщения за период или по количеству;
- собирать отдельные диапазоны сообщений по номеру или времени;
- фильтровать шум и исключенных пользователей;
- делать AI-саммари командой
/sum; - экспортировать JSON без AI командой
/copy; - публиковать результат в Telegraph или отправлять HTML-файл в Telegram;
- использовать несколько Google API ключей по кругу.
- Это userbot, а не BotFather-бот.
- Команды вы отправляете от своего аккаунта Telegram.
- При первом запуске Telethon попросит код подтверждения.
- Для Gemini на free tier есть жесткие квоты. Большие чаты часто упираются именно в них.
Если хотите просто завести бота без лишней теории:
- Установите
python3иvenv. - Клонируйте репозиторий.
- Создайте виртуальное окружение.
- Установите зависимости.
- Заполните
private.txt. - Запустите
python3 main.py. - В Telegram отправьте в нужный чат
/sum 12h.
Шаги 3–4 делает за вас ./setup.sh.
А если нужен бесплатный GitHub Actions вместо VPS — раздел
«Запуск на GitHub Actions → Форк за 10 минут».
Ниже все то же самое, но подробно.
Нужен Python 3.10+.
Проверка:
python3 --versionЕсли команда не найдена:
- Ubuntu/Debian:
sudo apt update
sudo apt install -y python3 python3-venv python3-pipgit clone https://github.com/Hohlas/ChatSum.git
cd ChatSumpython3 -m venv venv
source venv/bin/activateЕсли все хорошо, в начале строки терминала появится (venv).
pip install -r requirements.txtНужно получить:
TELEGRAM_API_IDTELEGRAM_API_HASHTELEGRAM_PHONE
Как получить:
- Откройте https://my.telegram.org/auth
- Войдите по номеру телефона.
- Откройте
API development tools. - Создайте приложение.
- Скопируйте
api_idиapi_hash.
Нужен хотя бы один ключ Google AI Studio.
Как получить:
- Откройте https://aistudio.google.com
- Создайте API key.
- Скопируйте его в
private.txt.
Можно использовать несколько ключей:
GOOGLE_API_KEYGOOGLE_API_KEY1GOOGLE_API_KEY2GOOGLE_API_KEY3
Бот умеет:
- брать следующий ключ для каждого нового
/sum; - переключаться на следующий ключ после ошибок квоты/доступа.
Важно:
- это помогает только если ключи реально имеют раздельные квоты;
- если ключи относятся к одному Google project, квоты часто общие.
При первом запуске бот сам создаст private.txt из private.txt.example.
Но проще сразу сделать вручную:
cp private.txt.example private.txtОткройте private.txt и заполните.
Минимальный рабочий пример:
TELEGRAM_API_ID=12345678
TELEGRAM_API_HASH=0123456789abcdef0123456789abcdef
TELEGRAM_PHONE=+79991234567
GOOGLE_API_KEY=AIzaSyExampleKey
GEMINI_MODEL=gemini-3.6-flash
TELEGRAM_GROUP_ID=-1001234567890Расширенный пример:
TELEGRAM_API_ID=12345678
TELEGRAM_API_HASH=0123456789abcdef0123456789abcdef
TELEGRAM_PHONE=+79991234567
TELEGRAM_GROUP_ID=-1001234567890
GOOGLE_API_KEY=AIzaSyMainKey
GOOGLE_API_KEY1=AIzaSySecondKey
GOOGLE_API_KEY2=AIzaSyThirdKey
GOOGLE_API_KEY3=AIzaSyFourthKey
GEMINI_MODEL=gemini-3.6-flash
GEMINI_REASONING_EFFORT=medium
GEMINI_CHUNK_MAX_CHARS=70000TELEGRAM_API_ID— Telegram API ID.TELEGRAM_API_HASH— Telegram API hash.TELEGRAM_PHONE— ваш номер телефона в международном формате.TELEGRAM_GROUP_ID— куда отправлять результат. Если не задано, бот используетИзбранное.GOOGLE_API_KEY— основной Gemini API ключ.GOOGLE_API_KEY1..N— дополнительные ключи для ротации.GEMINI_MODEL— модель Gemini.GEMINI_REASONING_EFFORT—none,low,medium,high.GEMINI_CHUNK_MAX_CHARS— лимит входных символов на один чанк.
Если не хотите разбираться:
GEMINI_MODEL=gemini-3.6-flash
GEMINI_REASONING_EFFORT=low
GEMINI_CHUNK_MAX_CHARS=70000Если хотите меньше чанков и меньше API-вызовов:
GEMINI_CHUNK_MAX_CHARS=150000Но имейте в виду:
- чем больше чанк, тем меньше запросов;
- но тем сильнее модель может “схлопывать” темы и делать саммари менее подробным.
python3 main.pyЧто будет:
- Бот прочитает
private.txt. - Проверит Telegram API.
- Проверит Google API ключи.
- Подключится к Telegram.
- При первом запуске попросит код подтверждения.
Если все хорошо, в терминале будет список команд и текущая конфигурация Gemini.
Примеры:
/sum
/sum 12h
/sum 2d
/sum 3d 6h
/sum 50
/sum 600-800
/sum 2d-3d
/sum 12h-24h
/sum 3-5d
/sum 2-4h
Что это значит:
/sum— последние 24 часа;/sum 12h— последние 12 часов;/sum 2d— последние 2 дня;/sum 3d 6h— последние 3 дня и 6 часов;/sum 50— последние 50 сообщений;/sum 600-800— текстовые сообщения с 600-го по 800-е от конца чата;/sum 2d-3d— сообщения от 3 до 2 дней назад;/sum 12h-24h— сообщения от 24 до 12 часов назад.
Диапазоны удобны для диагностики проблемных фрагментов: сначала можно проверить крупный кусок, затем делить его пополам.
Примеры:
/copy 12h
/copy 2d
/copy 100
/copy 600-800
/copy 2d-3d
Это полезно, если:
- Gemini уперся в квоты;
- хотите анализировать вручную в другом ИИ;
- хотите сохранить сырой экспорт.
/copy поддерживает те же диапазоны, что и /sum, но не тратит токены Gemini.
Если включен USE_HTML_EXPORT=true в MODEL_CONFIG.txt, бот:
- отправляет короткое сообщение со статистикой;
- создает HTML-файл;
- отправляет HTML-файл в Telegram.
Если включен USE_HTML_EXPORT=false, бот:
- публикует результат в Telegraph;
- отправляет ссылку в Telegram;
- для больших саммари может публиковать несколько частей.
Обычно бот пишет:
- модель;
- сколько сообщений обработано;
- сколько найдено тем;
- сколько найдено URL;
- период анализа;
- сколько токенов потрачено;
- ошибки API, если были.
Для явного диапазона бот сохраняет диапазон в статистике. Например:
• Обработано: 600-800 сообщений = 22 Тем
Если большое саммари разбито на несколько публикаций, в заголовке каждой страницы Telegraph/HTML указывается часть и диапазон сообщений, например:
Часть 1 (сообщения 1-516)
Часть 2 (сообщения 493-600)
/config
/show_prompt
/show_excluded
/show_priority
/show_model
/reload_config
/add_excluded User Name
/remove_excluded User Name
/add_priority User Name
/remove_priority User Name
/set_model gemini-3.6-flash
Команда обновляет GEMINI_MODEL в private.txt.
Главный файл конфигурации:
- Telegram API;
- Google API keys;
- Gemini model;
- reasoning;
- chunk size;
- ID группы для результатов.
Пользователи, которых нужно исключать из анализа.
Пример:
# Исключенные пользователи
SpamBot
FlooderВажно:
- указывать нужно отображаемое имя в чате, не username.
Пользователи, чьи сообщения модель должна считать приоритетными.
Пример:
# Приоритетные пользователи
Lex
Sergey (ICO Drops)Промпт для Gemini.
Если хотите:
- больше тем;
- меньше схлопывания;
- более подробные цитаты;
редактируйте именно этот файл.
Этот файл все еще используется, но теперь его роль уже, чем раньше. При этом он может вообще отсутствовать: бот умеет стартовать и без него.
Сейчас он в основном хранит:
- режим экспорта
USE_HTML_EXPORT; - старые совместимые флаги интерфейса.
Пример:
MODEL=gemini-3.6-flash
USE_REASONING=false
USE_HTML_EXPORT=trueВажно:
- реальная модель для Gemini берется из
private.txt(GEMINI_MODEL); - reasoning для Gemini тоже берется из
private.txt(GEMINI_REASONING_EFFORT); USE_HTML_EXPORTпо-прежнему читается изMODEL_CONFIG.txt.- если
MODEL_CONFIG.txtотсутствует, бот использует дефолтный экспорт в HTML.
/copy создает flat JSON.
Пример:
{
"metadata": {
"chat_id": "1675726024",
"period_start": "2026-05-04 03:00:00",
"chat_name": "ProChat",
"export_date": "2026-05-04 05:30:00",
"total_messages": 120,
"filtered_messages": 95
},
"messages": [
{
"id": 243613,
"s": "Insey",
"t": "Текст сообщения"
},
{
"id": 243616,
"s": "Artem",
"t": "Ответ на сообщение",
"r": 243613
}
]
}Где:
s— sender;t— text;r— reply_to message id.
Самая частая проблема сейчас — это не баг бота, а квоты Google.
В логах это выглядит так:
HTTP 429
Quota exceeded
RESOURCE_EXHAUSTEDЧто делает бот:
- показывает короткую ошибку API;
- при quota exceeded перестает долбить следующие чанки;
- может переключиться на следующий Google API key, если он есть.
Если сообщений очень много:
- бот разобьет их на чанки;
- каждый чанк — отдельный запрос к Gemini;
- больше чанков = выше расход квоты.
Если сильно увеличить лимит чанка:
- плюсы: меньше запросов;
- минусы: саммари может стать менее подробным.
cd ChatSum
source venv/bin/activate
python3 main.py./start_bot_background.sh
screen -r telegram-chat-analyzerОтключиться от screen, не останавливая процесс:
Ctrl+A- потом
D
Остановить:
./stop_bot.shПример юнита:
[Unit]
Description=ChatSum Telegram userbot
After=network.target
[Service]
Type=simple
User=your_user
WorkingDirectory=/path/to/ChatSum
ExecStart=/path/to/ChatSum/venv/bin/python /path/to/ChatSum/main.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetДальше:
sudo systemctl daemon-reload
sudo systemctl enable telegram-bot
sudo systemctl start telegram-bot
sudo systemctl status telegram-botТот же код может работать на GitHub Actions вместо VPS: ежедневные саммари из
SCHEDULE.txt запускаются по cron (*/10, UTC), раннер сам определяет, какие
задания «должны» в МСК, и не повторяет уже выполненные (дедупликация через
ветку state). Разовые команды тоже есть: пересланное сообщение + sum50
в General канала результатов выполняется следующим раном (опрос inbox,
без долгоживущего процесса).
# 1. Форк кнопкой Fork на GitHub, затем клонируйте СВОЙ форк:
git clone https://github.com/<ВЫ>/ChatSum.git
cd ChatSum
# 2. Форк должен быть PUBLIC (Settings → General → Change visibility):
# на private-репо cron быстро съест бесплатные минуты Actions.
./setup.sh # venv + зависимости + заготовка private.txt
# ... заполните private.txt (ключи: my.telegram.org, aistudio.google.com)
./venv/bin/python gen_session.py # один раз: ввести код из Telegram
gh auth login # один раз: доступ gh к вашему форку
./push_github_secrets.sh # секреты и переменные — в ваш репозиторийЧто делают скрипты:
setup.sh— проверяет Python 3.10+, создаёт/чинитvenv, ставитrequirements.txt, создаётprivate.txtиз примера, проверяет наличиеgh.gen_session.py— печатает StringSession и сохраняет её вtelegram_session.txt(gitignored) для следующего шага.push_github_secrets.sh— читаетprivate.txtи сессию, заливает Secrets (TELEGRAM_*,GOOGLE_API_KEY*) и Variables (GEMINI_*) в репозиторий из git remote (переопределить:--repo OWNER/REPO; предпросмотр:--dry-run). ВсеGOOGLE_API_KEY<N>забираются сколько бы их ни было (1 или 20+) + собирается сводныйGOOGLE_API_KEYSбез потолка. Сессия берётся из--session, envTELEGRAM_SESSION,telegram_session.txtили интерактивного ввода. Значения никогда не печатаются.
Дальше: поправьте SCHEDULE.txt, запушьте в main и запустите вручную
из Actions → ChatSum scheduled summaries → Run workflow (или дождитесь
ближайшего cron-запуска). Проверка inbox: форвард + sum50 в General канала
результатов → саммари появляется, команда удаляется.
| VPS | GitHub Actions | |
|---|---|---|
| Точка входа | python3 main.py (долгоживущий процесс) |
run_once.py --watch (cron) |
| Сессия | файловая session_name.session |
StringSession в секрете TELEGRAM_SESSION |
| Команды | /sum, /copy, /config вживую |
sum/copy через inbox-форвард (опрос), /config нет |
| Стоимость | сервер | бесплатно на public-репо |
Если push_github_secrets.sh не подходит:
- Проверьте visibility репозитория: для
schedule-триггеров cron и бесплатных минут подходит public-репозиторий (Settings → General → Danger Zone). - В
Settings → Secrets and variables → Actions → New repository secretдобавьте (обязательные —TELEGRAM_API_ID,TELEGRAM_API_HASH,TELEGRAM_PHONE,TELEGRAM_SESSION,GOOGLE_API_KEY):TELEGRAM_API_ID,TELEGRAM_API_HASH— из my.telegram.org;TELEGRAM_PHONE— номер аккаунта;TELEGRAM_SESSION— сгенерируйте один раз локально:Скопируйте вывод (длинная строка) в секрет./venv/bin/python gen_session.py
TELEGRAM_SESSION. Не коммитьте эту строку. Перевыпускается, если пароль/сессия были изменены.TELEGRAM_GROUP_ID— (необязательно) канал результатов, иначе «Избранное»;GOOGLE_API_KEY[,1..N]— ключи Gemini.
- В
Settings → Secrets and variables → Actions → New repository variableнастройтеGEMINI_MODEL,GEMINI_TEMPERATURE,GEMINI_REASONING_EFFORT(например,none),GEMINI_CHUNK_MAX_CHARS. Обратите внимание: Variables публичны, секреты — нет. Если значенияGEMINI_*надо скрыть, кладите в Secrets, а не в Variables. Рекомендуется явно задатьGEMINI_REASONING_EFFORT, иначе в логах будет предупреждение на каждый запуск генерации. - Отредактируйте
SCHEDULE.txt(коммитите через git) и запушите вmain. - Запустите вручную из
Actions → ChatSum scheduled summaries → Run workflow, либо дождитесь ближайшего cron-запуска.
.github/workflows/summarize.ymlставит env из Secrets/Variables и вызываетpython run_once.py --watch(цикл ~8 мин: due-задачи + опрос inbox).run_once.pyчитаетSCHEDULE.txt,PROMPT.txt,EXCLUDED_USERS.txt,PRIORITY_USERS.txtиз репозитория;MODEL_CONFIG.txtв репозитории нет — при отсутствии используется HTML-экспорт по умолчанию, а модель берётся изGEMINI_MODEL. Если нужно управлятьUSE_HTML_EXPORTчерез git — добавьтеMODEL_CONFIG.txtв репозиторий.- Inbox: сообщение вида
sum50/copy1dс форвардом из чата-источника (или ответом на форвард) в General канала результатов выполняется ближайшим раном через то же ядро, что VPS-команды; обработанная команда удаляется. Без форварда команда игнорируется и не удаляется. - Окно «должных» заданий:
[now(МСК) − LAG_MAX, now(МСК)], по умолчаниюLAG_MAX=15минут. Задания не раньше этого окна не запускаются (защита от повторов после долгой паузы). - Состояние хранится в ветке
state(толькоstate.json) и переиспользуется между прогонами. Уже выполненная в тот же день (МСК) задача пропускается. run_once.pyвозвращает ненулевой код, если хотя бы одна должная задача упала — такой прогон виден как красный в Actions, а неуспешная задача остаётся незаписанной в state и будет повторена.
- Для cron на public-репозитории: если 60 дней не было активности,
GitHub отключает
schedule— периодически коммитьте. - Частота опроса и
LAG_MAXзадаются вручную в workflow/флаге--lag-max.
Проверьте:
- установлен ли Python;
- активировано ли
venv; - выполнен ли
pip install -r requirements.txt; - заполнен ли
private.txt.
Удалите старую сессию и запустите заново:
rm session_name.session
python3 main.pyПроверьте:
- нет ли пробелов в начале или конце;
- не вставился ли ключ с переносом строки;
- ключ действительно создан в Google AI Studio.
Это значит:
- либо кончился бесплатный лимит модели;
- либо у ключа вообще нет доступной free-tier квоты для этой модели;
- либо у всех ключей из ротации общая квота и она уже выработана.
Что можно сделать:
- уменьшить период анализа;
- уменьшить число чанков;
- увеличить
GEMINI_CHUNK_MAX_CHARS; - добавить независимые ключи;
- перейти на платный tier.
Попробуйте:
- уменьшить
GEMINI_CHUNK_MAX_CHARS; - понизить
GEMINI_REASONING_EFFORT; - сделать промпт более анти-схлопывающим.
Попробуйте:
GEMINI_REASONING_EFFORT=mediumrequirements.txt сейчас соответствует коду.
Используются:
telethonopenaipython-dotenvhttpxtelegraphapscheduler(планировщик ежедневных саммари иrun_once.py)
run_once.py(GitHub Actions) импортируетmain, поэтомуapschedulerобязателен вrequirements.txtдля обеих площадок.
- Никогда не коммитьте
private.txt. - Не коммитьте
*.session. - Не публикуйте API-ключи в скриншотах и логах.
- Если ключ утек, перевыпустите его.