Тонкий Laravel-адаптер для MAX Messenger Bot API поверх framework-agnostic ядра
geekcodev/max-php-client.
Пакет отвечает только за «Laravel-клей»: конфиг, DI, фасад, вебхук-роутинг, очередь. Вся бизнес-логика API (DTO,
эндпоинты, ретраи, rate limit, безопасность, загрузка медиа) живёт в ядре — см. его документацию и OpenAPI-спецификацию
max-openapi.
- PHP ^8.4
- Laravel ^12.0|^13.0
geekcodev/max-php-client^1.0
composer require geekcodev/laravel-max-clientСервис-провайдер GeekCo\LaravelMaxClient\MaxServiceProvider и alias Max
подхватываются автоматически (package discovery). Затем опубликуйте конфиг:
php artisan vendor:publish --tag=laravel-max-client-configМинимально необходима одна переменная — токен бота:
MAX_API_TOKEN=your-bot-access-tokenВсе доступные переменные (имена см. в .env.example):
| Переменная | По умолчанию | Описание |
|---|---|---|
MAX_API_TOKEN |
— | Токен бота (заголовок Authorization) |
MAX_BASE_URI |
https://platform-api2.max.ru |
Базовый URI API (домен platform-api2) |
MAX_WEBHOOK_ENABLED |
false |
Регистрировать вебхук-роут |
MAX_WEBHOOK_SECRET |
— | Секрет вебхука (без него роут не включается) |
MAX_WEBHOOK_QUEUE |
default |
Очередь для джобов обработки Update |
MAX_WEBHOOK_PATH |
/max/webhook |
Путь вебхук-роута |
MAX_RETRY_* |
3 / 1 / 30 / 2 / false | Ретраи (попытки/базовая/макс. задержка/фактор/не-идемпотентные) |
MAX_RATE_LIMIT_* |
2.0 / 2.0 | Token bucket: токенов в секунду / максимум |
Токен и секрет никогда не должны попадать в код, логи или коммиты — только env.
Фасад Max резолвит единый экземпляр ApiClient из контейнера:
use GeekCo\LaravelMaxClient\Facades\Max;
use GeekCo\MaxPhpClient\Dto\Recipient;
use GeekCo\MaxPhpClient\Dto\NewMessageBody;
$me = Max::getMe();
Max::sendMessage(
new Recipient(chatId: $chatId),
new NewMessageBody(text: 'Привет!'),
);Список доступных методов — в ядре GeekCo\MaxPhpClient\ApiClient.
Полные рабочие примеры — в каталоге examples/:
basic-usage.php (фасад), webhook-listener.php (обработка апдейтов),
custom-http-client.php (подмена PSR-18 клиента),
long-polling-local-dev.md (настройка и запуск Long Polling локально и в Docker).
По умолчанию используется Guzzle с опциями http.options. Чтобы подменить транспорт, зарегистрируйте свою реализацию
Psr\Http\Client\ClientInterface в контейнере:
// AppServiceProvider
$this->app->instance(\Psr\Http\Client\ClientInterface::class, $yourClient);-
Включите вебхук и задайте секрет:
MAX_WEBHOOK_ENABLED=true MAX_WEBHOOK_SECRET=some-secret
Роут
POST /max/webhook(имяmax.webhook) регистрируется только при включённом флаге и заданном секрете (fail-closed). Роут вне CSRF, сthrottle:60,1(настраивается вwebhook.middlewareконфига). Приёмка проверяетX-Max-Bot-Api-Secretчерезhash_equals(иначе 401). -
Подпишитесь на событие доставки
MaxUpdateReceived:// app/Providers/EventServiceProvider.php protected $listen = [ \GeekCo\LaravelMaxClient\Webhook\MaxUpdateReceived::class => [ YourUpdateListener::class, ], ];
Обработчик:
use GeekCo\LaravelMaxClient\Webhook\MaxUpdateReceived; class YourUpdateListener { public function handle(MaxUpdateReceived $event): void { $update = $event->update; // GeekCo\MaxPhpClient\Dto\Update // бизнес-обработка апдейта } }
-
Пакет ставит
HandleMaxUpdateJobв очередьwebhook.queueна каждыйUpdateи сразу отвечает200(API требует ответ в течение 30 секунд). Если на событие нет слушателей — работа в очередь не ставится.
Вебхук требует публичного домена с HTTPS и доверенным CA, поэтому для локальной разработки используйте Long Polling:
php artisan max:listenКоманда опрашивает GET /updates через ядро (LongPollingRunner) и ставит
HandleMaxUpdateJob в ту же очередь (webhook.queue) — апдейты обрабатывает тот же слушатель MaxUpdateReceived.
Остановка — Ctrl+C.
Опции:
--marker=42— начать с указанного marker (последний обработанный timestamp);--once— обработать одну партию апдейтов и завершиться (для cron/смоука).
Поведение по умолчанию — в секции long_polling конфига (env MAX_POLLING_*):
limit (100), timeout (30 сек), break_on_failure (true — завершаться при ошибке API; для долгой работы в dev
задайте MAX_POLLING_BREAK_ON_FAILURE=false).
Активная webhook-подписка отключает Long Polling — не используйте оба механизма одновременно.
# unit-тесты (Testbench), lint, статика, покрытие, аудит
composer run lint
composer run format
composer run analyse
vendor/bin/phpunit
composer run coverage
composer auditИнтеграционные смоук-тесты против реального API (read-only, нужен MAX_API_TOKEN, TLS из Docker-сети блокируется —
только --network host):
source .env && docker run --rm --network host \
-v "$(pwd)":/var/www/html -w /var/www/html \
-e MAX_API_TOKEN="$MAX_API_TOKEN" \
ghcr.io/geekcodev/php:8.4-bookworm vendor/bin/phpunit --group integrationMIT (c) 2026 Evgeny Semenov. См. LICENSE.