torgodly / messenger-bot
Facebook Messenger webhooks and Page comments for Laravel (BotMan-style API, no BotMan dependency).
Requires
- php: ^8.3
- ext-json: *
- illuminate/cache: ^12.0|^13.0
- illuminate/console: ^12.0|^13.0
- illuminate/contracts: ^12.0|^13.0
- illuminate/events: ^12.0|^13.0
- illuminate/http: ^12.0|^13.0
- illuminate/routing: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.27
- orchestra/testbench: ^10.48|^11.0
- pestphp/pest: ^4.0
- phpunit/phpunit: ^11.5|^12.0
README
Facebook Messenger webhooks for Laravel: messages, postbacks, quick replies, and optional Page feed comments. Small API similar to BotMan (hears, payload, onComment) — not BotMan.
Requirements: PHP 8.3+, Laravel 12 or 13.
Install
composer require torgodly/messenger-bot php artisan vendor:publish --tag=messenger-bot-config
Then run:
php artisan messenger-bot:install
It publishes config, adds a short Messenger block to .env (with a blank line above it), asks for App ID and App Secret if they are still empty, then continues with webhook verify token and OAuth. Other settings use defaults from config/messenger-bot.php until you add more MESSENGER_BOT_* lines yourself.
What you configure
| You need | Notes |
|---|---|
APP_URL |
Public base URL of this app (no trailing slash). |
MESSENGER_BOT_APP_ID / MESSENGER_BOT_APP_SECRET |
Meta app. |
MESSENGER_BOT_VERIFY_TOKEN |
Any random string — same value in Meta → Webhooks → Verify Token. |
| Page token | Leave MESSENGER_BOT_PAGE_ACCESS_TOKEN empty and use OAuth, or paste a token for local tests. |
OAuth (recommended): In Meta → Facebook Login → Valid OAuth Redirect URIs, add exactly:
https://YOUR-DOMAIN/messenger-bot/oauth/facebook/callback
(Or the full URL if you set MESSENGER_BOT_OAUTH_REDIRECT_URI.) Open https://YOUR-DOMAIN/messenger-bot/oauth/facebook in a browser while logged in as a Page admin.
Webhook: In Meta → Webhooks → Page, callback URL = https://YOUR-DOMAIN/webhook/messenger (or your MESSENGER_BOT_WEBHOOK_PATH). Same verify token as above.
Useful commands
| Command | Purpose |
|---|---|
php artisan messenger-bot:install |
Config + .env keys + subscribe + menu (needs token). |
php artisan messenger-bot:sync-page |
Re-run subscribe/menu after changes. |
php artisan messenger-bot:token-status |
Token expiry hint. |
php artisan messenger-bot:clear-page-token |
Clear cached OAuth token; connect again. |
Use --skip-token-check on install/sync only if you really must skip the Graph GET /me check.
Handlers
Register in routes/web.php or a service provider boot():
use MessengerBot\Facades\MessengerBot; MessengerBot::hears('hi', fn ($bot) => $bot->reply('Hello!')); MessengerBot::payload('GET_STARTED', fn ($bot) => $bot->reply('Welcome!')); MessengerBot::onComment(function ($bot, $comment) { $bot->replyToComment($comment->id, 'Thanks!'); });
Postbacks and quick replies use the same payload('SOME_KEY', …) if the payload string matches. Get Started: if you use a persistent menu, Meta sends a Get Started postback — register payload for MESSENGER_BOT_GET_STARTED_PAYLOAD or set MESSENGER_BOT_GET_STARTED_REPLY for a default text when no handler is registered.
Going deeper
- Templates (generic, button, media, receipt, list, product, etc.) and typed helpers live on
Bot— see Send API templates. - Events:
MessageReceived,PostbackReceived,CommentCreated,WebhookReceived, plus outgoing message events. - Changelog: CHANGELOG.md.
Webhook and OAuth routes are registered outside the web middleware group so Meta is not blocked by CSRF (no 419). Keep MESSENGER_BOT_AUTO_REGISTER_ROUTES=true unless you register routes yourself.
403 on webhook: usually bad MESSENGER_BOT_APP_SECRET vs Meta. For local tests you can set MESSENGER_BOT_SIGNATURE_ENABLED=false; use a real secret in production.
Path repo (contributors)
{
"repositories": [{ "type": "path", "url": "packages/messenger-bot", "options": { "symlink": true } }],
"require": { "torgodly/messenger-bot": "@dev" }
}