Messenger
Build bots for Facebook Messenger with templates, buttons, reactions, and postbacks.
Building for Instagram Direct Messages? Use the Instagram adapter instead. It connects through Instagram API with Instagram Login and does not require a Facebook Page.
Create a new bot
Scaffold a Next.js bot with the Messenger adapter using create-chat-sdk:
pnpm create chat-sdk@latest my-bot --adapter messenger memory -yThe generated app uses the Memory state adapter for local development. To add the adapter to an existing app, start at Install.
Install
pnpm add @chat-adapter/messenger @chat-adapter/state-memoryQuick start
The adapter auto-detects FACEBOOK_APP_SECRET, FACEBOOK_PAGE_ACCESS_TOKEN, and FACEBOOK_VERIFY_TOKEN from the environment.
The memory state adapter keeps subscriptions and locks in process memory, which suits local development. Use Redis or PostgreSQL in production.
Platform setup
Create a Meta app
- Go to developers.facebook.com/apps.
- Create an app and select "Engage with customers on Messenger from Meta".
- Under App Settings then Basic, copy the App Secret to
FACEBOOK_APP_SECRET.
Create a Facebook Page
Users interact with your bot by messaging a Facebook Page, so the bot needs one to send and receive messages. If you don't already have a Page, create one under a Facebook Business profile.
Get credentials
- In your Meta app dashboard, open Use Cases then Messenger API Settings.
- Under Generate access tokens, click Add or remove Pages and select your Page.
- Generate the token and copy it to
FACEBOOK_PAGE_ACCESS_TOKEN.
Choose your own random string for FACEBOOK_VERIFY_TOKEN. You enter the same value in the next step.
Configure webhooks
Deploy the GET and POST route shown above to a public HTTPS URL first, then, in Messenger API Settings:
- Click Add Callback URL and enter
https://your-domain.com/api/webhooks/messenger. - Set Verify Token to the same value as
FACEBOOK_VERIFY_TOKEN. - Click Verify and Save.
- Add subscriptions:
messages,messaging_postbacks,messaging_reactions,message_deliveries,message_reads.
Configuration
Prop
Type
Environment variables
| Variable | Required | Description |
|---|---|---|
FACEBOOK_APP_SECRET | Yes | App secret used to verify webhook signatures |
FACEBOOK_PAGE_ACCESS_TOKEN | Yes | Access token for the Facebook Page the bot sends as |
FACEBOOK_VERIFY_TOKEN | Yes | Your chosen secret for the webhook verification handshake |
Webhooks
The route handles two kinds of request from Meta:
- GET verification handshake: Meta sends a
hub.verify_tokenchallenge that must matchFACEBOOK_VERIFY_TOKEN. - POST event delivery: incoming messages, reactions, and postbacks, signed with
X-Hub-Signature-256and verified againstFACEBOOK_APP_SECRET.
Interactive messages
The adapter converts card elements to Messenger templates:
- Generic Template: used when the card has a
titleorimageUrl. Up to 3 buttons. - Button Template: used when the card has text content and buttons but no title or image. Max 640 characters.
- Text fallback: used when the card contains unsupported elements (tables, select menus) or exceeds these constraints.
Constraints:
- Max 3 buttons per template.
- Button titles limited to 20 characters (truncated with ellipsis).
- Subtitles limited to 80 characters.
- Button Template text limited to 640 characters.
Inbound attachments
Inbound attachment URLs remain available as attachment.url. The adapter's
fetchData function downloads media only from Meta's fbsbx.com and
fbcdn.net hosts, refuses private and internal addresses (including after
redirects), limits responses to 25 MB, and times out after 30 seconds.
External fallback and link-share URLs are preserved but rejected before any
network request.
Read receipts
Use thread.markAsRead() in a message handler to send Messenger's mark_seen sender action:
Messenger applies this action to the conversation's seen state rather than a single message, even when you pass a message or message ID.
Thread IDs
Example: messenger:27161130920158013.
recipientId is the user's ID as Meta sends it in the webhook's sender.id. Each conversation between the Page and one user is one thread.
Feature support
Messaging
| Feature | Supported |
|---|---|
| Post message | |
| Message replies | |
| Edit message | |
| Delete message | |
| File uploads | |
| Streaming | Buffered |
| Scheduled messages |
Rich content
| Feature | Supported |
|---|---|
| Card format | Generic / Button Templates |
| Buttons | Max 3, postback |
| Link buttons | web_url |
| Select menus | |
| Tables | ASCII |
| Charts | |
| Fields | ASCII |
| Images in cards | |
| Modals |
Conversations
| Feature | Supported |
|---|---|
| Slash commands | |
| Mentions | |
| Add reactions | |
| Remove reactions | |
| Typing indicator | |
| Mark as read | |
| Message edit events | |
| Message delete events | |
| DMs | |
| Ephemeral messages | |
| User lookup | |
| Parent subject | |
| Native client | |
| Custom API endpoint |
Message history
| Feature | Supported |
|---|---|
| Fetch messages | Cached sent only |
| Fetch single message | Cached |
| Fetch thread info | |
| Fetch channel messages | Cached |
| List threads | |
| Fetch channel info | |
| Post channel message |