Adds a first-party Instagram Direct Messages adapter backed by Meta's
Instagram API with Instagram Login.
- Verifies webhook challenges and HMAC signatures, then normalizes DMs,
story replies, media, quick replies, postbacks, and reactions.
- Sends plain text, cards, quick replies, typing indicators, URL
attachments, and uploaded media through `graph.instagram.com`.
- Maps authentication, rate-limit, and 24-hour messaging-window failures
to typed adapter errors.
- Registers Instagram in the adapter catalog, CLI scaffold, official
docs, replay suite, and Next.js example.
## Usage
```ts
import { createInstagramAdapter } from "@chat-adapter/instagram";
import { Chat } from "chat";
const bot = new Chat({
userName: "mystore",
adapters: { instagram: createInstagramAdapter() },
});
```
## Webhook
```ts
export async function POST(request: Request) {
return bot.webhooks.instagram(request);
}
```
## Verification
- `pnpm --filter @chat-adapter/instagram test`
- `pnpm --filter @chat-adapter/instagram typecheck`
- `pnpm --filter example-nextjs-chat typecheck`
- `pnpm --filter example-nextjs-chat build`
- `pnpm check`
- `pnpm konsistent`
## Live Testing
<table>
<tr>
<td><img width="1440" height="2109" alt="1000000502"
src="https://github.com/user-attachments/assets/9fdb8c3b-4e41-4c81-9426-08756a5e4201"
/></td>
<td><img width="1440" height="1995" alt="1000000503"
src="https://github.com/user-attachments/assets/8a572493-c57a-4412-9049-5737aaa9dfd0"
/></td>
</tr>
</table>
Closes #729 / Co-Authored by @ivandujaut
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
Next.js Chat Example
A full-featured example app demonstrating the Chat SDK with Next.js. Integrates with Slack, Microsoft Teams, Google Chat, Discord, GitHub, Linear, Instagram, and other supported platforms — configure whichever platforms you need via environment variables.
Getting started
Prerequisites
- Node.js 20+
- pnpm 9+
- Redis (for state persistence)
- At least one platform configured (see Environment variables)
Setup
- Install dependencies from the monorepo root:
pnpm install
- Copy the example environment file and fill in your platform credentials:
cp .env.example .env.local
- Start the dev server:
pnpm dev
The app runs at http://localhost:3000. Platform webhooks should point to /api/webhooks/{platform} (e.g. /api/webhooks/slack).
For local development with real webhooks, use a tunneling tool like ngrok or
localtunnel.
What it demonstrates
- Event handlers — mentions, thread subscriptions, pattern matching, reactions
- AI mode —
@mention AIto enable streaming LLM responses via the Vercel AI SDK - Cards — interactive JSX-based cards with buttons, dropdowns, and fields
- Modals — form dialogs with text inputs, validation, and private metadata
- Actions — button clicks and dropdown selections with response handlers
- Slash commands — platform-specific command handling
- Ephemeral messages — user-only visible messages with DM fallback
- DMs — programmatic direct message initiation
- File uploads — attachment detection and display
- Multi-platform — same bot logic across all six platforms
Project structure
src/
├── app/
│ ├── api/
│ │ ├── webhooks/[platform]/route.ts # Main webhook entry point
│ │ └── discord/gateway/route.ts # Discord gateway cron
│ ├── settings/page.tsx # Preview branch config UI
│ └── page.tsx # Home page
├── lib/
│ ├── bot.tsx # Bot logic and handlers
│ ├── adapters.ts # Adapter initialization
│ └── recorder.ts # Webhook recording system
└── middleware.ts # Preview branch proxy
Environment variables
Copy .env.example for the full list. At minimum, set BOT_USERNAME and credentials for one platform:
| Variable | Description |
|---|---|
BOT_USERNAME |
Bot display name |
SLACK_CONNECTOR |
Slack Vercel Connect connector UID (e.g. slack/acme-slack) |
SLACK_AGENT_VIEW |
Set to true when your Slack manifest uses agent_view (see the commented blocks in slack-manifest.yml) — enables the Agent messaging experience with auto-applied suggested prompts |
SLACK_NATIVE_STREAMING |
Set to false to stream via post-and-edit (chat.update) instead of Slack's native streaming API — useful on Slack flavours without chat.startStream (e.g. GovSlack) |
VERCEL_OIDC_TOKEN |
Vercel OIDC token used by Connect (run vercel env pull) |
TEAMS_APP_ID |
Teams app ID |
TEAMS_APP_PASSWORD |
Teams app password |
GOOGLE_CHAT_CREDENTIALS |
Google Chat service account JSON |
DISCORD_BOT_TOKEN |
Discord bot token |
DISCORD_PUBLIC_KEY |
Discord interaction verification key |
INSTAGRAM_ACCESS_TOKEN |
Instagram User access token |
INSTAGRAM_ACCOUNT_ID |
Instagram professional account ID returned by /me?fields=user_id,username |
INSTAGRAM_APP_SECRET |
Meta app secret used to verify Instagram webhook signatures |
INSTAGRAM_VERIFY_TOKEN |
Private value configured as the Instagram webhook verify token |
GITHUB_CONNECTOR |
GitHub Vercel Connect connector UID (needs VERCEL_OIDC_TOKEN — run vercel env pull) |
LINEAR_CONNECTOR |
Linear Vercel Connect connector UID (needs VERCEL_OIDC_TOKEN — run vercel env pull) |
LINEAR_MODE |
Linear inbound mode: comments or agent-sessions |
NOTION_TOKEN |
Notion connection access token |
NOTION_VERIFICATION_TOKEN |
Notion webhook HMAC key (from subscription verification handshake) |
NOTION_MENTION_MODE |
Optional: mention | all-comments | keyword (adapter default mention) |
NOTION_KEYWORDS |
Optional: comma-separated keywords when NOTION_MENTION_MODE=keyword |
REDIS_URL |
Redis connection string |
See the Chat SDK docs for full platform setup guides.
For Linear app-actor mode, set LINEAR_MODE=agent-sessions, enable Agent session events on the webhook, install the Linear app with actor=app and app:mentionable, and keep using the existing thread.startTyping() / thread.post(...) handler flow. The adapter maps those calls onto Linear agent activities automatically.
Test Instagram DMs
- Add the four required
INSTAGRAM_*variables to.env.local. - Expose the app through an HTTPS tunnel or deploy it to Vercel.
- Configure Meta's callback URL as
https://your-domain.com/api/webhooks/instagram. - Subscribe the professional account to the webhook fields:
curl -X POST \
"https://graph.instagram.com/v26.0/me/subscribed_apps?subscribed_fields=messages,message_reactions,messaging_postbacks,messaging_seen&access_token=$INSTAGRAM_ACCESS_TOKEN"
Send the professional account a DM from another Instagram account. Normal
messages run the example's AI response; send post-card to test Instagram
quick replies without invoking the model.
Recording and replay
The app includes a recording system for capturing production webhook interactions and converting them into replay tests.
# Enable recording in your environment
RECORDING_ENABLED=true
# List recorded sessions
pnpm recording:list
# Export a session
pnpm recording:export <session-id>
See packages/integration-tests/fixtures/replay/README.md for the full workflow.
Preview branch testing
Test PRs with real webhook traffic by proxying requests from production to a preview deployment:
- Deploy a preview branch to Vercel
- Go to
/settingson the production deployment - Enter the preview branch URL and save
All webhook requests are proxied until the URL is cleared.