Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/friendly-pumas-message.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@chat-adapter/instagram": minor
"chat": minor
"create-chat-sdk": minor
---

Add a native Instagram Direct Messages adapter with signed webhooks, media, quick replies, story context, reactions, and typed Meta API errors.
10 changes: 10 additions & 0 deletions apps/docs/adapters.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@
"beta": true,
"readme": "https://github.com/vercel/chat/tree/main/packages/adapter-messenger"
},
{
"name": "Instagram",
"slug": "instagram",
"type": "platform",
"description": "Build bots for Instagram Direct with DMs, media, quick replies, reactions, and story replies.",
"packageName": "@chat-adapter/instagram",
"icon": "instagram",
"beta": true,
"readme": "https://github.com/vercel/chat/tree/main/packages/adapter-instagram"
},
{
"name": "Web",
"slug": "web",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
discord,
gchat,
github,
instagram,
linear,
messenger,
slack,
Expand All @@ -26,6 +27,7 @@ const platforms: {
{ icon: whatsapp, name: "WhatsApp", slug: "whatsapp" },
{ icon: twilio, name: "Twilio", slug: "twilio" },
{ icon: messenger, name: "Messenger", slug: "messenger" },
{ icon: instagram, name: "Instagram", slug: "instagram" },
{ icon: x, name: "X", slug: "x" },
{ icon: github, name: "GitHub", slug: "github" },
{ icon: linear, name: "Linear", slug: "linear" },
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/app/[lang]/adapters/components/adapter-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
discord,
gchat,
github,
instagram,
ioredis,
linear,
memory,
Expand All @@ -36,6 +37,7 @@ const iconMap: Record<
gchat,
discord,
github,
instagram,
web,
linear,
telegram,
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/components/geistdocs/adapter-hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
gchat,
github,
ioredis,
instagram,
linear,
memory,
messenger,
Expand All @@ -26,6 +27,7 @@ const ICON_MAP: Record<
gchat,
discord,
github,
instagram,
web,
linear,
telegram,
Expand Down
276 changes: 276 additions & 0 deletions apps/docs/content/adapters/official/instagram.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
---
title: Instagram
description: Instagram Direct Messages adapter using Meta's Instagram Messaging API.
packageName: "@chat-adapter/instagram"
slug: instagram
type: platform
logo: instagram
tagline: Build Instagram DM bots with media, quick replies, reactions, and story replies.
beta: true
features:
postMessage: yes
editMessage: no
deleteMessage: no
fileUploads:
status: yes
label: Uploads and HTTPS URLs
streaming:
status: partial
label: Buffered
scheduledMessages: no
cardFormat:
status: partial
label: Generic / Button Templates
buttons:
status: partial
label: Quick replies / postbacks
linkButtons:
status: yes
label: web_url
selectMenus: no
tables: no
fields: no
imagesInCards: yes
modals: no
slashCommands: no
mentions: no
addReactions: no
removeReactions: no
typingIndicator: yes
directMessages: yes
ephemeralMessages: no
customApiEndpoint: yes
fetchMessages:
status: partial
label: Cached sent only
fetchSingleMessage:
status: partial
label: Cached
fetchThreadInfo: yes
fetchChannelMessages:
status: partial
label: Cached
listThreads: no
fetchChannelInfo: yes
postChannelMessage: yes
---

<Callout type="info">
Building for Facebook Messenger? Use the [Messenger adapter](/adapters/official/messenger) instead. It connects through the Messenger Platform API and uses a Facebook Page access token.
</Callout>

## Install

<PackageInstall package="@chat-adapter/instagram" />

## Quick start

<Callout type="info">
The adapter auto-detects `INSTAGRAM_ACCESS_TOKEN`, `INSTAGRAM_APP_SECRET`, `INSTAGRAM_VERIFY_TOKEN`, `INSTAGRAM_ACCOUNT_ID`, and the optional `INSTAGRAM_API_VERSION` from the environment.
</Callout>

```typescript title="lib/bot.ts" lineNumbers
import { Chat } from "chat";
import { createInstagramAdapter } from "@chat-adapter/instagram";

export const bot = new Chat({
userName: "mybot",
adapters: {
instagram: createInstagramAdapter(),
},
});

bot.onDirectMessage(async (thread, message) => {
await thread.post("Hello from Instagram!");
});
```

```typescript title="app/api/webhooks/instagram/route.ts" lineNumbers
import { bot } from "@/lib/bot";

export async function GET(request: Request) {
return bot.webhooks.instagram(request);
}

export async function POST(request: Request) {
return bot.webhooks.instagram(request);
}
```

## Configuration

<TypeTable
type={{
accessToken: {
type: "string",
description:
"Instagram access token for the Messaging API. Auto-detected from `INSTAGRAM_ACCESS_TOKEN`.",
},
appSecret: {
type: "string",
description:
"Meta app secret for `X-Hub-Signature-256` verification. Auto-detected from `INSTAGRAM_APP_SECRET`.",
},
verifyToken: {
type: "string",
description:
"Webhook verification secret. Auto-detected from `INSTAGRAM_VERIFY_TOKEN`.",
},
accountId: {
type: "string",
description:
"Instagram professional account ID. Auto-detected from `INSTAGRAM_ACCOUNT_ID`.",
},
apiVersion: {
type: "string",
default: '"v26.0"',
description:
"Optional Meta Graph API version override. Auto-detected from `INSTAGRAM_API_VERSION`.",
},
userName: {
type: "string",
default: '"bot"',
description:
"Bot username. Defaults to the connected Instagram account username after initialization.",
},
logger: {
type: "Logger",
default: "ConsoleLogger",
description: "Logger used for adapter diagnostics.",
},
}}
/>

## Meta app setup

<Callout type="info">
This adapter uses **Instagram API with Instagram Login** and
`graph.instagram.com`. It does not require a Facebook Page. The connected
Instagram account must be a public professional Business or Creator account;
personal and private accounts cannot use the Messaging API.
</Callout>

### 1. Create a Business app and add Instagram

1. Open the [Meta App Dashboard](https://developers.facebook.com/apps) and
click **Create App**.
2. For the use case, select **Other**, then click **Next**.
3. Select the **Business** app type, then click **Next**.
4. Enter the app name and contact email and finish creating the app. Connecting
a verified business is required before publishing, but can be completed
later under **App settings > Basic**.
5. In the new app dashboard, find the **Instagram** product and click **Set
up**.

Meta automatically adds **API setup with Instagram login**. Do not select
**API setup with Facebook login** for this adapter; that setup uses Facebook
or Page tokens and `graph.facebook.com`.

### 2. Add the test account and generate a token

1. In the left menu, open **Instagram > API setup with Instagram login**.
2. Under **Generate access tokens**, click **Add account** and sign in to
the public Instagram professional account the bot will use.
3. Once the account appears, click **Generate token**, sign in again, and copy
the token to `INSTAGRAM_ACCESS_TOKEN`.

Tokens generated in the App Dashboard are long-lived and valid for 60 days.
They are suitable for development and for accounts you own or manage. Refresh
or rotate the token before it expires.

For an app that connects other businesses' accounts, configure **Instagram
business login** and request these scopes in the login flow:

- `instagram_business_basic`
- `instagram_business_manage_messages`

Business Login returns a one-hour token. Exchange it server-side for a
60-day token through `https://graph.instagram.com/access_token`.

### 3. Get the Instagram professional account ID

The account ID is not the app ID or the app-scoped user ID. Query the
professional account associated with the token:

```bash
curl "https://graph.instagram.com/v26.0/me?fields=user_id,username&access_token=$INSTAGRAM_ACCESS_TOKEN"
```

Copy the returned `data[0].user_id` value to `INSTAGRAM_ACCOUNT_ID`.

Set the remaining secrets:

- In **App settings > Basic**, copy the Meta app's **App Secret** to
`INSTAGRAM_APP_SECRET`. Meta uses this secret to sign webhook requests.
- Generate your own private random string for `INSTAGRAM_VERIFY_TOKEN`. This
value is only shared with Meta during webhook verification.

### 4. Configure and activate webhooks

Deploy the GET and POST route shown above to a public HTTPS URL first, then:

1. Return to **Instagram > API setup with Instagram login**.
2. Under **Configure webhooks**, click **Configure**.
3. Set **Callback URL** to
`https://your-domain.com/api/webhooks/instagram`.
4. Set **Verify token** to the same value as `INSTAGRAM_VERIFY_TOKEN`, then
click **Save**.
5. Click **Manage** and keep these fields enabled:
`messages`, `message_reactions`, `messaging_postbacks`, and
`messaging_seen`.

Configuring the callback does not subscribe an Instagram account by itself.
Subscribe the account represented by the access token:

```bash
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 to verify
the `messages` webhook. Meta first verifies the callback with GET, then sends
event notifications with POST.

### 5. Prepare for production

Standard Access works for professional accounts you own or have added to the
App Dashboard. To connect accounts you do not own, complete Business
Verification and App Review for Advanced Access to
`instagram_business_basic` and `instagram_business_manage_messages`.
Request the **Human Agent** feature only if real support agents will use the
seven-day response window.

See Meta's current
[app creation guide](https://developers.facebook.com/docs/instagram-platform/create-an-instagram-app),
[Business Login guide](https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/business-login/),
and [webhook subscription guide](https://developers.facebook.com/docs/instagram-platform/webhooks/)
for dashboard changes and production review requirements.

## Supported messaging

- Send and receive Instagram direct messages.
- Send images, video, audio, and files using binary data or publicly accessible HTTPS URLs.
- Render supported card buttons as Instagram quick replies. Quick-reply taps are delivered to action handlers.
- Send typing indicators while work is in progress.
- Receive reaction events through `onReaction`.
- Receive replies to Instagram stories as direct messages. The original webhook remains available on `message.raw` when story-specific context is needed.

<Callout type="warn">
Instagram's standard messaging window lasts 24 hours after the user's most recent message. `sendHumanAgentMessage` uses the `HUMAN_AGENT` tag for human-support replies within seven days, but Meta does not allow it for automated messages and may require approval.
</Callout>

### Buffered streaming

Instagram does not expose message editing, so streamed responses are buffered and sent as one message when the stream completes.

### Thread ID format

```
instagram:{accountId}:{userId}
```

Example: `instagram:17841400000000000:1234567890`.

## Feature support

<FeatureSupport />
4 changes: 4 additions & 0 deletions apps/docs/content/adapters/official/messenger.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ features:
postChannelMessage: yes
---

<Callout type="info">
Building for Instagram Direct Messages? Use the [Instagram adapter](/adapters/official/instagram) instead. It connects through Instagram API with Instagram Login and does not require a Facebook Page.
</Callout>

## Install

<PackageInstall package="@chat-adapter/messenger" />
Expand Down
1 change: 1 addition & 0 deletions apps/docs/content/adapters/official/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"whatsapp",
"twilio",
"messenger",
"instagram",
"x",
"xchat",
"web",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions apps/docs/lib/logos.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,27 @@ export const messenger = (props: ComponentProps<"svg">) => (
</svg>
);

export const instagram = (props: ComponentProps<"svg">) => (
<svg
fill="none"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<rect
height="20"
rx="5"
stroke="currentColor"
strokeWidth="2"
width="20"
x="2"
y="2"
/>
<circle cx="12" cy="12" r="4.5" stroke="currentColor" strokeWidth="2" />
<circle cx="17.5" cy="6.5" fill="currentColor" r="1.25" />
</svg>
);

export const x = (props: ComponentProps<"svg">) => (
<svg
fill="currentColor"
Expand Down
Loading