Skip to content

About

A Python bot for sending messages to Telegram chats at a scheduled time.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

TelegramNewsletter

TelegramNewsletter управляет периодическими публикациями через Telegram-бота, а отправляет их от имени отдельного пользовательского Telegram-аккаунта. Поддерживаются несколько групп, последовательности из текстов и медиаальбомов с подписями, готовые интервалы 1/3/7 дней, ручной интервал от 5 минут и настраиваемая пауза между сообщениями.

Что понадобится

  • Ubuntu-сервер с доступом в интернет и правами root/sudo; Docker Engine и Docker Compose plugin установщик добавит автоматически, если их ещё нет;
  • токен управляющего бота от @BotFather;
  • api_id и api_hash приложения с https://my.telegram.org;
  • Telegram user ID владельца панели;
  • отдельный Telegram-аккаунт, уже вступивший в целевые группы.

Управляющего бота добавлять в целевые группы не требуется. Сообщения публикует пользовательский аккаунт и только там, где у него есть обычное право писать.

Установка на Ubuntu одной командой

Загрузите проект на сервер, перейдите в его каталог и выполните:

bash install.sh

Скрипт запросит в консоли токен, API-реквизиты и числовой ID администратора, при необходимости установит Docker из официального APT-репозитория, создаст закрытый .env, проверит токен через Telegram, соберёт контейнеры и запустит интерактивную авторизацию аккаунта-отправителя. Вставленные токен и API Hash видны в консоли. Пустые значения и неверный формат не принимаются — установщик повторяет вопрос. Код входа и пароль 2FA вводятся только в консоли Ubuntu.

Нужен именно числовой Telegram user ID, а не @username. Его можно узнать, например, у @userinfobot. Часовой пояс при установке не запрашивается: после запуска он выбирается через кнопку «⚙️ Настройки» в управляющем боте.

После авторизации скрипт применит миграции при запуске приложения и поднимет все сервисы. Настройки и Telethon-сессия сохраняются в Docker volumes и переживают перезапуск контейнеров.

Первый запуск

  1. Откройте управляющего бота и отправьте /start.
  2. Откройте «⚙️ Настройки» и выберите часовой пояс.
  3. Нажмите «🔄 Синхронизировать».
  4. Проверьте список через «💬 Чаты».
  5. Нажмите «➕ Создать рассылку» и пройдите мастер.
  6. Для проверки откройте созданную рассылку и нажмите «🧪 Отправить тест».

Первый плановый запуск выбирается автоматически: ближайшее будущее указанное локальное время. После этого используется выбранный интервал от опорного момента. В ручном режиме можно вводить 5m, 30 мин, 2h, 3d или просто число минут. Для паузы между сообщениями доступны готовые варианты от 1 секунды до 5 минут и ручной ввод от 1 секунды до 1 часа: 30, 30s, 5m или 5 мин. Бот сначала последовательно отправляет все сообщения в первый чат, затем переходит к следующему. Пауза применяется между сообщениями внутри одного чата. Опциональная адаптивная пауза использует выбранное время как минимум. При FloodWait она увеличивается как минимум до запрошенного Telegram времени, а при сетевых и других временных ошибках удваивается, но не превышает 1 час. В течение одного запуска адаптивная пауза никогда не уменьшается. Короткий FloodWait ожидается согласно требованию Telegram, а превышающий настроенный безопасный предел останавливает рассылку и ставит её на паузу. На экране периода можно включить «Отправить сразу»: тогда после создания выполняется одна немедленная отправка, а последующие запуски продолжаются по выбранному расписанию. После полного запуска рассылки бот присылает один итоговый отчёт с числом успешных доставок и списком чатов с ошибками.

При начале каждого запуска бот создаёт одно сообщение прогресса с процентами доставленных, ошибочных и оставшихся сообщений, а также примерным временем окончания. Сообщение обновляется примерно раз в минуту. Кнопка паузы останавливает запуск после текущей операции; во время паузы можно изменить базовую задержку и адаптивный режим, затем продолжить. Продолжение использует тот же идентификатор запуска и не отправляет повторно доставки, уже отмеченные как успешные. Перед первым ещё не доставленным сообщением после продолжения бот заново выдерживает настроенную паузу — следующее сообщение не уходит мгновенно.

Кнопка «🧪 Отправить тест» отправляет всю рассылку в том же порядке и с той же паузой между элементами либо без ожидания между сообщениями — режим выбирается перед назначением. Назначением можно выбрать «Избранное» аккаунта-отправителя или любой доступный синхронизированный чат. Тест не создаёт боевые записи доставок, не сдвигает расписание и не влияет на последующий запуск. На последнем шаге мастера можно выбрать «🧪 Сначала отправить тест». В этом случае рассылка сохраняется на паузе, а после теста появляется кнопка запуска. Выбор «Отправить сразу» сохраняется и выполняется после подтверждения боевого запуска.

Для временных ошибок обычной текстовой доставки и безопасно повторяемых ошибок скачивания медиа выполняются три повтора: через 1, 5 и 15 минут. Время следующей попытки хранится в PostgreSQL и переживает перезапуск. Успешные и окончательно ошибочные доставки повторно в рамках того же запуска не отправляются. Неопределённый сбой непосредственно во время отправки альбома не повторяется автоматически: Telegram мог уже принять файлы, поэтому повтор создал бы дубликат.

Один элемент рассылки может содержать одно фото, одно видео или Telegram-альбом из 2–10 фото и видео в любой комбинации с общей подписью. Альбом отправляется в чат как единое сообщение.

В разделе «📋 Рассылки» каждая карточка показывает состояние: ожидание запуска, очередь, текущую отправку, тест, ручную паузу или незавершённый запуск. Кнопка «Просмотр» показывает чаты и содержимое сообщений. Через «Редактировать» можно изменить название, чаты, всю последовательность сообщений, паузу, адаптивный режим и расписание. На время полного редактирования рассылка ставится на паузу. Перед удалением бот отдельно запрашивает подтверждение. Удаление сначала останавливает текущую обычную или тестовую отправку после уже начатой Telegram-операции, отменяет её очередь и только затем удаляет данные.

Медиафайлы постоянно на диске приложения не хранятся. PostgreSQL содержит только Telegram file_id. Во время конкретной отправки управляющий бот загружает фото или видео во временный буфер оперативной памяти, пользовательский аккаунт отправляет его, после чего буфер освобождается. Поэтому диск медиаархивом не заполняется, но один большой альбом временно использует RAM примерно в размере всех его файлов.

Приложение присылает администраторам уведомление после запуска или перезапуска. Раз в минуту оно проверяет PostgreSQL, авторизацию и соединение аккаунта-отправителя, а также заполнение диска. Тревога отправляется один раз при появлении проблемы и один раз после восстановления. Незавершённый активный запуск после перезапуска продолжается с прежним идентификатором; уже успешные доставки пропускаются. Незавершённые рассылки на ручной паузе самостоятельно не запускаются.

Параметры мониторинга в .env необязательны:

MONITOR_INTERVAL_SECONDS=60
DISK_WARNING_PERCENT=90
DISK_CHECK_PATH=/app/data

Управление сервером

docker compose ps
docker compose logs -f app
docker compose restart app
docker compose down
docker compose up -d

Повторная авторизация аккаунта после отзыва сессии:

docker compose stop app
docker compose run --rm --no-deps app python -m botpy.auth
docker compose up -d app

Основной контейнер нужно остановить до авторизации: оба процесса используют один SQLite-файл Telethon-сессии, и одновременный доступ приводит к database is locked. install.sh делает эту остановку автоматически.

Обновление после загрузки новой версии:

docker compose up -d --build

При загрузке файлов через терминал не удаляйте существующий .env и убедитесь, что клиент передаёт скрытые файлы. Если .env всё же потерян, install.sh попытается восстановить настройки из старого контейнера приложения, не создавая новый пароль БД.

Локальные проверки

Все проверки можно выполнить без локальной установки Python:

docker compose build app
docker compose run --rm --no-deps app pytest
docker compose run --rm --no-deps app ruff check .
docker compose run --rm --no-deps app ruff format --check .
docker compose run --rm --no-deps app mypy src

Тесты не используют реальную Telegram-сессию и не отправляют сообщения.

Безопасность и ограничения

  • Не передавайте .env и содержимое Docker volume sender_data третьим лицам.
  • Не коммитьте файлы *.session: сессия предоставляет доступ к аккаунту.
  • При утечке завершите сессию в Telegram → Настройки → Устройства.
  • Публикуйте только в группах, где это разрешено правилами. Жалобы могут привести к ограничениям или блокировке аккаунта.
  • Приложение обрабатывает FloodWait, не выполняет массовое вступление и не пытается обходить ограничения Telegram.

Границы первой версии

Сейчас поддерживаются текст, фотографии, видео и смешанные фото/видеоальбомы до 10 файлов с необязательной подписью в группах и супергруппах. Документы, каналы, темы форумов и несколько аккаунтов-отправителей будут добавляться отдельными этапами.

About

A Python bot for sending messages to Telegram chats at a scheduled time.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages