Skip to main content

Instagram Direct

The instagram adapter connects the Direct messages of an Instagram professional account to Converger (lib/converger/channels/adapters/instagram.ex). It supports the modes inbound, outbound and duplex. Instagram messaging runs on the Messenger Platform, so the adapter shares its webhook parsing, Send API code, signature check and media downloads with Facebook Messenger (and the Graph code with WhatsApp); this page lists the differences. See ADR-0048.

Setup​

Meta offers two ways to reach Instagram messaging. Pick the one your app uses:

Instagram API with Facebook LoginInstagram API with Instagram Login
AccountInstagram professional account linked to a Facebook PageInstagram professional account
TokenPage access token (instagram_basic, instagram_manage_messages, pages_messaging)Instagram user access token (instagram_business_basic, instagram_business_manage_messages)
api_hostgraph.facebook.com (default)graph.instagram.com
account_idthe Page idthe Instagram account id
  1. Add the Instagram product to your Meta app and generate the token.

  2. Create the channel:

    {
    "name": "Instagram DMs",
    "type": "instagram",
    "mode": "duplex",
    "config": {
    "account_id": "17841400000000001",
    "access_token": "IGQV...",
    "api_host": "graph.instagram.com",
    "verify_token": "a-long-random-string",
    "app_secret": "0123456789abcdef0123456789abcdef"
    }
    }
  3. Set the webhook callback URL to https://<PHX_HOST>/api/v1/channels/<channel id>/inbound with the channel's verify_token, and subscribe to messages, messaging_postbacks, message_reactions and messaging_seen.

Configuration​

KeyRequiredDescription
account_idyesNumeric id the Send API is called on (/<version>/<account_id>/messages).
access_tokenyes (secret)Page token or Instagram user token.
api_hostnograph.facebook.com (default) or graph.instagram.com. No other host is accepted, so the token cannot be sent elsewhere.
verify_tokenyes (secret)Webhook subscription check.
app_secretwhen require_signature is trueSigns every webhook (X-Hub-Signature-256).
graph_api_versionnoDefault v26.0.
download_medianoDefault true.

Differences from Messenger​

  • Webhooks must have object: "instagram".
  • Story replies and mentions: message.reply_to.story (url, id) is kept in metadata.story; a story_mention, ig_reel or share attachment with a URL is downloaded like other media (story media expire after 24 hours).
  • Unsends (is_deleted) become messageDelete.
  • Receipts: Instagram read events name the message (read.mid), so they mark that delivery read.
  • Text is split into messages of at most 500 characters (Instagram limits a text message to 1000 bytes).
  • Media: Instagram fetches attachments from a URL; a file stored in Converger cannot be uploaded and fails the delivery permanently (Instagram API cannot fetch Converger attachment ...). Send media with a public contentUrl.
  • Rate limit: default 100/s (Instagram's Send API limit per professional account for text); set the channel's rate_limit to change it.
  • Errors: rate-limit code 80002 is retried, like the codes listed for Messenger.

Outbound messages, quick replies, message tags (metadata.message_tag, for example HUMAN_AGENT), the 24-hour window error, metadata keys and the health probe (GET /<version>/<account_id>?fields=id) work as described for Messenger.

Typed messages​

The adapter declares message_types: image file video audio (#68, ADR-0064): typed media arrive as file attachments and are sent as described above. Every other typed message is sent as its text rendering (messages.md section 5): the prompt with its actions as a numbered list (1. Track an order), links as label: url, cards as text blocks; native quick replies or buttons for typed messages are a follow-up. A reply that is only a number (2) within 24 hours of the conversation's most recent actionable message becomes the normalised answer, with metadata.action (source: "numeric") and reply_to_id (messages.md section 6).

Testing​

instagram_test.exs stubs the Graph API through config :converger, :instagram_req_options.