@0xmaxma/claude-gateway 1.8.10 → 1.8.12
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/README.md +14 -1
- package/config.template.json +2 -1
- package/dist/agent/runner.d.ts +72 -0
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +300 -6
- package/dist/agent/runner.js.map +1 -1
- package/dist/api/router.d.ts.map +1 -1
- package/dist/api/router.js +1001 -4
- package/dist/api/router.js.map +1 -1
- package/dist/api/webhooks-router.d.ts +2 -0
- package/dist/api/webhooks-router.d.ts.map +1 -1
- package/dist/api/webhooks-router.js +2 -0
- package/dist/api/webhooks-router.js.map +1 -1
- package/dist/api/whatsapp-access.d.ts +123 -0
- package/dist/api/whatsapp-access.d.ts.map +1 -0
- package/dist/api/whatsapp-access.js +135 -0
- package/dist/api/whatsapp-access.js.map +1 -0
- package/dist/api/whatsapp-cloud-access.d.ts +48 -0
- package/dist/api/whatsapp-cloud-access.d.ts.map +1 -0
- package/dist/api/whatsapp-cloud-access.js +58 -0
- package/dist/api/whatsapp-cloud-access.js.map +1 -0
- package/dist/api/whatsapp-cloud-client.d.ts +143 -0
- package/dist/api/whatsapp-cloud-client.d.ts.map +1 -0
- package/dist/api/whatsapp-cloud-client.js +298 -0
- package/dist/api/whatsapp-cloud-client.js.map +1 -0
- package/dist/api/whatsapp-cloud-webhook-router.d.ts +132 -0
- package/dist/api/whatsapp-cloud-webhook-router.d.ts.map +1 -0
- package/dist/api/whatsapp-cloud-webhook-router.js +494 -0
- package/dist/api/whatsapp-cloud-webhook-router.js.map +1 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +7 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/whatsapp-accounts.d.ts +77 -0
- package/dist/config/whatsapp-accounts.d.ts.map +1 -0
- package/dist/config/whatsapp-accounts.js +218 -0
- package/dist/config/whatsapp-accounts.js.map +1 -0
- package/dist/history/db.d.ts.map +1 -1
- package/dist/history/db.js +43 -11
- package/dist/history/db.js.map +1 -1
- package/dist/history/types.d.ts +18 -1
- package/dist/history/types.d.ts.map +1 -1
- package/dist/history/types.js +1 -1
- package/dist/history/types.js.map +1 -1
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/session/process.d.ts.map +1 -1
- package/dist/session/process.js +37 -0
- package/dist/session/process.js.map +1 -1
- package/dist/shared/image-optimize.d.ts +32 -0
- package/dist/shared/image-optimize.d.ts.map +1 -0
- package/dist/shared/image-optimize.js +197 -0
- package/dist/shared/image-optimize.js.map +1 -0
- package/dist/shared/image-sniff.d.ts +9 -0
- package/dist/shared/image-sniff.d.ts.map +1 -1
- package/dist/shared/image-sniff.js +13 -0
- package/dist/shared/image-sniff.js.map +1 -1
- package/dist/shared/text-chunk.d.ts +37 -0
- package/dist/shared/text-chunk.d.ts.map +1 -0
- package/dist/shared/text-chunk.js +105 -0
- package/dist/shared/text-chunk.js.map +1 -0
- package/dist/shared/whatsapp-ack.d.ts +13 -0
- package/dist/shared/whatsapp-ack.d.ts.map +1 -0
- package/dist/shared/whatsapp-ack.js +16 -0
- package/dist/shared/whatsapp-ack.js.map +1 -0
- package/dist/types.d.ts +158 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/whatsapp/manager.d.ts +173 -0
- package/dist/whatsapp/manager.d.ts.map +1 -0
- package/dist/whatsapp/manager.js +838 -0
- package/dist/whatsapp/manager.js.map +1 -0
- package/mcp/server.ts +4 -0
- package/mcp/tools/whatsapp/module.ts +162 -0
- package/mcp/tools/whatsapp-cloud/module.ts +536 -0
- package/package.json +9 -4
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.extractInboundMessages = extractInboundMessages;
|
|
37
|
+
exports.synthesizeVCard = synthesizeVCard;
|
|
38
|
+
exports.normalizeWhatsAppCloudMessage = normalizeWhatsAppCloudMessage;
|
|
39
|
+
exports.verifyMetaSignature = verifyMetaSignature;
|
|
40
|
+
exports.createWhatsAppCloudWebhookHandler = createWhatsAppCloudWebhookHandler;
|
|
41
|
+
const crypto_1 = require("crypto");
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const os = __importStar(require("os"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const logger_1 = require("../logger");
|
|
46
|
+
const whatsapp_cloud_access_1 = require("./whatsapp-cloud-access");
|
|
47
|
+
const pending_senders_1 = require("./pending-senders");
|
|
48
|
+
const whatsapp_cloud_client_1 = require("./whatsapp-cloud-client");
|
|
49
|
+
const media_store_1 = require("../history/media-store");
|
|
50
|
+
const image_sniff_1 = require("../shared/image-sniff");
|
|
51
|
+
const WHATSAPP_CLOUD_API_BASE = 'https://graph.facebook.com/v20.0';
|
|
52
|
+
// Inbound media cap. Sourced from MediaStore (where the downloaded bytes end
|
|
53
|
+
// up) for both images and documents — a router-local literal could drift
|
|
54
|
+
// from what the store then rejects.
|
|
55
|
+
const MAX_MEDIA_BYTES = media_store_1.MediaStore.maxUploadBytes;
|
|
56
|
+
// Meta retries a webhook delivery if our ack is slow/dropped — message.id is
|
|
57
|
+
// the dedup key. A bounded, age-pruned map is enough (mirrors Slack's
|
|
58
|
+
// seenEventIds): it only needs to outlive Meta's short retry window, not forever.
|
|
59
|
+
const WHATSAPP_CLOUD_MESSAGE_ID_TTL_MS = 10 * 60000;
|
|
60
|
+
// The returned media download `url` must resolve to a Meta-owned host before
|
|
61
|
+
// the bearer token is ever attached to the second GET — see
|
|
62
|
+
// downloadWhatsAppCloudMedia's doc comment (mirrors downloadSlackImage's
|
|
63
|
+
// host-check-before-sending-token defense).
|
|
64
|
+
const MEDIA_HOST_ALLOWLIST = [/\.fbcdn\.net$/, /^graph\.facebook\.com$/, /^lookaside\.fbsbx\.com$/];
|
|
65
|
+
/**
|
|
66
|
+
* Extract the inbound message list from a webhook `value` object — returns
|
|
67
|
+
* [] for a status-only batch (our own outbound delivery receipts) or any
|
|
68
|
+
* payload shape without a `messages` array at all, so callers never try to
|
|
69
|
+
* normalize a status update as an inbound message.
|
|
70
|
+
*/
|
|
71
|
+
function extractInboundMessages(value) {
|
|
72
|
+
return value?.messages ?? [];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Build a minimal vCard from Meta's structured contact payload.
|
|
76
|
+
*
|
|
77
|
+
* The Cloud API does NOT hand over a vCard string (Baileys does — see
|
|
78
|
+
* manager.ts's contactMessage branch, which uses `contactMessage.vcard`
|
|
79
|
+
* verbatim), it hands over decomposed JSON. Synthesizing a 3.0 vCard here
|
|
80
|
+
* means BOTH WhatsApp channels put the same kind of value in the same
|
|
81
|
+
* `meta.vcard` key, so the agent never needs channel-specific handling.
|
|
82
|
+
* Returns undefined when there is neither a name nor a phone to put in it.
|
|
83
|
+
*/
|
|
84
|
+
function synthesizeVCard(contact) {
|
|
85
|
+
const name = contact?.name?.formatted_name?.trim();
|
|
86
|
+
const phone = contact?.phones?.find((p) => p.phone)?.phone?.trim();
|
|
87
|
+
if (!name && !phone)
|
|
88
|
+
return undefined;
|
|
89
|
+
const lines = ['BEGIN:VCARD', 'VERSION:3.0'];
|
|
90
|
+
if (name)
|
|
91
|
+
lines.push(`FN:${name}`);
|
|
92
|
+
if (phone)
|
|
93
|
+
lines.push(`TEL:${phone}`);
|
|
94
|
+
lines.push('END:VCARD');
|
|
95
|
+
return lines.join('\n');
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Normalize an inbound Cloud API message into the gateway's {content, meta}
|
|
99
|
+
* intake shape. Returns null when `from` is missing/empty (no reply target).
|
|
100
|
+
* `content` is the text body for `type: 'text'`, the caption (possibly
|
|
101
|
+
* empty) for `type: 'image'`/`'document'`, or a short human summary for
|
|
102
|
+
* `type: 'location'`, or the selected option's title for `type: 'interactive'`
|
|
103
|
+
* (a button tap / list pick) — remaining types (audio, video, ...) are still
|
|
104
|
+
* out of scope and forward with empty content rather than being dropped, same
|
|
105
|
+
* posture as Slack's "no text → empty content, not null".
|
|
106
|
+
*
|
|
107
|
+
* Stays synchronous and pure: an attached image/document/sticker's bytes are
|
|
108
|
+
* fetched by the async handler AFTER this returns, which sets
|
|
109
|
+
* `meta.image_path`/`meta.document_path`/`meta.sticker_path` on the object
|
|
110
|
+
* built here.
|
|
111
|
+
*/
|
|
112
|
+
function normalizeWhatsAppCloudMessage(msg, resolved) {
|
|
113
|
+
const r = resolved ?? (0, whatsapp_cloud_access_1.resolveWhatsAppCloudSource)(msg.from);
|
|
114
|
+
if (r.kind === 'other' || !r.conversationId)
|
|
115
|
+
return null;
|
|
116
|
+
const meta = {
|
|
117
|
+
source: 'whatsapp_cloud',
|
|
118
|
+
chat_id: r.conversationId,
|
|
119
|
+
user_id: r.senderId,
|
|
120
|
+
user: r.senderId,
|
|
121
|
+
message_id: msg.id ?? '',
|
|
122
|
+
};
|
|
123
|
+
// Reply context. Meta's webhook carries ONLY the quoted message's id — the
|
|
124
|
+
// quoted text and its sender are NOT inlined (a real Cloud API limitation,
|
|
125
|
+
// not a gap here; retrieving them would need our own store of previously
|
|
126
|
+
// seen messages). So `replied_user`/`replied_text` are deliberately left
|
|
127
|
+
// unset for this channel, and buildChannelXml emits `<replied
|
|
128
|
+
// message_id=… user="">` with an empty body. Baileys, by contrast, does
|
|
129
|
+
// inline the quote and populates all three.
|
|
130
|
+
if (msg.context?.id)
|
|
131
|
+
meta.replied_message_id = msg.context.id;
|
|
132
|
+
let content = '';
|
|
133
|
+
if (msg.type === 'text')
|
|
134
|
+
content = msg.text?.body ?? '';
|
|
135
|
+
else if (msg.type === 'image')
|
|
136
|
+
content = msg.image?.caption ?? '';
|
|
137
|
+
else if (msg.type === 'document')
|
|
138
|
+
content = msg.document?.caption ?? '';
|
|
139
|
+
else if (msg.type === 'location' && msg.location) {
|
|
140
|
+
const { latitude, longitude, name, address } = msg.location;
|
|
141
|
+
if (typeof latitude === 'number')
|
|
142
|
+
meta.location_lat = String(latitude);
|
|
143
|
+
if (typeof longitude === 'number')
|
|
144
|
+
meta.location_lng = String(longitude);
|
|
145
|
+
// A pinned place carries a name/address; a raw dropped pin carries only
|
|
146
|
+
// coordinates, which already ride along in meta — hence the generic
|
|
147
|
+
// fallback rather than repeating the numbers in the text.
|
|
148
|
+
content = [name, address].filter(Boolean).join(', ') || '[Location shared]';
|
|
149
|
+
}
|
|
150
|
+
else if (msg.type === 'contacts') {
|
|
151
|
+
const vcard = synthesizeVCard(msg.contacts?.[0]);
|
|
152
|
+
if (vcard)
|
|
153
|
+
meta.vcard = vcard;
|
|
154
|
+
}
|
|
155
|
+
else if (msg.type === 'interactive') {
|
|
156
|
+
// A button tap / list pick (Phase 3). `content` becomes the DISPLAY TITLE
|
|
157
|
+
// of whatever the user selected, so the turn reads to the agent exactly as
|
|
158
|
+
// if they had typed that label — no interactive-aware agent-side handling
|
|
159
|
+
// is needed for the common case. The machine-readable `id` rides along in
|
|
160
|
+
// meta.interactive_id for agents whose logic branches on the id instead
|
|
161
|
+
// (ids are stable; titles are what the user reads and may be localized).
|
|
162
|
+
const selected = msg.interactive?.button_reply ?? msg.interactive?.list_reply;
|
|
163
|
+
if (selected) {
|
|
164
|
+
content = selected.title ?? '';
|
|
165
|
+
if (selected.id)
|
|
166
|
+
meta.interactive_id = selected.id;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return { content, meta };
|
|
170
|
+
}
|
|
171
|
+
/** Verify `X-Hub-Signature-256` (HMAC-SHA256 of the raw body — no timestamp component). */
|
|
172
|
+
function verifyMetaSignature(rawBody, appSecret, sigHeader) {
|
|
173
|
+
if (!appSecret || !sigHeader)
|
|
174
|
+
return false;
|
|
175
|
+
const prefix = 'sha256=';
|
|
176
|
+
if (!sigHeader.startsWith(prefix))
|
|
177
|
+
return false;
|
|
178
|
+
const expected = `${prefix}${(0, crypto_1.createHmac)('sha256', appSecret).update(rawBody).digest('hex')}`;
|
|
179
|
+
const expectedBuf = Buffer.from(expected, 'utf8');
|
|
180
|
+
const actualBuf = Buffer.from(sigHeader, 'utf8');
|
|
181
|
+
if (expectedBuf.length !== actualBuf.length)
|
|
182
|
+
return false;
|
|
183
|
+
return (0, crypto_1.timingSafeEqual)(expectedBuf, actualBuf);
|
|
184
|
+
}
|
|
185
|
+
/** Constant-time string equality — same posture as verifyMetaSignature above. */
|
|
186
|
+
function safeStringEqual(a, b) {
|
|
187
|
+
const aBuf = Buffer.from(a, 'utf8');
|
|
188
|
+
const bBuf = Buffer.from(b, 'utf8');
|
|
189
|
+
if (aBuf.length !== bBuf.length)
|
|
190
|
+
return false;
|
|
191
|
+
return (0, crypto_1.timingSafeEqual)(aBuf, bBuf);
|
|
192
|
+
}
|
|
193
|
+
/** Find the agent that has WhatsApp Cloud configured (mirrors resolveSlackAgent). */
|
|
194
|
+
function resolveWhatsAppCloudAgent(agents, agentId) {
|
|
195
|
+
if (agentId) {
|
|
196
|
+
const r = agents.get(agentId);
|
|
197
|
+
return r && r.getAgentConfig().whatsapp_cloud?.appSecret ? r : null;
|
|
198
|
+
}
|
|
199
|
+
for (const runner of agents.values()) {
|
|
200
|
+
if (runner.getAgentConfig().whatsapp_cloud?.appSecret)
|
|
201
|
+
return runner;
|
|
202
|
+
}
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* One-time pairing-code message — same visual-match-code contract as
|
|
207
|
+
* Slack/LINE's pairingMessage. DM-only (no "in this channel/group" phrasing
|
|
208
|
+
* needed — there is no group tier on this channel).
|
|
209
|
+
*/
|
|
210
|
+
function pairingMessage(code) {
|
|
211
|
+
return (`รหัสจับคู่ (pairing code) ของคุณคือ: ${code}\n` +
|
|
212
|
+
`กรุณาแจ้งรหัสนี้ให้แอดมินเพื่อขอเปิดใช้งานบอท (ไม่ต้องพิมพ์รหัสตอบกลับ)\n\n` +
|
|
213
|
+
`Your pairing code: ${code}\n` +
|
|
214
|
+
`Share this code with the admin to get access. (No need to reply with it.)`);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Fetch an inbound media attachment's bytes and return them + the reported
|
|
218
|
+
* mime type. Two-step, per the Cloud API's media contract:
|
|
219
|
+
* 1. `GET /{media-id}?access_token=...` → `{url, mime_type}` — the
|
|
220
|
+
* returned `url` is short-lived and NOT itself bearer-protected the way
|
|
221
|
+
* `url_private` is on Slack, but IS host-restricted to Meta's own CDN.
|
|
222
|
+
* 2. `GET <url>` with the SAME bearer token.
|
|
223
|
+
*
|
|
224
|
+
* Step 2's host is validated against MEDIA_HOST_ALLOWLIST BEFORE the token is
|
|
225
|
+
* attached — defense in depth against a future payload-shape change or bug
|
|
226
|
+
* upstream of this call handing us an attacker-chosen `url` (mirrors
|
|
227
|
+
* downloadSlackImage's identical host-check-before-sending-token structure).
|
|
228
|
+
* Enforces MAX_MEDIA_BYTES against both the declared content-length and the
|
|
229
|
+
* actual streamed byte count. Returns null when the metadata step yields no
|
|
230
|
+
* `url`; throws on HTTP failure, an untrusted host, or an over-cap size — the
|
|
231
|
+
* caller logs and forwards the turn regardless.
|
|
232
|
+
*/
|
|
233
|
+
async function downloadWhatsAppCloudMedia(accessToken, mediaId, apiBase) {
|
|
234
|
+
const metaRes = await fetch(`${apiBase}/${mediaId}?access_token=${encodeURIComponent(accessToken)}`);
|
|
235
|
+
if (!metaRes.ok)
|
|
236
|
+
throw new Error(`HTTP ${metaRes.status} fetching media metadata`);
|
|
237
|
+
const metaJson = (await metaRes.json());
|
|
238
|
+
if (!metaJson.url)
|
|
239
|
+
return null;
|
|
240
|
+
let host;
|
|
241
|
+
try {
|
|
242
|
+
host = new URL(metaJson.url).hostname;
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
throw new Error('invalid media url');
|
|
246
|
+
}
|
|
247
|
+
if (!MEDIA_HOST_ALLOWLIST.some((re) => re.test(host))) {
|
|
248
|
+
throw new Error(`refusing to send bearer token to untrusted media host: ${host}`);
|
|
249
|
+
}
|
|
250
|
+
const res = await fetch(metaJson.url, { headers: { Authorization: `Bearer ${accessToken}` } });
|
|
251
|
+
if (!res.ok)
|
|
252
|
+
throw new Error(`HTTP ${res.status} downloading media`);
|
|
253
|
+
const declared = Number(res.headers.get('content-length') ?? '');
|
|
254
|
+
if (Number.isFinite(declared) && declared > MAX_MEDIA_BYTES) {
|
|
255
|
+
throw new Error(`media exceeds ${MAX_MEDIA_BYTES} byte cap`);
|
|
256
|
+
}
|
|
257
|
+
let buf;
|
|
258
|
+
if (res.body) {
|
|
259
|
+
const chunks = [];
|
|
260
|
+
let total = 0;
|
|
261
|
+
for await (const chunk of res.body) {
|
|
262
|
+
total += chunk.byteLength;
|
|
263
|
+
if (total > MAX_MEDIA_BYTES)
|
|
264
|
+
throw new Error(`media exceeds ${MAX_MEDIA_BYTES} byte cap`);
|
|
265
|
+
chunks.push(Buffer.from(chunk));
|
|
266
|
+
}
|
|
267
|
+
buf = Buffer.concat(chunks);
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
buf = Buffer.from(await res.arrayBuffer());
|
|
271
|
+
if (buf.length > MAX_MEDIA_BYTES)
|
|
272
|
+
throw new Error(`media exceeds ${MAX_MEDIA_BYTES} byte cap`);
|
|
273
|
+
}
|
|
274
|
+
return { buf, mimeType: metaJson.mime_type ?? 'application/octet-stream' };
|
|
275
|
+
}
|
|
276
|
+
function writeTempImage(buf, messageId) {
|
|
277
|
+
// messageId is Meta-webhook-supplied and not guaranteed to match wamid.*'s
|
|
278
|
+
// format — sanitize before it reaches a filename (see sanitizeFilenameId).
|
|
279
|
+
const suffix = `${(0, image_sniff_1.sanitizeFilenameId)(messageId)}-${Date.now()}`;
|
|
280
|
+
const dest = path.join(os.tmpdir(), `whatsapp-cloud-img-${suffix}.${(0, image_sniff_1.sniffImageExt)(buf)}`);
|
|
281
|
+
fs.writeFileSync(dest, buf, { mode: 0o600 });
|
|
282
|
+
return dest;
|
|
283
|
+
}
|
|
284
|
+
function writeTempDocument(buf, mimeType, filename, messageId) {
|
|
285
|
+
const suffix = `${(0, image_sniff_1.sanitizeFilenameId)(messageId)}-${Date.now()}`;
|
|
286
|
+
const extFromName = filename ? path.extname(filename) : '';
|
|
287
|
+
const ext = extFromName || (mimeType === 'application/pdf' ? '.pdf' : '');
|
|
288
|
+
const dest = path.join(os.tmpdir(), `whatsapp-cloud-doc-${suffix}${ext}`);
|
|
289
|
+
fs.writeFileSync(dest, buf, { mode: 0o600 });
|
|
290
|
+
return dest;
|
|
291
|
+
}
|
|
292
|
+
function createWhatsAppCloudWebhookHandler(agents, logDir, opts = {}) {
|
|
293
|
+
const logger = (0, logger_1.createLogger)('whatsapp-cloud-webhook', logDir);
|
|
294
|
+
const apiBase = opts.apiBase ?? WHATSAPP_CLOUD_API_BASE;
|
|
295
|
+
const seenMessageIds = new Map();
|
|
296
|
+
const isDuplicateMessage = (id) => {
|
|
297
|
+
const now = Date.now();
|
|
298
|
+
for (const [mid, ts] of seenMessageIds) {
|
|
299
|
+
if (now - ts > WHATSAPP_CLOUD_MESSAGE_ID_TTL_MS)
|
|
300
|
+
seenMessageIds.delete(mid);
|
|
301
|
+
}
|
|
302
|
+
if (seenMessageIds.has(id))
|
|
303
|
+
return true;
|
|
304
|
+
seenMessageIds.set(id, now);
|
|
305
|
+
return false;
|
|
306
|
+
};
|
|
307
|
+
// GET handshake (opposite of Slack's signed-POST url_verification): Meta
|
|
308
|
+
// calls this once when the webhook subscription is configured, comparing
|
|
309
|
+
// our echoed `hub.challenge` against what it sent. Must respond with the
|
|
310
|
+
// RAW challenge string, not JSON-wrapped, on match.
|
|
311
|
+
const verify = (req, res) => {
|
|
312
|
+
const agentId = req.params.agentId;
|
|
313
|
+
const runner = resolveWhatsAppCloudAgent(agents, agentId);
|
|
314
|
+
const mode = req.query['hub.mode'];
|
|
315
|
+
const token = req.query['hub.verify_token'];
|
|
316
|
+
const challenge = req.query['hub.challenge'];
|
|
317
|
+
const expected = runner?.getAgentConfig().whatsapp_cloud?.verifyToken;
|
|
318
|
+
if (mode === 'subscribe' && expected && typeof token === 'string' && safeStringEqual(token, expected)) {
|
|
319
|
+
res.status(200).type('text/plain').send(String(challenge ?? ''));
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
logger.warn('WhatsApp Cloud webhook: verify handshake failed', { agentId, mode });
|
|
323
|
+
res.status(403).json({ error: 'verification failed' });
|
|
324
|
+
};
|
|
325
|
+
const handlePost = async (req, res) => {
|
|
326
|
+
const agentId = req.params.agentId;
|
|
327
|
+
const runner = resolveWhatsAppCloudAgent(agents, agentId);
|
|
328
|
+
if (!runner) {
|
|
329
|
+
res.status(404).json({ error: 'no WhatsApp Cloud-enabled agent' });
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
const cfg = runner.getAgentConfig().whatsapp_cloud;
|
|
333
|
+
const secret = cfg?.appSecret ?? '';
|
|
334
|
+
const buf = Buffer.isBuffer(req.body) ? req.body : Buffer.from('');
|
|
335
|
+
if (!verifyMetaSignature(buf, secret, req.header('x-hub-signature-256'))) {
|
|
336
|
+
logger.warn('WhatsApp Cloud webhook rejected: bad signature', { agentId: runner.getAgentConfig().id });
|
|
337
|
+
res.status(401).json({ error: 'invalid signature' });
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
let payload;
|
|
341
|
+
try {
|
|
342
|
+
payload = JSON.parse(buf.toString('utf8'));
|
|
343
|
+
}
|
|
344
|
+
catch (err) {
|
|
345
|
+
logger.warn('WhatsApp Cloud webhook: bad JSON', { error: err.message });
|
|
346
|
+
res.status(400).json({ error: 'bad JSON' });
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
// Ack immediately (Meta retries if our ack is slow/dropped) — process after.
|
|
350
|
+
res.status(200).json({ ok: true });
|
|
351
|
+
const deniedAgentId = runner.getAgentConfig().id;
|
|
352
|
+
for (const entry of payload.entry ?? []) {
|
|
353
|
+
for (const change of entry.changes ?? []) {
|
|
354
|
+
const value = change.value;
|
|
355
|
+
const messages = extractInboundMessages(value);
|
|
356
|
+
if (messages.length === 0)
|
|
357
|
+
continue; // status-only batch, or no messages field at all
|
|
358
|
+
// contacts[] carries profile.name synchronously, keyed by wa_id — used
|
|
359
|
+
// for the pending-knock display name with no extra API call needed
|
|
360
|
+
// (unlike Slack's getUserDisplayName round-trip).
|
|
361
|
+
const nameByWaId = new Map();
|
|
362
|
+
for (const c of value?.contacts ?? []) {
|
|
363
|
+
if (c.wa_id && c.profile?.name)
|
|
364
|
+
nameByWaId.set(c.wa_id, c.profile.name);
|
|
365
|
+
}
|
|
366
|
+
for (const msg of messages) {
|
|
367
|
+
if (msg.id && isDuplicateMessage(msg.id)) {
|
|
368
|
+
logger.debug('WhatsApp Cloud webhook: duplicate message id (Meta retry), skipping', { id: msg.id });
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
const resolved = (0, whatsapp_cloud_access_1.resolveWhatsAppCloudSource)(msg.from);
|
|
372
|
+
if (resolved.kind === 'other' || !resolved.conversationId)
|
|
373
|
+
continue;
|
|
374
|
+
if (!(0, whatsapp_cloud_access_1.isResolvedWhatsAppCloudSourceAllowed)(cfg, resolved)) {
|
|
375
|
+
logger.debug('WhatsApp Cloud webhook: source not allowed', {
|
|
376
|
+
agentId: deniedAgentId,
|
|
377
|
+
policy: cfg?.dmPolicy ?? '(closed)',
|
|
378
|
+
conversationId: resolved.conversationId,
|
|
379
|
+
});
|
|
380
|
+
const knockId = resolved.senderId;
|
|
381
|
+
if (knockId) {
|
|
382
|
+
const isPairing = cfg?.pairing !== false && cfg?.dmPolicy !== 'open' && cfg?.dmPolicy !== 'disabled';
|
|
383
|
+
const prev = (0, pending_senders_1.getPendingSender)('whatsapp_cloud', deniedAgentId, knockId);
|
|
384
|
+
const code = prev?.code ?? (isPairing ? (0, pending_senders_1.generatePairingCode)() : undefined);
|
|
385
|
+
const displayName = nameByWaId.get(knockId);
|
|
386
|
+
const wasNew = (0, pending_senders_1.recordDeniedSender)('whatsapp_cloud', deniedAgentId, knockId, displayName, Date.now(), code);
|
|
387
|
+
// Send the pairing code exactly once — on first contact only.
|
|
388
|
+
if (isPairing && wasNew && code && cfg?.accessToken && cfg?.phoneNumberId) {
|
|
389
|
+
const client = new whatsapp_cloud_client_1.WhatsAppCloudClient({
|
|
390
|
+
accessToken: cfg.accessToken,
|
|
391
|
+
phoneNumberId: cfg.phoneNumberId,
|
|
392
|
+
logDir,
|
|
393
|
+
apiBase: opts.apiBase,
|
|
394
|
+
});
|
|
395
|
+
void client
|
|
396
|
+
.sendText(knockId, pairingMessage(code))
|
|
397
|
+
.catch((err) => logger.debug('WhatsApp Cloud pairing code reply failed', { error: err.message }));
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
const norm = normalizeWhatsAppCloudMessage(msg, resolved);
|
|
403
|
+
if (!norm)
|
|
404
|
+
continue;
|
|
405
|
+
// Receipt signals (Phase 2), both strictly best-effort and both
|
|
406
|
+
// gated on config — mirrors slack-webhook-router.ts's
|
|
407
|
+
// `void client.addReaction(...).catch(() => {})` call site: fired
|
|
408
|
+
// right after the access gate, never awaited, never able to fail
|
|
409
|
+
// the turn. The ack reaction is cleared by the
|
|
410
|
+
// `whatsapp_cloud_reply` MCP tool once the agent's reply lands.
|
|
411
|
+
if (msg.id && cfg?.accessToken && cfg?.phoneNumberId) {
|
|
412
|
+
const receiptClient = new whatsapp_cloud_client_1.WhatsAppCloudClient({
|
|
413
|
+
accessToken: cfg.accessToken,
|
|
414
|
+
phoneNumberId: cfg.phoneNumberId,
|
|
415
|
+
logDir,
|
|
416
|
+
apiBase: opts.apiBase,
|
|
417
|
+
});
|
|
418
|
+
if (cfg.sendReadReceipts !== false) {
|
|
419
|
+
void receiptClient.markAsRead(msg.id).catch(() => { });
|
|
420
|
+
}
|
|
421
|
+
if ((cfg.reactionLevel ?? 'ack') === 'ack') {
|
|
422
|
+
void receiptClient.sendReaction(resolved.conversationId, msg.id).catch(() => { });
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
// Inbound media (image AND document, both eager at receipt time):
|
|
426
|
+
// fetch the bytes with the access token and hand the agent an
|
|
427
|
+
// absolute path. Images use the existing meta.image_path contract;
|
|
428
|
+
// documents use the new meta.document_path key, but ONLY when the
|
|
429
|
+
// mime type passes MediaStore.isAllowedMime() (PDF only in
|
|
430
|
+
// practice today) — an unsupported document type is logged and
|
|
431
|
+
// skipped, but the turn still forwards with whatever caption it has.
|
|
432
|
+
//
|
|
433
|
+
// Stickers (Phase 2) ride the SAME download path — they are
|
|
434
|
+
// `image/webp` media, which MediaStore.isAllowedMime already
|
|
435
|
+
// permits (`image/` prefix) and sniffImageExt already recognizes
|
|
436
|
+
// (RIFF/WEBP magic bytes) — but land on their own
|
|
437
|
+
// meta.sticker_path key, never image_path, so the agent can tell a
|
|
438
|
+
// sticker apart from a photo.
|
|
439
|
+
if (cfg?.accessToken && (msg.type === 'image' || msg.type === 'document' || msg.type === 'sticker')) {
|
|
440
|
+
const mediaObj = msg.type === 'image' ? msg.image : msg.type === 'sticker' ? msg.sticker : msg.document;
|
|
441
|
+
if (mediaObj?.id) {
|
|
442
|
+
try {
|
|
443
|
+
const downloaded = await downloadWhatsAppCloudMedia(cfg.accessToken, mediaObj.id, apiBase);
|
|
444
|
+
if (downloaded) {
|
|
445
|
+
if (msg.type === 'image') {
|
|
446
|
+
norm.meta.image_path = writeTempImage(downloaded.buf, msg.id);
|
|
447
|
+
}
|
|
448
|
+
else if (msg.type === 'sticker') {
|
|
449
|
+
if (media_store_1.MediaStore.isAllowedMime(downloaded.mimeType)) {
|
|
450
|
+
norm.meta.sticker_path = writeTempImage(downloaded.buf, msg.id);
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
logger.warn('WhatsApp Cloud webhook: sticker mime type not allowed, skipping download', {
|
|
454
|
+
mimeType: downloaded.mimeType,
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
else if (media_store_1.MediaStore.isAllowedMime(downloaded.mimeType)) {
|
|
459
|
+
norm.meta.document_path = writeTempDocument(downloaded.buf, downloaded.mimeType, mediaObj.filename, msg.id);
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
logger.warn('WhatsApp Cloud webhook: document mime type not allowed, skipping download', {
|
|
463
|
+
mimeType: downloaded.mimeType,
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
catch (err) {
|
|
469
|
+
logger.warn('WhatsApp Cloud webhook: media download failed', {
|
|
470
|
+
mediaId: mediaObj.id,
|
|
471
|
+
error: err.message,
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
try {
|
|
477
|
+
await fetch(`http://127.0.0.1:${runner.getCallbackPort()}/channel`, {
|
|
478
|
+
method: 'POST',
|
|
479
|
+
headers: { 'Content-Type': 'application/json' },
|
|
480
|
+
body: JSON.stringify(norm),
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
catch (err) {
|
|
484
|
+
logger.error('WhatsApp Cloud webhook: failed to forward to callback', {
|
|
485
|
+
error: err.message,
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
return { verify, handlePost };
|
|
493
|
+
}
|
|
494
|
+
//# sourceMappingURL=whatsapp-cloud-webhook-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp-cloud-webhook-router.js","sourceRoot":"","sources":["../../src/api/whatsapp-cloud-webhook-router.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAIjD,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,EAAE,EAAE,MAAM;CAIvB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,MAAM;CAK5B;AAuED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACjD;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,OAAO,EAAE,MAAM,GACd,IAAI,CAQN;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,aAAa,CA6MzF"}
|
package/dist/config/loader.js
CHANGED
|
@@ -40,6 +40,7 @@ const fs = __importStar(require("fs"));
|
|
|
40
40
|
const os = __importStar(require("os"));
|
|
41
41
|
const path = __importStar(require("path"));
|
|
42
42
|
const public_url_1 = require("./public-url");
|
|
43
|
+
const whatsapp_accounts_1 = require("./whatsapp-accounts");
|
|
43
44
|
class ConfigValidationError extends Error {
|
|
44
45
|
constructor(message) {
|
|
45
46
|
super(message);
|
|
@@ -230,6 +231,12 @@ function loadConfig(configPath, options) {
|
|
|
230
231
|
skipAgent(String(agent.id || `index ${i}`), error);
|
|
231
232
|
continue;
|
|
232
233
|
}
|
|
234
|
+
// Normalize a legacy flat `whatsapp` block into the multi-account
|
|
235
|
+
// `{ accounts: [...] }` shape BEFORE anything downstream reads it, so
|
|
236
|
+
// runtime is always correct even when the write-back at boot
|
|
237
|
+
// (upgradeWhatsAppAccountsFile) couldn't persist — e.g. a read-only
|
|
238
|
+
// config volume. Idempotent: an already-upgraded agent is untouched.
|
|
239
|
+
(0, whatsapp_accounts_1.upgradeAgentWhatsAppAccounts)(agent);
|
|
233
240
|
validAgents.push(agent);
|
|
234
241
|
}
|
|
235
242
|
// Check for duplicate IDs among valid agents
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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"}
|