Telegram-бот для игры Encounter. Помогает команде пробивать коды, следит за таймерами уровня и разгружает штурманов от рутины при работе с движком.
Что умеет:
- Пробитие кодов и бонусов прямо из игрового чата (
&en123,#en123,;en123 //комментарий), автоопределение бонусных кодов, гео-коды. - Метки и сектора: сводка по секторам уровня, списки открытых/закрытых меток и бонусов, схема дохода, подсказки, сообщения организатора.
- Таймеры: уведомления о подсказках и автопереходе за 15 и 5 минут и в момент события, скриншот движка на каждое событие.
- Точки на местности:
/setpoint,/listpoint,/closepoint, приём Telegram-venue, карта точек. - Штабной чат (
/game shtab) и инфоканал для дублирования событий. - Скриншоты движка через headless Chromium (
/screenshot,/getscreens).
Полный список команд — /help в самом боте (см. также bot.php).
Бот работает только на long polling, входящий HTTP-порт и webhook не нужны. Внутри контейнера крутятся три процесса:
| Процесс | Назначение |
|---|---|
polling.php |
Telegram long polling → handleUpdate(); подтверждает update только после обработки |
daemon.php |
обработка просроченных таймеров (подсказка, автопереход, события) |
cron.php |
периодический проход по всем играм, таймерам и секторам |
Состояние (игры, коды, таймеры, настройки чатов, очки, точки, координаты)
хранится в одном файле SQLite — /data/enxbot.sqlite. Схема создаётся и
мигрируется автоматически при старте.
PHP-биндинги к движку и libencx берутся из публичного репозитория
skrashevich/encx-cli (тег
v0.26.0) и собираются в builder-стадии образа. Требуются биндинги и
библиотека версии v0.26.0 или новее: бот использует resolveEngine() и
Helpers::levelSectorProgress().
- Docker 24+ с плагином Compose v2 — для всех вариантов, кроме запуска «на голом PHP».
- Токен бота от @BotFather.
- Данные аккаунта Encounter с правами на нужную игру (домен, логин, пароль).
Репозиторный docker-compose.yml уже настроен на образ
ghcr.io/skrashevich/enxbot:latest.
cp .env.example .env
# заполните BOT_TOKEN, BOT_USERNAME, ENCRYPTION_KEY (и, при желании, ADMIN_USERNAME)
docker compose up -d
docker compose logs -fОбновление до свежего образа:
docker compose pull
docker compose up -dЕсли образ в GHCR приватный, сначала выполните
docker login ghcr.io(username — логин GitHub, password — PAT с правомread:packages) либо сделайте пакет публичным в настройках GitHub Packages.
Тот же файл содержит build: ., поэтому образ можно собрать из исходников,
не заходя в реестр:
cp .env.example .env # заполнить обязательные переменные
docker compose up -d --buildСборка тянет encx-cli из GitHub, поэтому нужен доступ в сеть.
docker run -d \
--name enxbot \
--restart unless-stopped \
-v enxbot-data:/data \
-e BOT_TOKEN='123456:ваш-telegram-токен' \
-e BOT_USERNAME='my_encounter_bot' \
-e ENCRYPTION_KEY='длинная-случайная-строка' \
-e ADMIN_USERNAME='telegram_admin' \
ghcr.io/skrashevich/enxbot:latestСобственная сборка образа: docker build -t enxbot . && docker run ... enxbot.
Именованный том enxbot-data хранит /data/enxbot.sqlite и переживает
пересоздание контейнера; удаление контейнера том не трогает.
Подходит для отладки и нестандартных окружений. Docker-вариант проще, потому что сам собирает биндинги движка.
-
PHP 8.1+ (проверяется на 8.4–8.5) с расширениями
ffi,pdo_sqlite,curl,openssl,mbstring,zip. -
Go 1.27+ и
git— для сборки PHP-биндинговencx-cli:git clone --branch v0.26.0 --depth 1 https://github.com/skrashevich/encx-cli /opt/encx-cli bash /opt/encx-cli/bindings/php/build.sh export ENCX_BINDINGS_PATH=/opt/encx-cli/bindings/php -
(опционально) Chromium +
chromium-driverи Python 3 — для/screenshotи/getscreens. Путь к обёртке задаётся константойPHANTOMJS. -
Создайте
config.phpв корне репозитория:<?php define('BOT_TOKEN', '123456:ваш-telegram-токен'); define('API_URL', 'https://api.telegram.org/bot'.BOT_TOKEN.'/'); define('ENCRYPTION_KEY', 'длинная-случайная-строка'); define('BOT_USERNAME', 'my_encounter_bot'); // без @ define('ADMIN_USERNAME', 'telegram_admin'); // без @, можно '' define('PHANTOMJS', '/usr/local/bin/enxbot-screenshot'); // обёртка над Chromium // define('PUBLIC_URL', 'https://bot.example.com'); // только для ссылок map.php $sqlite_path = __DIR__.'/data/enxbot.sqlite'; // каталог создаётся автоматически
-
Запустите три процесса (каждый — своим сервисом systemd/supervisor или в отдельном терминале):
php polling.php php daemon.php while :; do php cron.php; sleep 60; done
В Docker всё задаётся переменными окружения (см. .env.example), в
bare-metal — одноимёнными константами в config.php.
| Переменная | Обяз. | По умолчанию | Назначение |
|---|---|---|---|
BOT_TOKEN |
да | — | токен Telegram-бота |
BOT_USERNAME |
да | — | имя бота без @ |
ENCRYPTION_KEY |
да | — | ключ шифрования паролей Encounter в БД |
ADMIN_USERNAME |
нет | '' |
главный администратор бота (username без @) |
PUBLIC_URL |
нет | — | базовый URL для ссылок на map.php и адреса точек |
ENXBOT_SQLITE_PATH |
нет | /data/enxbot.sqlite |
путь к файлу БД |
ENXBOT_CRON_INTERVAL |
нет | 5 |
пауза между проходами cron.php, секунды (одна модель на игру за проход) |
ENXBOT_POLL_TIMEOUT |
нет | 30 |
таймаут Telegram long polling, 1..50 секунд |
ENXBOT_IDLE_TIMEOUT |
нет | 86400 |
тишина в чате до автоостановки игры, секунды |
ENXBOT_CRON_LOCK_TIMEOUT |
нет | 300 |
протухание блокировки cron.php, секунды |
API_URL |
нет | Telegram Bot API | альтернативный endpoint (полезно для тестов) |
GEOCODER_URL |
нет | — | сервис геокодинга для адресов точек |
ENCX_ENGINE |
нет | auto |
backend движка: auto / legacy / new |
ENCX_USE_HTTP |
нет | auto | принудительный HTTP (локальные адреса определяются сами) |
ENCX_INSECURE_TLS |
нет | false |
отключить проверку TLS для нестандартного домена Encounter |
В режиме ENCX_ENGINE=auto движок определяется методом resolveEngine()
библиотеки encx-cli. Только результат с definitive=true сохраняется
в SQLite (engine_cache). Последующие действия, другие процессы
бота и перезапуски используют сохранённый выбор без повторной сетевой проверки.
Определение выполняется до передачи сессии, а подтверждённый движок закрепляется
в клиенте на всё действие. Временный fallback (definitive=false) не сохраняется
и оставляет клиент в auto, чтобы библиотека могла повторить проверку.
Старые записи кеша без подтверждения автоматически проверяются заново.
Явные legacy и new имеют приоритет над кешем.
Если домен перенесли на другой движок, задайте его явно либо удалите запись
домена из engine_cache и перезапустите бота для нового определения.
Подробнее о Docker-специфике — в DOCKER.md.
Команды доступны администраторам чата и бота. Добавьте бота в игровой чат и введите по порядку:
/game domain moscow.en.cx # домен игры
/game login ЛОГИН # логин движка
/game pass ЗАШИФР_ПАРОЛЬ # см. /encrypt в личке боту
/game id 12345 # ID игры из адресной строки
/game auth # авторизация на движке
/game start # старт бота в этом чате
Зашифрованный пароль получают командой /encrypt пароль в личном чате с
ботом (в открытом виде пароль в БД не хранится). Прочие команды управления —
/game print, /game stop, /game restart, /game delete,
/game codes on|off, /game shtab -100…, /game infochannel @channel.
В /settings есть переключатель «Принимать DR/ДР-коды без префикса»
(по умолчанию выключен). При включении сообщения dr1, др1, ДР1
распознаются как коды; разрешён комментарий после //. Сообщение с обычным
текстом после кода автоматически не отправляется. Префикс др приводится к
dr, русские буквы в остальной части кода исправляются на английскую
раскладку; комментарий сохраняется. С явным префиксом, например &др1,
преобразование работает независимо от переключателя. Требование примечания
и режим записи без отправки в движок продолжают действовать.
Вся персистентность — файл enxbot.sqlite в томе /data. Горячий бэкап без
остановки бота:
docker compose exec -T enxbot php -r '$d=new PDO("sqlite:/data/enxbot.sqlite"); $d->exec("VACUUM INTO \"/data/backup.sqlite\"");'
docker compose cp enxbot:/data/backup.sqlite ./enxbot-backup.sqliteЛибо просто скопировать enxbot.sqlite (+ -wal, -shm) при остановленном
контейнере.
GitHub Actions (.github/workflows/docker-image.yml) собирает и публикует
multi-arch образ (linux/amd64, linux/arm64) в GitHub Container Registry:
| Событие | Тег образа |
|---|---|
| push в ветку по умолчанию | latest, sha-<короткий-хеш> |
| push произвольной ветки | sha-<короткий-хеш> |
тег v* (например v1.2.0) |
v1.2.0 |
| pull request | только сборка, без публикации |
Аутентификация — встроенным GITHUB_TOKEN (packages: write), отдельные
секреты не нужны. После первой публикации при необходимости сделайте пакет
enxbot публичным в настройках GitHub Packages.
Смоук-стенд, e2e и прогоны против боевого движка описаны в
tests/README.md:
tests/run.sh # смоук: php -l, SQLite, encx-mock, 40+ сценариев апдейтов
tests/e2e.sh # сквозной прогон через реальные моки Telegram и движка