← All @molecule/* packages · App templates

@molecule/api-channel-messenger

Provider bond · channel · API (Node) · v1.0.1 · Apache-2.0

Facebook Messenger channel bond — implements @molecule/api-channel for sendMessage via the Send API, X-Hub-Signature-256 webhook verification, and inbound entry/messaging parsing.

npm install @molecule/api-channel-messenger

npm · Source on GitHub · Implements @molecule/api-channel

How it works

@molecule/api-channel-messenger is a provider bond on the API (Node) side: it implements the channel core interface (@molecule/api-channel) with a concrete vendor or library behind it.

Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.

import { setProvider } from '@molecule/api-channel'
import { provider } from '@molecule/api-channel-messenger'

setProvider('messenger', provider)

Works with: @molecule/api-secrets

Secrets: CHANNEL_MESSENGER_PAGE_ACCESS_TOKEN, CHANNEL_MESSENGER_APP_SECRET

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Facebook Messenger channel provider for molecule.dev.

Implements the framework-agnostic {@link ChannelProvider} interface over the Messenger Send API and webhook envelope. Bond under the named-multi-provider 'channel' category at app startup:

Quick Start

import { setProvider } from '@molecule/api-channel'
import { provider } from '@molecule/api-channel-messenger'

setProvider('messenger', provider)

Type

provider

Installation

npm install @molecule/api-channel-messenger @molecule/api-channel @molecule/api-secrets

API

Interfaces

MessengerActor

Subset of the Messenger Sender/Recipient shape used during inbound normalization.

interface MessengerActor {
  /** Page-scoped user identifier. */
  id: string
}

MessengerConfig

Configuration for the Messenger channel provider.

The page access token authorizes Send API calls; the app secret signs inbound webhooks via X-Hub-Signature-256. Both are deliberately accepted only via this config (or the CHANNEL_MESSENGER_PAGE_ACCESS_TOKEN / CHANNEL_MESSENGER_APP_SECRET env vars) and are NEVER included in error messages, log lines, or normalized payloads.

interface MessengerConfig {
  /**
   * Page access token (`EAA…`). Required for outbound `sendMessage`.
   * Defaults to the `CHANNEL_MESSENGER_PAGE_ACCESS_TOKEN` env var.
   *
   * Treat as a secret — providers redact this value in any user-facing
   * output.
   */
  pageAccessToken?: string

  /**
   * Facebook app secret used to verify `X-Hub-Signature-256` on inbound
   * webhook requests. Defaults to the `CHANNEL_MESSENGER_APP_SECRET` env
   * var.
   *
   * If unset, {@link MessengerChannelProvider.verifyWebhookSignature}
   * returns `false`.
   */
  appSecret?: string

  /**
   * Graph API base URL. Override only for tests or alternative regional
   * endpoints. Defaults to `https://graph.facebook.com`.
   */
  apiBaseUrl?: string

  /**
   * Graph API version to target. Defaults to `'v22.0'`.
   */
  apiVersion?: string

  /**
   * Per-request timeout in milliseconds. Defaults to 10000.
   */
  timeoutMs?: number

  /**
   * Optional default `messaging_type` applied to outbound sends. Defaults
   * to `'RESPONSE'` (replies to user-initiated conversations within the
   * 24-hour window). Override to `'UPDATE'` or `'MESSAGE_TAG'` when
   * sending unsolicited messages — note the Messenger Platform policy
   * restrictions.
   */
  defaultMessagingType?: MessengerMessagingType
}

MessengerInboundAttachment

Subset of an inbound Messenger attachment object.

interface MessengerInboundAttachment {
  /** Attachment kind (`'image'`, `'video'`, `'audio'`, `'file'`, …). */
  type?: string
  /** Optional payload object — typically `{ url }`. */
  payload?: { url?: string; sticker_id?: number }
}

MessengerInboundDelivery

Subset of an inbound Messenger delivery object.

interface MessengerInboundDelivery {
  /** Mids of the messages confirmed delivered. */
  mids?: string[]
  /** Watermark — all messages sent before this timestamp are delivered. */
  watermark?: number
}

MessengerInboundMessage

Subset of an inbound Messenger message object.

interface MessengerInboundMessage {
  /** Provider-assigned message identifier (mid). */
  mid?: string
  /** Plain-text body. */
  text?: string
  /** Quick-reply payload, when the user clicked a quick reply. */
  quick_reply?: { payload?: string }
  /** Attachments (images, files, …) included with the message. */
  attachments?: MessengerInboundAttachment[]
  /** Whether the message was an echo of one this app sent. */
  is_echo?: boolean
}

MessengerInboundPostback

Subset of an inbound Messenger postback object — the payload returned when a user taps a button on a button_template or persistent menu.

interface MessengerInboundPostback {
  /** Opaque payload originally set on the button. */
  payload?: string
  /** Visible title shown on the button when it was tapped. */
  title?: string
}

MessengerInboundRead

Subset of an inbound Messenger read object.

interface MessengerInboundRead {
  /** Watermark — all messages sent before this timestamp are read. */
  watermark?: number
}

MessengerMessagingEntry

A single messaging entry inside an inbound webhook envelope.

interface MessengerMessagingEntry {
  /** Sender of the inbound event. */
  sender?: MessengerActor
  /** Recipient (typically the page receiving the event). */
  recipient?: MessengerActor
  /** Unix timestamp in milliseconds. */
  timestamp?: number
  /** Inbound user message. */
  message?: MessengerInboundMessage
  /** Inbound button-tap postback. */
  postback?: MessengerInboundPostback
  /** Delivery confirmation. */
  delivery?: MessengerInboundDelivery
  /** Read receipt. */
  read?: MessengerInboundRead
}

MessengerSendApiResponse

Successful Send API response shape used by the provider.

interface MessengerSendApiResponse {
  /** Page-scoped recipient identifier (echoed). */
  recipient_id?: string
  /** Messenger-assigned outbound message id. */
  message_id?: string
}

MessengerWebhookEntry

A single entry inside an inbound webhook envelope.

interface MessengerWebhookEntry {
  /** Page identifier the events belong to. */
  id?: string
  /** Unix timestamp in milliseconds. */
  time?: number
  /** Per-conversation events. Typically a single-element array. */
  messaging?: MessengerMessagingEntry[]
}

MessengerWebhookPayload

Top-level Messenger webhook envelope.

interface MessengerWebhookPayload {
  /** Always `'page'` for Messenger Platform webhooks. */
  object?: string
  /** Per-page event groups. */
  entry?: MessengerWebhookEntry[]
}

ProcessEnv

Environment variables consumed by the Messenger channel provider.

interface ProcessEnv {
  /** Page access token (`EAA…`). Required for outbound sends. */
  CHANNEL_MESSENGER_PAGE_ACCESS_TOKEN: string

  /** Facebook app secret used to verify inbound webhook signatures. */
  CHANNEL_MESSENGER_APP_SECRET: string
}

Types

MessengerMessagingType

Messenger messaging_type values accepted on the Send API.

type MessengerMessagingType = 'RESPONSE' | 'UPDATE' | 'MESSAGE_TAG'

Classes

MessengerChannelProvider

Concrete Messenger Platform implementation of {@link ChannelProvider}.

Functions

createProvider(config)

Convenience factory for the named-multi-provider bond pattern.

function createProvider(config?: MessengerConfig): MessengerChannelProvider
  • config — Optional Messenger config.

Returns: A new {@link MessengerChannelProvider} instance.

Constants

channelMessengerSecretDefinitions

Secret definitions required by the Messenger channel bond.

const channelMessengerSecretDefinitions: SecretDefinition[]

provider

Lazily-instantiated singleton instance for app-startup wiring. Reads configuration from environment variables on first use.

const provider: ChannelProvider

Core Interface

Implements @molecule/api-channel interface.

Injection Notes

Requirements

Peer dependencies:

  • @molecule/api-channel ^1.0.1
  • @molecule/api-secrets ^1.0.1

Environment Variables

  • CHANNEL_MESSENGER_PAGE_ACCESS_TOKEN (required) — Messenger page access token
  • CHANNEL_MESSENGER_APP_SECRET (required) — Meta app secret

Runtime Dependencies

  • @molecule/api-channel

  • @molecule/api-secrets

  • Webhook subscription needs a GET echo the bond does not provide. When you register the webhook URL in the Meta console, Meta first sends GET ?hub.mode=subscribe&hub.verify_token=<your token>&hub.challenge=<n>. Your route must check the verify token you chose in the console and respond 200 with the raw hub.challenge value. Only POST deliveries go through verifyWebhookSignature() / parseInbound().

  • 24-hour messaging window: outside 24h since the user's last message, the Send API rejects standard sends — Meta requires an approved message tag for out-of-window messages. Expect and surface that API error.

E2E Tests

Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:

  • Each channel-notifying flow the app defines (a Slack/Discord alert on a new order, a status-change message) actually produces a message. The sandbox CAPTURES channel messages instead of sending — read them with the read_activity tool (filter type 'channel'); never mock the flow or modify production code to expose the message.
  • The captured message targets the configured channel/provider name and carries the app's real content (readable text, no undefined placeholders, no secrets).
  • A failed send (unbonded or misconfigured provider) is visible in logs/UI — never silently swallowed.