Skip to content

krotname/TelegramResenderBot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

82 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Telegram Resender

CI CodeQL Coverage OpenSSF Scorecard OpenSSF Best Practices License: GPL-3.0 Python

Telegram Resender Bot

English README

Что это

Этот бот проверяет текстовые сообщения пользователей по белому списку и пересылает разрешенные сообщения в указанный чат/группу.

Начиная с 1.1.0, бот по умолчанию говорит по-русски, показывает шаблон заявки, различает причины отказа и имеет диагностический режим без запуска Telegram polling.

Возможности

  • /start, /help, /template, /avto для пользовательского сценария.
  • Белый список числовых Telegram user ID из CSV.
  • Понятный отказ для неизвестного пользователя и отдельный отказ для пользователя без данных отправителя.
  • Защита от случайной пересылки коротких приветствий вместо заявки.
  • Ответ на неподдерживаемые типы сообщений: фото, документы, стикеры, голосовые.
  • Диагностика конфигурации через telegram-resender doctor.
  • Проверка обязательных полей заявки и опциональное подтверждение перед пересылкой.
  • Админские команды для статуса и перезагрузки whitelist без рестарта.
  • Опциональные multi-route правила через routes.json.
  • SQLite delivery/pending state, retry/backoff и идемпотентность по request id.
  • Docker, docker-compose, systemd и health-check для production.
  • Детерминированный формат пересылки с request id и временем заявки.

Быстрый старт

python -m venv .venv
.venv\Scripts\activate
pip install -e .[dev]
copy .env.example .env      # Windows
# или: cp .env.example .env  # Linux/macOS
telegram-resender doctor
telegram-resender

Если doctor сообщает об ошибке, заполните .env до запуска polling.

Конфигурация

Переменная Обязательная Описание
TELEGRAM_RESENDER_BOT_TOKEN да токен Telegram-бота
TELEGRAM_RESENDER_FORWARD_CHAT_ID да id чата/группы для пересылки
TELEGRAM_RESENDER_WHITELIST_PATH нет путь к whitelist.csv, по умолчанию whitelist.csv
TELEGRAM_RESENDER_ROUTES_PATH нет путь к JSON-файлу маршрутов
TELEGRAM_RESENDER_LOCALE нет ru или en, по умолчанию ru
TELEGRAM_RESENDER_CONFIRM_BEFORE_FORWARD нет true, чтобы показывать preview и ждать /confirm
TELEGRAM_RESENDER_PENDING_REQUEST_TTL_SECONDS нет срок жизни preview в секундах, по умолчанию 900
TELEGRAM_RESENDER_DELIVERY_LEASE_SECONDS нет timeout stale-владельца доставки/подтверждения, по умолчанию 300
TELEGRAM_RESENDER_ADMIN_IDS нет Telegram user id администраторов через запятую
TELEGRAM_RESENDER_STORAGE_PATH нет SQLite delivery/pending state, по умолчанию telegram_resender.sqlite3
TELEGRAM_RESENDER_DELIVERY_MAX_ATTEMPTS нет попытки отправки в Telegram, по умолчанию 3
TELEGRAM_RESENDER_DELIVERY_RETRY_BACKOFF нет базовая задержка retry в секундах
TELEGRAM_RESENDER_LOG_LEVEL нет DEBUG, INFO, WARNING, ERROR, CRITICAL
TELEGRAM_RESENDER_LOG_FORMAT нет TEXT или JSON, по умолчанию TEXT
TELEGRAM_RESENDER_POLLING_TIMEOUT нет таймаут polling, по умолчанию 30
TELEGRAM_RESENDER_REQUEST_ACCEPTED_MESSAGE нет переопределение текста успешной заявки
TELEGRAM_RESENDER_ACCESS_DENIED_MESSAGE нет переопределение текста отказа неизвестному пользователю

Формат whitelist (по одному неизменяемому числовому Telegram user ID в строке; ID можно узнать через /whoami):

123456789
987654321

Формат заявки

Пользователь может вызвать /template или /avto и отправить текст:

Объект/здание: Башня А
Дата и время прибытия: 12.06.2026 10:30
Автомобиль: Ford Focus
Госномер: А123ВС
Комментарий: встреча с отделом эксплуатации

Пока бот принимает только текст. Медиа и документы не пересылаются. Если заявка со служебным заголовком или preview превышает лимит Telegram, бот попросит сократить комментарий или другие поля.

Обязательные поля: объект/здание, дата и время прибытия, автомобиль, госномер. Если включить TELEGRAM_RESENDER_CONFIRM_BEFORE_FORWARD=true, бот покажет preview заявки и отправит ее администратору только после /confirm. Для нескольких preview можно указать ID: /confirm <request_id> или /cancel <request_id>; команды без ID относятся к последней заявке. Pending preview хранится в SQLite, переживает рестарт процесса и истекает через настроенный TTL.

Администрирование

  • /whoami показывает Telegram user id и chat id. Команда доступна всем, чтобы администратор мог узнать свой id для .env.
  • /admin_status показывает версию, locale, целевой чат, размер whitelist, число администраторов и режим подтверждения.
  • /whitelist_count показывает текущий размер whitelist.
  • /reload_whitelist перечитывает CSV whitelist без рестарта процесса.

Все команды кроме /whoami доступны только id из TELEGRAM_RESENDER_ADMIN_IDS.

Маршруты

Если TELEGRAM_RESENDER_ROUTES_PATH не задан, бот использует один маршрут из TELEGRAM_RESENDER_FORWARD_CHAT_ID. Для нескольких целей создайте JSON по образцу routes.example.json:

{
  "routes": [
    {
      "name": "tower-a",
      "target_chat_id": -1002222222222,
      "allowed_user_ids": [123456789],
      "allowed_usernames": [],
      "keywords_any": ["Башня А"],
      "keywords_none": ["отмена"],
      "template": "[{route}]\n{request}",
      "enabled": true
    }
  ]
}

Заявка отправляется во все активные маршруты, где совпали пользователь и keyword-фильтры. Для маршрутизации с контролем доступа используйте allowed_user_ids. Поле allowed_usernames сохранено для миграционной совместимости, но Telegram username изменяем: этот legacy-фильтр допустим только как незащитная метка поверх общего числового whitelist. Если заданы оба поля, должны совпасть оба. Дубли JSON-ключей, пустые и некорректные фильтры отклоняются при старте. Если одному target chat соответствуют несколько правил, применяется первое совпавшее правило из файла: одна заявка формирует один детерминированный payload на destination.

Надежность доставки

Бот ведет SQLite-журнал доставок. Для каждой пары request_id + target_chat_id хранится статус pending, delivered или failed, отправитель и последняя ошибка. Если такая пара уже доставлена, повторная обработка того же request id не отправит сообщение второй раз. Атомарный SQLite lease с owner/version также не дает параллельным handler-задачам одновременно отправить одну пару. Stale lease можно занять заново после TELEGRAM_RESENDER_DELIVERY_LEASE_SECONDS.

telegram-resender doctor --storage-check
telegram-resender health
telegram-resender export-requests --since 2026-06-12

Развертывание

Docker:

copy .env.production.example .env.production
mkdir data
copy whitelist.example.csv data\whitelist.csv
docker compose up -d --build

Docker env template: .env.production.example. Для systemd используйте deploy/telegram-resender.service вместе с .env.systemd.example: оба используют /opt/telegram-resender/data для изменяемых файлов.

cp .env.systemd.example /opt/telegram-resender/.env.production

Для production-логов включите:

TELEGRAM_RESENDER_LOG_FORMAT=JSON

Релизы и Supply Chain

  • Docker base image закреплен по digest в Dockerfile.
  • Python runtime/dev/audit зависимости ставятся из hash-locked файлов requirements*.lock.
  • GitHub Actions закреплены по commit SHA.
  • Релизный workflow собирает wheel и sdist, публикует SHA256SUMS.txt и GitHub provenance attestation.
  • Правила обновления зависимостей описаны в docs/DEPENDENCY_POLICY.md.

Проверка релизных артефактов:

sha256sum -c SHA256SUMS.txt
gh attestation verify telegram_resender-*.whl --repo krotname/TelegramResenderBot

Ограничения

  • Это bot-based intake/forwarding, не userbot.
  • Бот не обходит protected/restricted Telegram-чаты.
  • Медиа, документы, voice и polls пока не пересылаются как payload.
  • Отправку в Telegram и следующий SQLite commit невозможно сделать одной атомарной операцией. Если процесс завершится после приема сообщения Telegram, но до записи delivered, возможна одна повторная отправка после истечения stale lease.
  • Отправка confirmation preview и публикация pending-строки в SQLite тоже не являются одной транзакцией. Сбой в узком промежутке может оставить видимый preview, который придется отправить заново. Pending публикуется после успешного ответа Telegram, поэтому неотправленный preview не заменяет более старую подтверждаемую заявку.
  • Известные retry waits автоматически продлевают оба lease. Но отдельный Telegram API call, зависший дольше TELEGRAM_RESENDER_DELIVERY_LEASE_SECONDS, может быть занят заново; задавайте lease больше transport timeout текущего deployment.
  • AI rewrite/translate/digest не реализованы.
  • Hosted SaaS, mobile app и web dashboard не входят в текущую self-hosted область.

Тесты и качество

  • tests/unit — чистые unit-тесты доменной логики
  • tests/integration — сборка сервиса и контура настроек
  • tests/conversation — сценарии пользовательского диалога
  • tests/security — проверки безопасности конфигурации

Запуск:

pytest
ruff check .
mypy src tests

Roadmap и UX-аудит

Подробный UX/конкурентный аудит и план следующих версий: docs/ux-competitive-roadmap.ru.md.

Вклад в проект

Смотрите CONTRIBUTING.md и CODE_OF_CONDUCT.md.

Безопасность

Смотрите SECURITY.md и docs/DEPENDENCY_POLICY.md.

About

Telegram-бот для пересылки сообщений по правилам белого списка: маршрутизация, конфигурация окружения, тесты и CI для контроля качества.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors