Fixes Monolog 'Failed to open stream: Permission denied' on storage/logs when host files are owned by pkirillw but php-fpm runs as www-data. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
max-bot-test
Тестовый бот, демонстрирующий весь публичный API библиотеки
pkirillw/max-bot-api-php.
Получает обновления через PSR-15 webhook (Slim 4 + Nyholm PSR-17), покрывает все 6
endpoint groups, 13 типов апдейтов, все типы кнопок и вложений. Запускается в Docker
Compose (php-fpm + nginx на :8080). Публичный HTTPS-адрес для webhook'а
подключаете своим туннелем (ngrok, cloudflared, обратный прокси и т.д.).
Что внутри
- 6 endpoint groups:
Bots,Chats,Messages,Uploads,Subscriptions,Debugs. - 13 типов апдейтов — отдельный handler на каждый.
- Все 7 типов inline-кнопок (
callback,link,message,clipboard,request_contact,request_geo_location,open_app) + все 3Intent-окраса. - Все варианты загрузок: file / URL / bytes / base64, отдельно для фото и media.
- Все типы вложений: photo / audio / video / file / location / contact / sticker.
- Symfony Console CLI для subscribe / unsubscribe / list / bot info / selftest.
- PHPUnit: unit-тесты на парсинг команд и клавиатуры, integration-тесты на webhook secret-check.
Структура
src/
├── Bootstrap.php — Slim + DI container + env loader
├── Handler/
│ ├── UpdateRouter.php — dispatch UpdateInterface → handler
│ ├── AbstractUpdateHandler.php — общее логирование + error handling
│ └── Update/ — 13 handler'ов под каждый UpdateType
├── Scenario/ — обработчики команд (/help, /chats, /keyboard, …)
├── Command/ — bin/console команды
├── Keyboard/ — KeyboardFactory со всеми типами кнопок
├── Logger/ — Monolog factory
└── Util/
├── CommandRouter.php — command name → ScenarioInterface
└── ParsedCommand.php — парсер `/cmd arg1 arg2` и `/cmd:arg`
config/
├── container.php — PHP-DI definitions
└── routes.php — /webhook + /health
public/index.php — Slim entrypoint
bin/console — CLI entrypoint
Установка
git clone <this repo> max-bot-test
cd max-bot-test
cp .env.example .env
Заполните .env:
BOT_TOKEN— токен бота из @MasterBot или панели MAX.MAX_BOT_API_SECRET— общий секрет для webhook. Сгенерируйте:openssl rand -hex 32.WEBHOOK_URL— публичный HTTPS-URL, по которому MAX будет присылать апдейты (напримерhttps://bot.example.com/webhook). Поднять публичный доступ можно любым способом: ngrok, cloudflared, Caddy/Nginx на VPS и т.п.DEBUG_CHAT_ID,SELFTEST_CHAT_ID— ID чата, в который бот может слать служебные сообщения (обычно ваш диалог с ботом).
Библиотека pkirillw/max-bot-api-php подключена через repositories в
composer.json как path-симлинк на /var/www/max-php-client внутри контейнера
(через volume ../max-php-client в docker-compose.yml). Если библиотека лежит
в другом месте — поправьте volume и/или URL в composer.json.
Запуск
make build # собрать Docker-образы
make up # запустить app + nginx (порт :8080)
make install # composer install
Пробросьте свой публичный HTTPS на localhost:8080 и впишите URL в .env:
WEBHOOK_URL=https://your-public-host/webhook
make up # перезапустить чтобы подхватить новый env
make subscribe # эквивалент: docker compose exec app bin/console webhook:subscribe
Готово. Откройте диалог с ботом в MAX, отправьте /help.
Команды бота
Полный список — в /help (или в src/Scenario/HelpScenario.php). Кратко:
Bot: /bot, /bot_patch <name>.
Chats: /chats, /chat <id>, /members <id>, /admins <id>,
/action <id> <typing_on|typing_off|mark_seen|sending_photo|sending_video|sending_audio>,
/pin <id> <mid>, /edit_chat <id> <title>, /add_member <id> <userId>,
/remove_member <id> <userId>, /leave <id>.
Messages: /send_text <text>, /send_markdown <text>, /send_html <text>,
/reply <mid> <text>, /forward <mid>, /edit <mid> <text>, /delete <mid>,
/messages <id> [count], /message <mid>, /markup <userId>, /notify <text>,
/disable_preview <url>, /keyboard.
Uploads: /upload_photo_file [path], /upload_photo_url <url>,
/upload_photo_bytes, /upload_photo_base64, /upload_audio [path],
/upload_video [path], /upload_file [path],
/upload_url <audio|video|file> <url>.
Attachments: /attach_location <lat> <lng>, /attach_contact <name> <id>,
/attach_sticker <code>.
Phone: /phone_check <phone>, /phone_list <phone1,phone2>.
Debug: /debug <on|off|raw|err|status>.
CLI
bin/console webhook:subscribe [--url=…] [--secret=…] [--types=msg_created,…]
bin/console webhook:unsubscribe [url]
bin/console subs:list
bin/console bot:info
bin/console selftest # дымовой тур по всем endpoint groups
Тесты
make test
# или локально:
vendor/bin/phpunit
Логи
storage/logs/app.log
make logs # app + nginx в реальном времени
Известные особенности
- Long polling не поддерживается библиотекой. Получение событий — только webhook. Запуск без публичного URL невозможен (используйте cloudflared).
DebugScenario::offне может выключить debug-чат в рантайме —Debugsне выставляет chatId обратно в null. Перезапустите контейнер безDEBUG_CHAT_ID.- При
attachment.not.readyбиблиотека сама делает до 3 retries с экспоненциальной задержкой — повторных попыток на уровне бота не требуется.
Лицензия
Apache-2.0 — как и сама библиотека.