npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@molecule/api-channel-messenger

v1.0.2

Published

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.

Readme

@molecule/api-channel-messenger

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.