@mono-agent/messenger-adapter 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +302 -0
- package/dist/adapter.d.ts +261 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +1021 -0
- package/dist/adapter.js.map +1 -0
- package/dist/channel-driver.d.ts +15 -0
- package/dist/channel-driver.d.ts.map +1 -0
- package/dist/channel-driver.js +209 -0
- package/dist/channel-driver.js.map +1 -0
- package/dist/config.d.ts +108 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +187 -0
- package/dist/config.js.map +1 -0
- package/dist/graph-client.d.ts +92 -0
- package/dist/graph-client.d.ts.map +1 -0
- package/dist/graph-client.js +296 -0
- package/dist/graph-client.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/message-stream.d.ts +37 -0
- package/dist/message-stream.d.ts.map +1 -0
- package/dist/message-stream.js +62 -0
- package/dist/message-stream.js.map +1 -0
- package/dist/server.d.ts +38 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +155 -0
- package/dist/server.js.map +1 -0
- package/dist/start.d.ts +37 -0
- package/dist/start.d.ts.map +1 -0
- package/dist/start.js +77 -0
- package/dist/start.js.map +1 -0
- package/dist/text.d.ts +16 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +103 -0
- package/dist/text.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# @mono-agent/messenger-adapter
|
|
2
|
+
|
|
3
|
+
Connect a mono-agent responder to Facebook Messenger users through the Meta
|
|
4
|
+
Graph API: a signed webhook for inbound messages and the Send API for replies.
|
|
5
|
+
|
|
6
|
+
## Category
|
|
7
|
+
|
|
8
|
+
<!-- package-metadata:start -->
|
|
9
|
+
<!-- Generated by scripts/generate-package-docs.mjs. Do not edit by hand. -->
|
|
10
|
+
|
|
11
|
+
Category: `communication`
|
|
12
|
+
Tier: `plugin`
|
|
13
|
+
Catalog responsibility: Adapts Facebook Messenger webhook events to structural agent requests and delivers final-only replies through the Send API.
|
|
14
|
+
|
|
15
|
+
<!-- package-metadata:end -->
|
|
16
|
+
|
|
17
|
+
## Responsibility
|
|
18
|
+
|
|
19
|
+
Verify Meta webhook signatures, deduplicate events, authorize page-scoped user
|
|
20
|
+
ids (PSIDs), turn text, postbacks, images, and documents into agent requests,
|
|
21
|
+
queue work per user, support `/cancel`, and deliver each completed answer as
|
|
22
|
+
plain-text Send API messages. Proactive cron/webhook notifications are
|
|
23
|
+
delivered verbatim and recorded to the conversation's history.
|
|
24
|
+
|
|
25
|
+
This is a **plugin-tier** package: it publishes to npm in the mono-agent
|
|
26
|
+
lockstep at the same version as the core packages, but it is not part of the
|
|
27
|
+
core `@mono-agent/agent-app` dependency closure. `@mono-agent/agent-app` loads it
|
|
28
|
+
only when a host declares it under `channels.plugins[]`.
|
|
29
|
+
|
|
30
|
+
The adapter is opt-in: plugin `config.enabled` / `MONO_AGENT_MESSENGER_ENABLED`
|
|
31
|
+
defaults to `false`. While disabled the loader skips secret and allowlist
|
|
32
|
+
validation and the channel reports `disabled` rather than `waiting_for_config`.
|
|
33
|
+
|
|
34
|
+
## Install / Usage
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm add @mono-agent/agent-app@latest @mono-agent/messenger-adapter@latest
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Put the three Meta credentials in the agent's `.env`:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
MONO_AGENT_MESSENGER_PAGE_ACCESS_TOKEN=... # Page access token with pages_messaging
|
|
44
|
+
MONO_AGENT_MESSENGER_APP_SECRET=... # App secret, verifies X-Hub-Signature-256
|
|
45
|
+
MONO_AGENT_MESSENGER_VERIFY_TOKEN=... # Any string you also paste into the Meta webhook setup
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Then declare the plugin:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"channels": {
|
|
53
|
+
"plugins": [
|
|
54
|
+
{
|
|
55
|
+
"package": "@mono-agent/messenger-adapter",
|
|
56
|
+
"id": "messenger",
|
|
57
|
+
"config": {
|
|
58
|
+
"enabled": true,
|
|
59
|
+
"allowedUserIds": ["1234567890123456"],
|
|
60
|
+
"host": "0.0.0.0",
|
|
61
|
+
"port": 8650,
|
|
62
|
+
"allowNonLoopback": true,
|
|
63
|
+
"webhookPath": "/messenger/webhook"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Expose the webhook over HTTPS (reverse proxy or tunnel) and register
|
|
72
|
+
`https://<public-host>/messenger/webhook` in the Meta app's Messenger webhook
|
|
73
|
+
settings with the same verify token, subscribing to the `messages` and
|
|
74
|
+
`messaging_postbacks` fields. `GET <path>/health` answers `{"ok":true}` for
|
|
75
|
+
liveness checks.
|
|
76
|
+
|
|
77
|
+
## Architecture
|
|
78
|
+
|
|
79
|
+
### Data flow
|
|
80
|
+
|
|
81
|
+
1. The channel driver layers plugin JSON and environment settings, validates
|
|
82
|
+
secrets and the PSID allowlist, then starts the webhook server on the
|
|
83
|
+
configured host and port.
|
|
84
|
+
2. The server answers Meta's `hub.challenge` handshake, verifies each POST's
|
|
85
|
+
`X-Hub-Signature-256` over the raw body, acknowledges with 200, and hands the
|
|
86
|
+
parsed payload to the adapter afterwards so Meta never waits on a model turn.
|
|
87
|
+
3. The adapter drops echoes, receipts, and duplicate message ids, rejects
|
|
88
|
+
unauthorized senders with a one-line denial, normalizes text, postbacks, and
|
|
89
|
+
attachments (downloading images and documents from Meta's CDN), and handles
|
|
90
|
+
`/start`, `/help`, and `/cancel` without a model call.
|
|
91
|
+
4. Allowed prompts enter the host-owned structural responder behind a per-user
|
|
92
|
+
queue with typing indicators. The message stream buffers deltas, flattens
|
|
93
|
+
Markdown, and posts the final answer as 2,000-character Send API messages.
|
|
94
|
+
5. Proactive notifications (`messenger:<psid>` destinations) are posted verbatim
|
|
95
|
+
with the configured `messaging_type`/tag and recorded to conversation history;
|
|
96
|
+
process-job wakes steer into an active run or fall back to a follow-up turn.
|
|
97
|
+
6. Shutdown closes the webhook server and aborts active responder work.
|
|
98
|
+
|
|
99
|
+
### Package structure
|
|
100
|
+
|
|
101
|
+
| Source module | Responsibility |
|
|
102
|
+
| --- | --- |
|
|
103
|
+
| [`channel-driver.ts`](https://github.com/robertsreberski/mono-agent/blob/main/extras/messenger-adapter/src/channel-driver.ts) | Config-first plugin lifecycle, proactive notify routing, and process-job delivery. |
|
|
104
|
+
| [`config.ts`](https://github.com/robertsreberski/mono-agent/blob/main/extras/messenger-adapter/src/config.ts) | JSON/env layering, secret and allowlist validation, loopback guard, and redacted config metadata. |
|
|
105
|
+
| [`server.ts`](https://github.com/robertsreberski/mono-agent/blob/main/extras/messenger-adapter/src/server.ts) | Meta verification handshake, signature check, body limits, and health endpoint. |
|
|
106
|
+
| [`adapter.ts`](https://github.com/robertsreberski/mono-agent/blob/main/extras/messenger-adapter/src/adapter.ts) | Dedup, authorization, normalization, attachment ingest, per-user queue, commands, cancellation, responder invocation, and proactive delivery. |
|
|
107
|
+
| [`graph-client.ts`](https://github.com/robertsreberski/mono-agent/blob/main/extras/messenger-adapter/src/graph-client.ts) | Send API client for text chunks, attachment URLs, and sender actions. Replay-safe sender actions retry once; message POSTs retry only a `429` and surface every other unknown outcome as an ambiguous delivery. Graph errors are scrubbed of the configured token. |
|
|
108
|
+
| [`message-stream.ts`](https://github.com/robertsreberski/mono-agent/blob/main/extras/messenger-adapter/src/message-stream.ts) | Buffered final-only answer delivery with Markdown flattening. |
|
|
109
|
+
| [`text.ts`](https://github.com/robertsreberski/mono-agent/blob/main/extras/messenger-adapter/src/text.ts) | Signature verification, Markdown stripping, and code-point-safe chunking. |
|
|
110
|
+
| [`start.ts`](https://github.com/robertsreberski/mono-agent/blob/main/extras/messenger-adapter/src/start.ts) | Composition root wiring client, adapter, and server into one start/stop handle. |
|
|
111
|
+
|
|
112
|
+
### Configuration
|
|
113
|
+
|
|
114
|
+
| Key | Env | Default | Purpose |
|
|
115
|
+
| --- | --- | --- | --- |
|
|
116
|
+
| `enabled` | `MONO_AGENT_MESSENGER_ENABLED` | `false` | Opt-in switch. |
|
|
117
|
+
| — | `MONO_AGENT_MESSENGER_PAGE_ACCESS_TOKEN` | — | Secret, **env-only**. Page token used for the Send API. Rejected in JSON. |
|
|
118
|
+
| — | `MONO_AGENT_MESSENGER_APP_SECRET` | — | Secret, **env-only**. HMAC key for webhook signature verification. Rejected in JSON. |
|
|
119
|
+
| — | `MONO_AGENT_MESSENGER_VERIFY_TOKEN` | — | Secret, **env-only**. Expected `hub.verify_token` during webhook setup. Rejected in JSON. |
|
|
120
|
+
| `allowedUserIds` | `MONO_AGENT_MESSENGER_ALLOWED_USER_IDS` | `[]` | PSIDs allowed to talk to the agent. |
|
|
121
|
+
| `allowAllUsers` | `MONO_AGENT_MESSENGER_ALLOW_ALL_USERS` | `false` | Allow every user (ignores the allowlist). |
|
|
122
|
+
| `host` | `MONO_AGENT_MESSENGER_HOST` | `127.0.0.1` | Bind address. Non-loopback needs `allowNonLoopback`. |
|
|
123
|
+
| `port` | `MONO_AGENT_MESSENGER_PORT` | `8650` | Bind port. |
|
|
124
|
+
| `webhookPath` | `MONO_AGENT_MESSENGER_WEBHOOK_PATH` | `/messenger/webhook` | Webhook route; `/health` is appended for liveness. |
|
|
125
|
+
| `apiVersion` | `MONO_AGENT_MESSENGER_API_VERSION` | `v21.0` | Graph API version. |
|
|
126
|
+
| `allowNonLoopback` | `MONO_AGENT_MESSENGER_ALLOW_NON_LOOPBACK` | `false` | Explicit opt-in to bind a non-loopback host, enforced at load, at `startMessengerAdapter`, and immediately before `listen()`. |
|
|
127
|
+
| `proactiveMessagingType` | `MONO_AGENT_MESSENGER_PROACTIVE_MESSAGING_TYPE` | `RESPONSE` | `messaging_type` for cron/webhook deliveries (`RESPONSE`, `UPDATE`, `MESSAGE_TAG`). |
|
|
128
|
+
| `proactiveTag` | `MONO_AGENT_MESSENGER_PROACTIVE_TAG` | — | Required with `MESSAGE_TAG`, e.g. `CONFIRMED_EVENT_UPDATE`. |
|
|
129
|
+
|
|
130
|
+
Meta only delivers ordinary messages inside the 24-hour window after the
|
|
131
|
+
user's last message. A scheduled reminder that may fire outside that window
|
|
132
|
+
needs `proactiveMessagingType: "MESSAGE_TAG"` plus a policy-compliant tag.
|
|
133
|
+
|
|
134
|
+
### Conversation ids and notifications
|
|
135
|
+
|
|
136
|
+
Conversations are keyed `messenger:<psid>`. Cron jobs and webhook endpoints can
|
|
137
|
+
target one with `notifyConversationId: "messenger:<psid>"`; the final answer is
|
|
138
|
+
posted verbatim, Markdown flattened, split into 2,000-character messages, and
|
|
139
|
+
recorded to that conversation's history. Destinations outside the allowlist are
|
|
140
|
+
refused by the adapter.
|
|
141
|
+
|
|
142
|
+
### Behaviour notes
|
|
143
|
+
|
|
144
|
+
- Meta expects a 200 within seconds; the server acknowledges first and processes
|
|
145
|
+
the payload afterwards. Duplicate deliveries are dropped by message id.
|
|
146
|
+
- Messages from one user are handled in order. Up to four wait behind the
|
|
147
|
+
active turn; beyond that the user gets a short busy reply.
|
|
148
|
+
- `/cancel` aborts the active turn and retires every prompt already queued
|
|
149
|
+
behind it, so a withdrawn message never answers later; a message sent after
|
|
150
|
+
the cancel runs normally. `/help` and `/start` answer without a model call.
|
|
151
|
+
- Image and PDF/text attachments are downloaded from Meta's CDN and passed to
|
|
152
|
+
the agent; audio, video, and other files are described in the request text
|
|
153
|
+
with their URL. Downloads are bounded by an explicit host policy (HTTPS on
|
|
154
|
+
`fbcdn.net` / `fbsbx.com` by default, configurable via
|
|
155
|
+
`attachments.allowedHostSuffixes`): redirects are followed manually with
|
|
156
|
+
every hop re-validated, hostnames must resolve entirely to public addresses,
|
|
157
|
+
and the 20 MiB cap is applied while streaming rather than after buffering.
|
|
158
|
+
- A background wake reserves its per-user queue slot BEFORE offering live input
|
|
159
|
+
to the active turn, so a prompt arriving mid-offer cannot overtake it.
|
|
160
|
+
- Replies are plain text: Markdown is flattened before sending.
|
|
161
|
+
- Unauthorized senders receive a one-line denial and are logged; their text
|
|
162
|
+
never reaches the agent.
|
|
163
|
+
|
|
164
|
+
## Public API
|
|
165
|
+
|
|
166
|
+
### Start here
|
|
167
|
+
|
|
168
|
+
| API | Use it for |
|
|
169
|
+
| --- | --- |
|
|
170
|
+
| `createChannelDriver` / `createMessengerChannelDriver` | Load the adapter through a config-first `channels.plugins[]` entry. |
|
|
171
|
+
| `startMessengerAdapter` | Start the Graph client, adapter, and webhook server together in a custom host. |
|
|
172
|
+
| `MessengerAdapter` | Apply signature-verified webhook events, authorization, commands, cancellation, and responder behavior. |
|
|
173
|
+
| `MessengerAdapter.notify` | Deliver a proactive message verbatim or as a follow-up turn for one user. |
|
|
174
|
+
| `createMessengerWebhookServer` | Serve the Meta verification handshake and signed webhook POSTs. |
|
|
175
|
+
| `MessengerGraphClient` | Send text, attachment URLs, and sender actions through the Send API. |
|
|
176
|
+
| `MessengerMessageStream` | Reuse buffered plain-text final-answer delivery. |
|
|
177
|
+
| `loadMessengerAdapterConfig` | Validate and redact plugin/env config without starting the channel. |
|
|
178
|
+
| `verifyMessengerSignature` / `splitForMessenger` / `stripMarkdownForMessenger` | Reuse the webhook signature check and text shaping helpers. |
|
|
179
|
+
|
|
180
|
+
<!-- public-api-inventory:start -->
|
|
181
|
+
<!-- Generated by scripts/generate-public-api-docs.mjs. Do not edit by hand. -->
|
|
182
|
+
|
|
183
|
+
Every symbol exported by each public code entrypoint is listed below.
|
|
184
|
+
|
|
185
|
+
**`@mono-agent/messenger-adapter`**
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
AgentMessageStream
|
|
189
|
+
AgentRequest
|
|
190
|
+
AgentResponder
|
|
191
|
+
AgentResponse
|
|
192
|
+
DEFAULT_GRAPH_API_BASE_URL
|
|
193
|
+
DEFAULT_MESSENGER_API_VERSION
|
|
194
|
+
DEFAULT_MESSENGER_ATTACHMENT_HOST_SUFFIXES
|
|
195
|
+
DEFAULT_MESSENGER_HOST
|
|
196
|
+
DEFAULT_MESSENGER_PORT
|
|
197
|
+
DEFAULT_MESSENGER_WEBHOOK_PATH
|
|
198
|
+
LoadMessengerAdapterConfigInput
|
|
199
|
+
MESSENGER_CHANNEL_ID
|
|
200
|
+
MESSENGER_CONFIG_FIELDS
|
|
201
|
+
MESSENGER_ENV_ONLY_SECRET_KEYS
|
|
202
|
+
MESSENGER_MAX_MESSAGE_CHARS
|
|
203
|
+
MESSENGER_MESSAGING_TYPES
|
|
204
|
+
MessengerAdapter
|
|
205
|
+
MessengerAdapterConfig
|
|
206
|
+
MessengerAdapterConfigError
|
|
207
|
+
MessengerAdapterConfigErrorCode
|
|
208
|
+
MessengerAdapterConfigErrorDetails
|
|
209
|
+
MessengerAdapterLogger
|
|
210
|
+
MessengerAdapterMessages
|
|
211
|
+
MessengerAdapterOptions
|
|
212
|
+
MessengerAdapterStartLogger
|
|
213
|
+
MessengerAdapterStartResult
|
|
214
|
+
MessengerAmbiguousDeliveryError
|
|
215
|
+
MessengerAttachmentIngestOptions
|
|
216
|
+
MessengerChannelDriverConfig
|
|
217
|
+
MessengerChannelDriverOptions
|
|
218
|
+
MessengerEventResult
|
|
219
|
+
MessengerGraphClient
|
|
220
|
+
MessengerGraphClientLike
|
|
221
|
+
MessengerGraphClientLogger
|
|
222
|
+
MessengerGraphClientOptions
|
|
223
|
+
MessengerGraphError
|
|
224
|
+
MessengerIgnoredReason
|
|
225
|
+
MessengerMessageStream
|
|
226
|
+
MessengerMessageStreamLogger
|
|
227
|
+
MessengerMessageStreamOptions
|
|
228
|
+
MessengerMessagingType
|
|
229
|
+
MessengerNotifyOptions
|
|
230
|
+
MessengerNotifyResult
|
|
231
|
+
MessengerProactiveOptions
|
|
232
|
+
MessengerRequestMetadata
|
|
233
|
+
MessengerSendOptions
|
|
234
|
+
MessengerSendResult
|
|
235
|
+
MessengerSenderAction
|
|
236
|
+
MessengerWebhookAttachment
|
|
237
|
+
MessengerWebhookEvent
|
|
238
|
+
MessengerWebhookServer
|
|
239
|
+
MessengerWebhookServerLogger
|
|
240
|
+
MessengerWebhookServerOptions
|
|
241
|
+
RedactedMessengerAdapterConfig
|
|
242
|
+
StartMessengerAdapterOptions
|
|
243
|
+
assertMessengerBindAllowed
|
|
244
|
+
assertNoMessengerSecretsInJson
|
|
245
|
+
assertValidMessengerAdapterConfig
|
|
246
|
+
attachmentUrlPolicyRejection
|
|
247
|
+
createChannelDriver
|
|
248
|
+
createMessengerChannelDriver
|
|
249
|
+
createMessengerWebhookServer
|
|
250
|
+
isLoopbackHost
|
|
251
|
+
isMessengerAmbiguousDeliveryError
|
|
252
|
+
isPublicUnicastAddress
|
|
253
|
+
isSafeAttachmentUrl
|
|
254
|
+
loadMessengerAdapterConfig
|
|
255
|
+
messengerConversationId
|
|
256
|
+
messengerUserIdFromConversation
|
|
257
|
+
redactMessengerAdapterConfig
|
|
258
|
+
splitForMessenger
|
|
259
|
+
startMessengerAdapter
|
|
260
|
+
stripMarkdownForMessenger
|
|
261
|
+
verifyMessengerSignature
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
<!-- public-api-inventory:end -->
|
|
265
|
+
|
|
266
|
+
### Programmatic use
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
import { loadMessengerAdapterConfig, startMessengerAdapter } from "@mono-agent/messenger-adapter";
|
|
270
|
+
|
|
271
|
+
const config = await loadMessengerAdapterConfig({ env: process.env, jsonPath: "./mono-agent.config.json" });
|
|
272
|
+
const running = await startMessengerAdapter({ config, responder });
|
|
273
|
+
await running.notify("1234567890123456", "Reminder text", { verbatim: true });
|
|
274
|
+
await running.stop();
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Dependency Boundary
|
|
278
|
+
|
|
279
|
+
Depends only on `@mono-agent/agent-contracts` and Node's built-in `http`,
|
|
280
|
+
`crypto`, and global `fetch`. It never imports the app host, harness, other
|
|
281
|
+
adapters, or operator surfaces.
|
|
282
|
+
|
|
283
|
+
## What This Package Does Not Own
|
|
284
|
+
|
|
285
|
+
It does not own the Meta app or Page, TLS termination or the public URL for the
|
|
286
|
+
webhook, Meta's messaging-window policy, prompt building, model execution,
|
|
287
|
+
memory, or an operator UI.
|
|
288
|
+
|
|
289
|
+
## Related Documentation
|
|
290
|
+
|
|
291
|
+
- [Messenger channel guide](https://mono-agent-docs.vercel.app/channels/messenger/)
|
|
292
|
+
- [Channels overview](https://mono-agent-docs.vercel.app/channels/)
|
|
293
|
+
- [Delivery and send tools](https://mono-agent-docs.vercel.app/channels/delivery-and-send-tools/)
|
|
294
|
+
- [Write your own channel adapter](https://mono-agent-docs.vercel.app/programmatic/custom-channels/)
|
|
295
|
+
|
|
296
|
+
## Verification
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
pnpm --filter @mono-agent/messenger-adapter run build
|
|
300
|
+
pnpm --filter @mono-agent/messenger-adapter run typecheck
|
|
301
|
+
pnpm --filter @mono-agent/messenger-adapter run test
|
|
302
|
+
```
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { type AgentMessageStream, type AgentRequestBase, type AgentResponder as SharedAgentResponder, type AgentResponse, type NotifyDeliveryResult, type ProcessJobProjection, type ProcessJobWakeDisposition } from "@mono-agent/agent-contracts";
|
|
2
|
+
import type { MessengerMessagingType } from "./config.js";
|
|
3
|
+
import type { MessengerGraphClientLike } from "./graph-client.js";
|
|
4
|
+
import { type MessengerMessageStreamLogger } from "./message-stream.js";
|
|
5
|
+
export declare const MESSENGER_CHANNEL_ID = "messenger";
|
|
6
|
+
/** Conversation id for a Messenger user: `messenger:<psid>`. */
|
|
7
|
+
export declare function messengerConversationId(userId: string): string;
|
|
8
|
+
/** Parse `messenger:<psid>` back into the PSID; undefined for any other shape. */
|
|
9
|
+
export declare function messengerUserIdFromConversation(conversationId: string): string | undefined;
|
|
10
|
+
export interface MessengerWebhookAttachment {
|
|
11
|
+
readonly type?: string;
|
|
12
|
+
readonly title?: string;
|
|
13
|
+
readonly payload?: {
|
|
14
|
+
readonly url?: string;
|
|
15
|
+
readonly coordinates?: {
|
|
16
|
+
readonly lat?: number;
|
|
17
|
+
readonly long?: number;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** One `entry[].messaging[]` event from a Messenger webhook payload. */
|
|
22
|
+
export interface MessengerWebhookEvent {
|
|
23
|
+
readonly sender?: {
|
|
24
|
+
readonly id?: string;
|
|
25
|
+
};
|
|
26
|
+
readonly recipient?: {
|
|
27
|
+
readonly id?: string;
|
|
28
|
+
};
|
|
29
|
+
readonly timestamp?: number;
|
|
30
|
+
readonly message?: {
|
|
31
|
+
readonly mid?: string;
|
|
32
|
+
readonly text?: string;
|
|
33
|
+
readonly is_echo?: boolean;
|
|
34
|
+
readonly attachments?: readonly MessengerWebhookAttachment[];
|
|
35
|
+
};
|
|
36
|
+
readonly postback?: {
|
|
37
|
+
readonly mid?: string;
|
|
38
|
+
readonly title?: string;
|
|
39
|
+
readonly payload?: string;
|
|
40
|
+
};
|
|
41
|
+
readonly delivery?: unknown;
|
|
42
|
+
readonly read?: unknown;
|
|
43
|
+
}
|
|
44
|
+
export interface MessengerRequestMetadata {
|
|
45
|
+
readonly user: {
|
|
46
|
+
readonly id: string;
|
|
47
|
+
};
|
|
48
|
+
readonly page?: {
|
|
49
|
+
readonly id: string;
|
|
50
|
+
};
|
|
51
|
+
readonly message: {
|
|
52
|
+
readonly id?: string;
|
|
53
|
+
readonly timestamp?: number;
|
|
54
|
+
};
|
|
55
|
+
readonly attachmentTypes: readonly string[];
|
|
56
|
+
readonly trigger: "message" | "postback" | "proactive";
|
|
57
|
+
}
|
|
58
|
+
export interface AgentRequest extends AgentRequestBase {
|
|
59
|
+
readonly conversationId: string;
|
|
60
|
+
readonly userId: string;
|
|
61
|
+
readonly messageId?: string;
|
|
62
|
+
readonly text: string;
|
|
63
|
+
readonly abortSignal: AbortSignal;
|
|
64
|
+
readonly metadata: {
|
|
65
|
+
readonly messenger: MessengerRequestMetadata;
|
|
66
|
+
readonly [key: string]: unknown;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export type { AgentResponse };
|
|
70
|
+
export type AgentResponder = SharedAgentResponder<AgentRequest, AgentMessageStream, AgentResponse>;
|
|
71
|
+
export interface MessengerAdapterMessages {
|
|
72
|
+
welcomeText?: string;
|
|
73
|
+
helpText?: string;
|
|
74
|
+
busyText?: string;
|
|
75
|
+
unauthorizedText?: string;
|
|
76
|
+
cancelledText?: string;
|
|
77
|
+
errorText?: string;
|
|
78
|
+
unsupportedText?: string;
|
|
79
|
+
}
|
|
80
|
+
export interface MessengerAdapterLogger extends MessengerMessageStreamLogger {
|
|
81
|
+
info?(message: string, metadata?: Record<string, unknown>): void;
|
|
82
|
+
}
|
|
83
|
+
export interface MessengerAttachmentIngestOptions {
|
|
84
|
+
readonly fetch?: typeof fetch;
|
|
85
|
+
readonly maxBytes?: number;
|
|
86
|
+
readonly timeoutMs?: number;
|
|
87
|
+
/**
|
|
88
|
+
* Explicit host policy for attachment downloads. Only hostnames equal to, or
|
|
89
|
+
* a subdomain of, one of these suffixes are contacted. Defaults to Meta's
|
|
90
|
+
* media CDNs ({@link DEFAULT_MESSENGER_ATTACHMENT_HOST_SUFFIXES}) — the only
|
|
91
|
+
* origin a Messenger webhook legitimately points at. Pass `[]` to disable
|
|
92
|
+
* attachment downloads entirely.
|
|
93
|
+
*/
|
|
94
|
+
readonly allowedHostSuffixes?: readonly string[];
|
|
95
|
+
/** Resolves a hostname to IP addresses. Test seam; defaults to the system resolver. */
|
|
96
|
+
readonly resolveAddresses?: (hostname: string) => Promise<readonly string[]>;
|
|
97
|
+
}
|
|
98
|
+
export interface MessengerProactiveOptions {
|
|
99
|
+
readonly messagingType: MessengerMessagingType;
|
|
100
|
+
readonly tag?: string;
|
|
101
|
+
}
|
|
102
|
+
export interface MessengerAdapterOptions {
|
|
103
|
+
readonly client: MessengerGraphClientLike;
|
|
104
|
+
readonly responder: AgentResponder;
|
|
105
|
+
readonly allowedUserIds?: readonly string[];
|
|
106
|
+
readonly allowAllUsers?: boolean;
|
|
107
|
+
readonly messages?: MessengerAdapterMessages;
|
|
108
|
+
readonly logger?: MessengerAdapterLogger;
|
|
109
|
+
readonly attachments?: MessengerAttachmentIngestOptions;
|
|
110
|
+
readonly proactive?: MessengerProactiveOptions;
|
|
111
|
+
/** Inbound messages queued per user while a turn runs; beyond it the user gets `busyText`. */
|
|
112
|
+
readonly maxQueuedPerUser?: number;
|
|
113
|
+
readonly maxMessageChars?: number;
|
|
114
|
+
}
|
|
115
|
+
export interface MessengerNotifyOptions {
|
|
116
|
+
readonly verbatim?: boolean;
|
|
117
|
+
readonly deliveryKey?: string;
|
|
118
|
+
readonly steerActive?: boolean;
|
|
119
|
+
}
|
|
120
|
+
export interface MessengerNotifyResult extends NotifyDeliveryResult {
|
|
121
|
+
readonly disposition?: ProcessJobWakeDisposition;
|
|
122
|
+
}
|
|
123
|
+
export type MessengerIgnoredReason = "echo" | "receipt" | "no_sender" | "no_content" | "duplicate" | "empty_text";
|
|
124
|
+
export type MessengerEventResult = {
|
|
125
|
+
kind: "handled";
|
|
126
|
+
userId: string;
|
|
127
|
+
messageId?: string;
|
|
128
|
+
action: "command" | "responded";
|
|
129
|
+
command?: "start" | "help";
|
|
130
|
+
} | {
|
|
131
|
+
kind: "ignored";
|
|
132
|
+
reason: MessengerIgnoredReason;
|
|
133
|
+
userId?: string;
|
|
134
|
+
messageId?: string;
|
|
135
|
+
} | {
|
|
136
|
+
kind: "unauthorized";
|
|
137
|
+
userId: string;
|
|
138
|
+
messageId?: string;
|
|
139
|
+
} | {
|
|
140
|
+
kind: "busy";
|
|
141
|
+
userId: string;
|
|
142
|
+
messageId?: string;
|
|
143
|
+
} | {
|
|
144
|
+
kind: "cancelled";
|
|
145
|
+
userId: string;
|
|
146
|
+
messageId?: string;
|
|
147
|
+
} | {
|
|
148
|
+
kind: "error";
|
|
149
|
+
userId?: string;
|
|
150
|
+
messageId?: string;
|
|
151
|
+
error: unknown;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Meta's media CDNs. Messenger attachment payload URLs are signed links into
|
|
155
|
+
* these origins, so an explicit allowlist — rather than "any public-looking
|
|
156
|
+
* HTTPS host" — is what actually bounds this downloader.
|
|
157
|
+
*/
|
|
158
|
+
export declare const DEFAULT_MESSENGER_ATTACHMENT_HOST_SUFFIXES: readonly string[];
|
|
159
|
+
export declare class MessengerAdapter {
|
|
160
|
+
private readonly client;
|
|
161
|
+
private readonly responder;
|
|
162
|
+
private readonly allowAllUsers;
|
|
163
|
+
private readonly allowedUserIds;
|
|
164
|
+
private readonly messages;
|
|
165
|
+
private readonly logger;
|
|
166
|
+
private readonly ingest;
|
|
167
|
+
private readonly proactive;
|
|
168
|
+
private readonly maxQueuedPerUser;
|
|
169
|
+
private readonly maxMessageChars;
|
|
170
|
+
private readonly dedup;
|
|
171
|
+
/**
|
|
172
|
+
* Every controller admitted for a user, registered BEFORE the work reaches
|
|
173
|
+
* the per-user queue. Registering eagerly is what lets `/cancel` retire a
|
|
174
|
+
* prompt that is still parked behind an earlier run — a controller created
|
|
175
|
+
* only at execution time would not exist yet.
|
|
176
|
+
*/
|
|
177
|
+
private readonly pendingControllers;
|
|
178
|
+
private readonly queueTails;
|
|
179
|
+
/** Admitted work per user: at most one active turn plus `maxQueuedPerUser` waiting. */
|
|
180
|
+
private readonly admitted;
|
|
181
|
+
private stopping;
|
|
182
|
+
constructor(options: MessengerAdapterOptions);
|
|
183
|
+
/** Process one full webhook payload (`{ object: "page", entry: [...] }`). */
|
|
184
|
+
handleWebhookPayload(payload: unknown): Promise<MessengerEventResult[]>;
|
|
185
|
+
handleEvent(event: MessengerWebhookEvent): Promise<MessengerEventResult>;
|
|
186
|
+
/** Stop accepting work and abort every active turn. */
|
|
187
|
+
stop(reason?: unknown): void;
|
|
188
|
+
/**
|
|
189
|
+
* Proactive delivery. With `verbatim`, `text` is posted unchanged (no model
|
|
190
|
+
* call) and recorded to history; otherwise it runs as a turn for the user and
|
|
191
|
+
* the answer is delivered. Enforces the adapter allowlist.
|
|
192
|
+
*/
|
|
193
|
+
notify(userId: string, text: string, options?: MessengerNotifyOptions): Promise<MessengerNotifyResult>;
|
|
194
|
+
/**
|
|
195
|
+
* Offer a wake to the active turn, having RESERVED this user's queue slot
|
|
196
|
+
* first.
|
|
197
|
+
*
|
|
198
|
+
* The `AgentLiveInputOffer` contract requires an accepted offer to stay
|
|
199
|
+
* represented by its reserved normal-turn slot until `settled` says whether
|
|
200
|
+
* that reservation runs or becomes a no-op. Offering first and enqueueing
|
|
201
|
+
* only afterwards lets a prompt that arrives during the offer overtake the
|
|
202
|
+
* wake; reserving first keeps arrival order. Every settlement path —
|
|
203
|
+
* accepted/applied, requeue, discard, uncertain, unavailable, and a throwing
|
|
204
|
+
* offer — resolves the reservation exactly once.
|
|
205
|
+
*/
|
|
206
|
+
private steerOrRunReserved;
|
|
207
|
+
updateProcessJob(userId: string, projection: ProcessJobProjection): Promise<NotifyDeliveryResult>;
|
|
208
|
+
/** Create and register a controller for a user BEFORE the work is admitted. */
|
|
209
|
+
private registerController;
|
|
210
|
+
private unregisterController;
|
|
211
|
+
/** Abort every controller currently admitted for a user (active and parked). */
|
|
212
|
+
private cancelPending;
|
|
213
|
+
/** Append work to a user's serial queue, tracking admitted depth for the busy cap. */
|
|
214
|
+
private admit;
|
|
215
|
+
private respondToInbound;
|
|
216
|
+
private runProactiveTurn;
|
|
217
|
+
private deliverVerbatim;
|
|
218
|
+
private normalizeInbound;
|
|
219
|
+
/**
|
|
220
|
+
* Fetch one attachment under an explicit host policy.
|
|
221
|
+
*
|
|
222
|
+
* Redirects are followed MANUALLY so every hop is re-validated: the original
|
|
223
|
+
* URL being a signed Meta link says nothing about where a `Location` header
|
|
224
|
+
* points. Each hop must satisfy the host allowlist AND resolve entirely to
|
|
225
|
+
* public addresses, so neither an open redirect nor a hostname whose DNS
|
|
226
|
+
* answer is loopback/private/link-local can reach internal resources. The
|
|
227
|
+
* body is then read incrementally against the size cap, so a chunked
|
|
228
|
+
* response with an absent or lying `Content-Length` cannot exhaust memory.
|
|
229
|
+
*/
|
|
230
|
+
private downloadAttachment;
|
|
231
|
+
/**
|
|
232
|
+
* Full per-hop admission check: the static URL policy, then DNS resolution
|
|
233
|
+
* with every returned address required to be public. Returns a short
|
|
234
|
+
* rejection reason, or `undefined` when the hop may be fetched.
|
|
235
|
+
*/
|
|
236
|
+
private attachmentUrlRejection;
|
|
237
|
+
private createStream;
|
|
238
|
+
private proactiveSend;
|
|
239
|
+
private isAuthorized;
|
|
240
|
+
private finishCancelledUnlessAcknowledged;
|
|
241
|
+
private finishSafely;
|
|
242
|
+
private sendTextSafely;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Static URL policy for an attachment download: HTTPS, no embedded
|
|
246
|
+
* credentials, no literal IP host, and a hostname inside the configured
|
|
247
|
+
* allowlist. Returns a short rejection reason, or `undefined` when the URL
|
|
248
|
+
* passes. Address resolution is a separate, asynchronous check —
|
|
249
|
+
* see {@link MessengerAdapter.attachmentUrlRejection}.
|
|
250
|
+
*/
|
|
251
|
+
export declare function attachmentUrlPolicyRejection(url: string, allowedHostSuffixes?: readonly string[]): string | undefined;
|
|
252
|
+
/** Only fetch https URLs on allowlisted Meta CDN hostnames. */
|
|
253
|
+
export declare function isSafeAttachmentUrl(url: string, allowedHostSuffixes?: readonly string[]): boolean;
|
|
254
|
+
/**
|
|
255
|
+
* True only for a globally routable unicast address. Everything else —
|
|
256
|
+
* loopback, private, link-local, CGNAT, multicast, and the reserved/documentation
|
|
257
|
+
* ranges — is rejected, so a hostname whose DNS answer points inside the
|
|
258
|
+
* deployment cannot be fetched.
|
|
259
|
+
*/
|
|
260
|
+
export declare function isPublicUnicastAddress(address: string): boolean;
|
|
261
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|