@openclaw/crabline 0.1.17 → 0.1.19

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.
Files changed (33) hide show
  1. package/README.md +8 -0
  2. package/dist/src/openclaw/private-file.js +71 -24
  3. package/dist/src/openclaw/private-file.js.map +1 -1
  4. package/dist/src/platform/process-owned-lock.d.ts +5 -2
  5. package/dist/src/platform/process-owned-lock.js +20 -10
  6. package/dist/src/platform/process-owned-lock.js.map +1 -1
  7. package/dist/src/servers/discord.js +25 -35
  8. package/dist/src/servers/discord.js.map +1 -1
  9. package/dist/src/servers/http.d.ts +3 -0
  10. package/dist/src/servers/http.js +15 -0
  11. package/dist/src/servers/http.js.map +1 -1
  12. package/dist/src/servers/matrix.js +8 -8
  13. package/dist/src/servers/matrix.js.map +1 -1
  14. package/dist/src/servers/mattermost.js +7 -10
  15. package/dist/src/servers/mattermost.js.map +1 -1
  16. package/dist/src/servers/recorder.d.ts +16 -6
  17. package/dist/src/servers/recorder.js +52 -12
  18. package/dist/src/servers/recorder.js.map +1 -1
  19. package/dist/src/servers/signal.js +8 -8
  20. package/dist/src/servers/signal.js.map +1 -1
  21. package/dist/src/servers/slack.js +8 -8
  22. package/dist/src/servers/slack.js.map +1 -1
  23. package/dist/src/servers/telegram.d.ts +2 -2
  24. package/dist/src/servers/telegram.js +8 -8
  25. package/dist/src/servers/telegram.js.map +1 -1
  26. package/dist/src/servers/whatsapp-baileys-websocket.js +4 -3
  27. package/dist/src/servers/whatsapp-baileys-websocket.js.map +1 -1
  28. package/dist/src/servers/whatsapp.js +13 -18
  29. package/dist/src/servers/whatsapp.js.map +1 -1
  30. package/dist/src/servers/zalo.js +8 -7
  31. package/dist/src/servers/zalo.js.map +1 -1
  32. package/docs/channel-setup.md +14 -1
  33. package/package.json +11 -11
@@ -1,7 +1,7 @@
1
1
  import { createCipheriv, createHash, createHmac, hkdfSync, randomBytes } from "node:crypto";
2
2
  import path from "node:path";
3
- import { adminAuthError, constantTimeTokenEqual, drainRequestBody, hasAdminToken, InvalidJsonBodyError, isJsonObject, isLoopbackHost, jsonResponse, parseUnknownRequestBody, queryRecord, readTrimmedString, RequestBodyTooLargeError, startHttpJsonServer, } from "./http.js";
4
- import { recordServerEvent, ServerRecorderCommittedError, } from "./recorder.js";
3
+ import { adminAuthError, createServerClose, constantTimeTokenEqual, drainRequestBody, hasAdminToken, InvalidJsonBodyError, isJsonObject, isLoopbackHost, jsonResponse, parseUnknownRequestBody, queryRecord, readTrimmedString, RequestBodyTooLargeError, startHttpJsonServer, } from "./http.js";
4
+ import { createServerRecorder, ServerRecorderCommittedError, } from "./recorder.js";
5
5
  import { attachWhatsAppBaileysWebSocketServer, resolveMaxPendingWhatsAppInboundMessages, } from "./whatsapp-baileys-websocket.js";
6
6
  import { canonicalizeWhatsAppChatJid, canonicalizeWhatsAppUserCorrelationJid, canonicalizeWhatsAppUserJid, isWhatsAppGroupJid, } from "./whatsapp-jid.js";
7
7
  const WHATSAPP_CLOUD_RECIPIENT_RE = /^\d{7,15}$/u;
@@ -51,7 +51,7 @@ function graphAuthError() {
51
51
  });
52
52
  }
53
53
  async function appendEvent(state, event) {
54
- await recordServerEvent({ event, onEvent: state.onEvent, recorderPath: state.recorderPath });
54
+ await state.recorder.record(event);
55
55
  }
56
56
  function requireWhatsAppChatJid(value) {
57
57
  const stringValue = readTrimmedString(value);
@@ -660,6 +660,7 @@ export async function startWhatsAppServer(params = {}) {
660
660
  if (!selfJid) {
661
661
  throw new Error("WhatsApp selfJid must be a WhatsApp user JID.");
662
662
  }
663
+ const recorderPath = params.recorderPath ?? path.resolve(".crabline", "servers", "whatsapp.jsonl");
663
664
  const state = {
664
665
  accessToken: params.accessToken ?? createDefaultAccessToken(),
665
666
  adminToken: params.adminToken ?? randomBytes(24).toString("hex"),
@@ -673,9 +674,9 @@ export async function startWhatsAppServer(params = {}) {
673
674
  pendingMessageIds: new Set(),
674
675
  recentMessageIds: new Map(),
675
676
  nextMessageId: 1n,
676
- onEvent: params.onEvent,
677
+ recorder: createServerRecorder({ recorderPath, onEvent: params.onEvent }),
677
678
  phoneNumberId,
678
- recorderPath: params.recorderPath ?? path.resolve(".crabline", "servers", "whatsapp.jsonl"),
679
+ recorderPath,
679
680
  selfJid,
680
681
  };
681
682
  const httpServer = await startHttpJsonServer({
@@ -730,21 +731,15 @@ export async function startWhatsAppServer(params = {}) {
730
731
  }
731
732
  state.prepareInboundMessage = (message) => baileysWebSocketServer.prepareInboundMessage(message);
732
733
  return {
733
- async close() {
734
- const results = await Promise.allSettled([
735
- baileysWebSocketServer.close(),
736
- httpServer.close(),
737
- ]);
738
- const errors = results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
739
- state.mediaByPath.clear();
740
- state.mediaBytes = 0;
741
- if (errors.length === 1) {
742
- throw errors[0];
734
+ close: createServerClose(state.recorder, async () => {
735
+ try {
736
+ await baileysWebSocketServer.close();
743
737
  }
744
- if (errors.length > 1) {
745
- throw new AggregateError(errors, "WhatsApp server shutdown failed.");
738
+ finally {
739
+ state.mediaByPath.clear();
740
+ state.mediaBytes = 0;
746
741
  }
747
- },
742
+ }, () => httpServer.close()),
748
743
  manifest: {
749
744
  accessToken: state.accessToken,
750
745
  adminToken: state.adminToken,
@@ -1 +1 @@
1
- {"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../../src/servers/whatsapp.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage } from \"node:http\";\nimport { createCipheriv, createHash, createHmac, hkdfSync, randomBytes } from \"node:crypto\";\nimport path from \"node:path\";\nimport {\n adminAuthError,\n constantTimeTokenEqual,\n drainRequestBody,\n hasAdminToken,\n InvalidJsonBodyError,\n isJsonObject,\n isLoopbackHost,\n jsonResponse,\n parseUnknownRequestBody,\n queryRecord,\n readTrimmedString,\n RequestBodyTooLargeError,\n startHttpJsonServer,\n type ServerRequestEvent,\n} from \"./http.js\";\nimport {\n recordServerEvent,\n ServerRecorderCommittedError,\n type ServerEventObserver,\n} from \"./recorder.js\";\nimport {\n attachWhatsAppBaileysWebSocketServer,\n resolveMaxPendingWhatsAppInboundMessages,\n type PreparedWhatsAppBaileysInboundDelivery,\n type WhatsAppBaileysInboundMessage,\n} from \"./whatsapp-baileys-websocket.js\";\nimport {\n canonicalizeWhatsAppChatJid,\n canonicalizeWhatsAppUserCorrelationJid,\n canonicalizeWhatsAppUserJid,\n isWhatsAppGroupJid,\n} from \"./whatsapp-jid.js\";\n\nconst WHATSAPP_CLOUD_RECIPIENT_RE = /^\\d{7,15}$/u;\nconst WHATSAPP_GRAPH_VERSION_RE = /^v\\d+\\.\\d+$/u;\nconst WHATSAPP_GENERATED_MESSAGE_ID_RE = /^wamid\\.FAKE(\\d{8,})$/u;\nconst DEFAULT_GRAPH_VERSION = \"v25.0\";\nconst MAX_WHATSAPP_READABLE_MESSAGE_IDS = 10_000;\nconst MAX_WHATSAPP_RECENT_MESSAGE_IDS = 10_000;\nconst MAX_WHATSAPP_MESSAGE_ID_BYTES = 128;\nconst MAX_WHATSAPP_TEXT_MESSAGE_CHARACTERS = 4_096;\nconst MAX_WHATSAPP_MEDIA_FIXTURES = 1_000;\nconst MAX_WHATSAPP_MEDIA_BYTES = 16 * 1024 * 1024;\nconst WHATSAPP_MEDIA_TTL_MS = 5 * 60 * 1_000;\nconst WHATSAPP_MEDIA_DOWNLOAD_GRACE_MS = 30 * 1_000;\n\nfunction createDefaultAccessToken(): string {\n return `EAA${randomBytes(24).toString(\"base64url\")}`;\n}\n\ntype WhatsAppServerState = {\n accessToken: string;\n adminToken: string;\n baseUrl: string;\n displayPhoneNumber: string;\n prepareInboundMessage(\n message: WhatsAppBaileysInboundMessage,\n ): PreparedWhatsAppBaileysInboundDelivery | undefined;\n graphVersion: string;\n inboundMessageIds: Set<string>;\n mediaByPath: Map<string, { content: Buffer; expiresAt: number; mimeType: string }>;\n mediaBytes: number;\n pendingMessageIds: Set<string>;\n recentMessageIds: Map<string, true>;\n nextMessageId: bigint;\n onEvent: ServerEventObserver | undefined;\n phoneNumberId: string;\n recorderPath: string;\n selfJid: string;\n};\n\nexport type WhatsAppBaileysMessage = WhatsAppBaileysInboundMessage;\n\nexport type WhatsAppServerManifest = {\n accessToken: string;\n adminToken: string;\n baseUrl: string;\n endpoints: {\n adminInboundUrl: string;\n apiRoot: string;\n baileysWebSocketUrl: string;\n messagesUrl: string;\n phoneNumberUrl: string;\n };\n env: {\n CLOUD_API_ACCESS_TOKEN: string;\n CLOUD_API_VERSION: string;\n WA_BASE_URL: string;\n WA_PHONE_NUMBER_ID: string;\n };\n graphVersion: string;\n phoneNumberId: string;\n provider: \"whatsapp\";\n recorderPath: string;\n selfJid: string;\n version: 1;\n};\n\nexport type StartedWhatsAppServer = {\n close(): Promise<void>;\n manifest: WhatsAppServerManifest;\n};\n\nexport type StartWhatsAppServerParams = {\n accessToken?: string | undefined;\n adminToken?: string | undefined;\n displayPhoneNumber?: string | undefined;\n graphVersion?: string | undefined;\n host?: string | undefined;\n maxPendingInboundMessages?: number | undefined;\n messageAcceptanceTimeoutMs?: number | undefined;\n onEvent?: ServerEventObserver | undefined;\n phoneNumberId?: string | undefined;\n port?: number | undefined;\n recorderPath?: string | undefined;\n selfJid?: string | undefined;\n};\n\ntype WhatsAppAdminInboundResult = {\n mediaFixture?: WhatsAppMediaFixture | undefined;\n message?: WhatsAppBaileysMessage | undefined;\n messageIdReservation?: WhatsAppMessageIdReservation | undefined;\n response?: Response | undefined;\n webhook?: Record<string, unknown> | undefined;\n};\n\ntype WhatsAppRecorderEvent = ServerRequestEvent & {\n accepted?: boolean | undefined;\n message?: WhatsAppBaileysMessage | undefined;\n};\n\nfunction whatsappOk(value: Record<string, unknown> = {}): Response {\n return jsonResponse({ ok: true, ...value });\n}\n\nfunction graphError(params: {\n code?: number | undefined;\n details?: string | undefined;\n message: string;\n status?: number | undefined;\n type?: string | undefined;\n}): Response {\n return jsonResponse(\n {\n error: {\n code: params.code ?? 100,\n ...(params.details\n ? {\n error_data: {\n details: params.details,\n messaging_product: \"whatsapp\",\n },\n }\n : {}),\n fbtrace_id: \"A1B2C3D4E5F\",\n message: params.message,\n type: params.type ?? \"OAuthException\",\n },\n },\n params.status ?? 400,\n );\n}\n\nfunction graphParameterError(message: string, details?: string): Response {\n return graphError({ code: 100, details, message, status: 400 });\n}\n\nfunction graphAuthError(): Response {\n return graphError({\n code: 190,\n message: \"Invalid OAuth access token.\",\n status: 401,\n });\n}\n\nasync function appendEvent(state: WhatsAppServerState, event: WhatsAppRecorderEvent) {\n await recordServerEvent({ event, onEvent: state.onEvent, recorderPath: state.recorderPath });\n}\n\nfunction requireWhatsAppChatJid(value: unknown): string | Response {\n const stringValue = readTrimmedString(value);\n const canonical = stringValue ? canonicalizeWhatsAppChatJid(stringValue) : undefined;\n if (!canonical) {\n return graphParameterError(\n \"(#100) Invalid parameter: chatJid\",\n \"chatJid must be a WhatsApp user or group JID.\",\n );\n }\n return canonical;\n}\n\nfunction requireWhatsAppSenderJid(value: unknown): string | Response {\n const stringValue = readTrimmedString(value);\n const canonical = stringValue ? canonicalizeWhatsAppUserJid(stringValue) : undefined;\n if (!canonical) {\n return graphParameterError(\n \"(#100) Invalid parameter: senderJid\",\n \"senderJid must be a WhatsApp user JID.\",\n );\n }\n return canonical;\n}\n\nfunction requireCloudRecipient(value: unknown): string | Response {\n const recipient = readTrimmedString(value);\n if (!recipient || !WHATSAPP_CLOUD_RECIPIENT_RE.test(recipient)) {\n return graphParameterError(\n \"(#100) Invalid parameter: to\",\n \"to must be a WhatsApp phone number in international format without punctuation.\",\n );\n }\n return recipient;\n}\n\nfunction requireAuth(request: IncomingMessage, state: WhatsAppServerState): boolean {\n const authorization = request.headers.authorization;\n if (typeof authorization !== \"string\") {\n return false;\n }\n const match = /^Bearer +(.+)$/iu.exec(authorization.trimStart());\n const providedToken = match?.[1];\n return providedToken ? constantTimeTokenEqual(providedToken, state.accessToken) : false;\n}\n\ntype WhatsAppMessageIdReservation = {\n cancel(): void;\n commit(): void;\n id: string;\n};\n\n/** @internal */\nexport function isWhatsAppMessageIdInUse(\n state: {\n inboundMessageIds: ReadonlySet<string>;\n pendingMessageIds: ReadonlySet<string>;\n recentMessageIds: ReadonlyMap<string, true>;\n },\n id: string,\n): boolean {\n return (\n state.inboundMessageIds.has(id) ||\n state.pendingMessageIds.has(id) ||\n state.recentMessageIds.has(id)\n );\n}\n\nfunction reserveMessageId(\n state: WhatsAppServerState,\n requestedId?: string,\n): WhatsAppMessageIdReservation | Response {\n let id = requestedId;\n if (id) {\n if (Buffer.byteLength(id, \"utf8\") > MAX_WHATSAPP_MESSAGE_ID_BYTES) {\n return graphParameterError(\n \"(#100) Invalid parameter: messageId\",\n `messageId must not exceed ${MAX_WHATSAPP_MESSAGE_ID_BYTES} UTF-8 bytes.`,\n );\n }\n if (isWhatsAppMessageIdInUse(state, id)) {\n return graphParameterError(\n \"(#100) Invalid parameter: messageId\",\n \"messageId must be unique within this WhatsApp server.\",\n );\n }\n } else {\n do {\n id = `wamid.FAKE${String(state.nextMessageId++).padStart(8, \"0\")}`;\n } while (isWhatsAppMessageIdInUse(state, id));\n }\n state.pendingMessageIds.add(id);\n let settled = false;\n return {\n cancel() {\n if (!settled) {\n settled = true;\n state.pendingMessageIds.delete(id);\n }\n },\n commit() {\n if (settled) {\n return;\n }\n settled = true;\n state.pendingMessageIds.delete(id);\n state.recentMessageIds.delete(id);\n state.recentMessageIds.set(id, true);\n if (state.recentMessageIds.size > MAX_WHATSAPP_RECENT_MESSAGE_IDS) {\n const oldestId = state.recentMessageIds.keys().next().value;\n if (oldestId !== undefined) {\n state.recentMessageIds.delete(oldestId);\n }\n }\n const generatedSequence = WHATSAPP_GENERATED_MESSAGE_ID_RE.exec(id)?.[1];\n if (generatedSequence) {\n const sequence = BigInt(generatedSequence);\n if (sequence >= state.nextMessageId) {\n state.nextMessageId = sequence + 1n;\n }\n }\n },\n id,\n };\n}\n\nfunction waIdFromJid(jid: string): string {\n const correlationJid = canonicalizeWhatsAppUserCorrelationJid(jid);\n return correlationJid?.split(\"@\", 1)[0] ?? jid;\n}\n\nfunction directPeerIdentity(jid: string): string {\n return canonicalizeWhatsAppUserCorrelationJid(jid) ?? jid;\n}\n\nfunction requireMessagingProduct(body: Record<string, unknown>): Response | undefined {\n const messagingProduct = readTrimmedString(body.messaging_product);\n if (messagingProduct !== \"whatsapp\") {\n return graphParameterError(\n \"(#100) Invalid parameter: messaging_product\",\n 'messaging_product must be \"whatsapp\".',\n );\n }\n return undefined;\n}\n\nfunction readTextMessageBody(body: Record<string, unknown>): string | Response {\n const type = readTrimmedString(body.type);\n if (!type) {\n return graphParameterError(\n \"(#100) Missing required parameter: type\",\n 'A WhatsApp text send requires type to be \"text\".',\n );\n }\n if (type !== \"text\") {\n return graphParameterError(\n \"(#100) Unsupported message type\",\n \"This test API currently supports WhatsApp text message sends.\",\n );\n }\n const textPayload = body.text;\n const text =\n textPayload && typeof textPayload === \"object\"\n ? readMessageText((textPayload as Record<string, unknown>).body)\n : undefined;\n if (text === undefined) {\n return graphParameterError(\n \"(#100) Missing required parameter: text.body\",\n \"A WhatsApp text send requires text.body.\",\n );\n }\n if ([...text].length > MAX_WHATSAPP_TEXT_MESSAGE_CHARACTERS) {\n return graphParameterError(\n \"(#100) Invalid parameter: text.body\",\n `text.body must not exceed ${MAX_WHATSAPP_TEXT_MESSAGE_CHARACTERS} characters.`,\n );\n }\n return text;\n}\n\nfunction createWhatsAppMessage(params: {\n fromMe: boolean;\n id: string;\n pushName?: string | undefined;\n remoteJid: string;\n senderJid?: string | undefined;\n text: string;\n}) {\n return {\n key: {\n fromMe: params.fromMe,\n id: params.id,\n ...(params.senderJid ? { participant: params.senderJid } : {}),\n remoteJid: params.remoteJid,\n },\n message: {\n conversation: params.text,\n },\n messageTimestamp: Math.floor(Date.now() / 1000),\n pushName: params.pushName ?? (params.fromMe ? \"Test Bot\" : \"Test User\"),\n };\n}\n\ntype WhatsAppAdminAudio = {\n content: Buffer;\n mimeType: string;\n ptt: boolean;\n};\n\ntype WhatsAppMediaFixture = {\n content: Buffer;\n mimeType: string;\n path: string;\n};\n\nfunction readAdminAudio(value: unknown): WhatsAppAdminAudio | Response | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (!isJsonObject(value)) {\n return graphParameterError(\n \"(#100) Invalid parameter: audio\",\n \"audio must be an object containing inline base64 content and an audio MIME type.\",\n );\n }\n const contentBase64 = typeof value.contentBase64 === \"string\" ? value.contentBase64 : undefined;\n if (\n !contentBase64 ||\n !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u.test(contentBase64)\n ) {\n return graphParameterError(\n \"(#100) Invalid parameter: audio.contentBase64\",\n \"audio.contentBase64 must contain non-empty canonical base64.\",\n );\n }\n const mimeType = readTrimmedString(value.mimeType);\n if (!mimeType?.toLowerCase().startsWith(\"audio/\")) {\n return graphParameterError(\n \"(#100) Invalid parameter: audio.mimeType\",\n \"audio.mimeType must be an audio MIME type.\",\n );\n }\n if (value.ptt !== undefined && typeof value.ptt !== \"boolean\") {\n return graphParameterError(\n \"(#100) Invalid parameter: audio.ptt\",\n \"audio.ptt must be a boolean when provided.\",\n );\n }\n const content = Buffer.from(contentBase64, \"base64\");\n if (content.byteLength === 0 || content.toString(\"base64\") !== contentBase64) {\n return graphParameterError(\n \"(#100) Invalid parameter: audio.contentBase64\",\n \"audio.contentBase64 must decode to non-empty content.\",\n );\n }\n return { content, mimeType, ptt: value.ptt ?? false };\n}\n\nfunction createWhatsAppAudioFixture(params: {\n audio: WhatsAppAdminAudio;\n messageId: string;\n state: WhatsAppServerState;\n}) {\n const mediaKey = randomBytes(32);\n const expandedKey = Buffer.from(\n hkdfSync(\"sha256\", mediaKey, Buffer.alloc(32), Buffer.from(\"WhatsApp Audio Keys\", \"utf8\"), 112),\n );\n const iv = expandedKey.subarray(0, 16);\n const cipherKey = expandedKey.subarray(16, 48);\n const macKey = expandedKey.subarray(48, 80);\n const cipher = createCipheriv(\"aes-256-cbc\", cipherKey, iv);\n const ciphertext = Buffer.concat([cipher.update(params.audio.content), cipher.final()]);\n const mac = createHmac(\"sha256\", macKey).update(iv).update(ciphertext).digest().subarray(0, 10);\n const encrypted = Buffer.concat([ciphertext, mac]);\n const mediaCapability = randomBytes(32).toString(\"base64url\");\n const encodedMessageId = Buffer.from(params.messageId, \"utf8\").toString(\"base64url\");\n const mediaPath = `/_crabline/media/whatsapp/${encodedMessageId}/${mediaCapability}`;\n return {\n audioMessage: {\n fileEncSha256: createHash(\"sha256\").update(encrypted).digest(),\n fileLength: params.audio.content.byteLength,\n fileSha256: createHash(\"sha256\").update(params.audio.content).digest(),\n mediaKey,\n mediaKeyTimestamp: Math.floor(Date.now() / 1_000),\n mimetype: params.audio.mimeType,\n ptt: params.audio.ptt,\n url: `${params.state.baseUrl}${mediaPath}`,\n },\n mediaFixture: {\n content: encrypted,\n mimeType: \"application/octet-stream\",\n path: mediaPath,\n },\n };\n}\n\nfunction removeWhatsAppMedia(state: WhatsAppServerState, mediaPath: string): void {\n const fixture = state.mediaByPath.get(mediaPath);\n if (!fixture) {\n return;\n }\n state.mediaByPath.delete(mediaPath);\n state.mediaBytes -= fixture.content.byteLength;\n}\n\nfunction purgeExpiredWhatsAppMedia(state: WhatsAppServerState, now = Date.now()): void {\n for (const [mediaPath, fixture] of state.mediaByPath) {\n if (fixture.expiresAt <= now) {\n removeWhatsAppMedia(state, mediaPath);\n }\n }\n}\n\nfunction reserveWhatsAppMedia(state: WhatsAppServerState, fixture: WhatsAppMediaFixture): boolean {\n purgeExpiredWhatsAppMedia(state);\n if (\n state.mediaByPath.size >= MAX_WHATSAPP_MEDIA_FIXTURES ||\n state.mediaBytes + fixture.content.byteLength > MAX_WHATSAPP_MEDIA_BYTES\n ) {\n return false;\n }\n state.mediaByPath.set(fixture.path, {\n content: fixture.content,\n expiresAt: Date.now() + WHATSAPP_MEDIA_TTL_MS,\n mimeType: fixture.mimeType,\n });\n state.mediaBytes += fixture.content.byteLength;\n return true;\n}\n\ntype PreparedWhatsAppSend = {\n commit(): Response;\n};\n\nfunction prepareSendMessage(params: {\n body: Record<string, unknown>;\n state: WhatsAppServerState;\n}): PreparedWhatsAppSend | Response {\n const productError = requireMessagingProduct(params.body);\n if (productError) {\n return productError;\n }\n const recipientType = readTrimmedString(params.body.recipient_type);\n if (recipientType && recipientType !== \"individual\") {\n return graphParameterError(\n \"(#100) Invalid parameter: recipient_type\",\n 'recipient_type must be \"individual\".',\n );\n }\n const to = requireCloudRecipient(params.body.to);\n if (to instanceof Response) {\n return to;\n }\n const text = readTextMessageBody(params.body);\n if (text instanceof Response) {\n return text;\n }\n return {\n commit() {\n const reservation = reserveMessageId(params.state);\n if (reservation instanceof Response) {\n return reservation;\n }\n reservation.commit();\n const message = createWhatsAppMessage({\n fromMe: true,\n id: reservation.id,\n remoteJid: `${to}@s.whatsapp.net`,\n text,\n });\n return jsonResponse({\n contacts: [\n {\n input: to,\n wa_id: to,\n },\n ],\n messages: [{ id: message.key.id }],\n messaging_product: \"whatsapp\",\n });\n },\n };\n}\n\nfunction handleMessageStatus(state: WhatsAppServerState, body: Record<string, unknown>): Response {\n const productError = requireMessagingProduct(body);\n if (productError) {\n return productError;\n }\n if (readTrimmedString(body.status) !== \"read\") {\n return graphParameterError(\n \"(#100) Invalid parameter: status\",\n 'status must be \"read\" for message status updates.',\n );\n }\n const messageId = readTrimmedString(body.message_id);\n if (!messageId) {\n return graphParameterError(\n \"(#100) Missing required parameter: message_id\",\n \"A message status update requires message_id.\",\n );\n }\n if (!state.inboundMessageIds.has(messageId)) {\n return graphParameterError(\n \"(#100) Invalid parameter: message_id\",\n \"message_id must reference an accepted inbound message.\",\n );\n }\n return jsonResponse({ success: true });\n}\n\nfunction rememberInboundMessageId(state: WhatsAppServerState, messageId: string): void {\n state.inboundMessageIds.delete(messageId);\n state.inboundMessageIds.add(messageId);\n if (state.inboundMessageIds.size > MAX_WHATSAPP_READABLE_MESSAGE_IDS) {\n const oldest = state.inboundMessageIds.values().next().value;\n if (oldest !== undefined) {\n state.inboundMessageIds.delete(oldest);\n }\n }\n}\n\nasync function handleAdminInbound(params: {\n body: Record<string, unknown>;\n state: WhatsAppServerState;\n}): Promise<WhatsAppAdminInboundResult> {\n const chatJid = requireWhatsAppChatJid(params.body.chatJid ?? params.body.chatId);\n if (chatJid instanceof Response) {\n return { response: chatJid };\n }\n const senderJid = requireWhatsAppSenderJid(params.body.senderJid ?? params.body.from);\n if (senderJid instanceof Response) {\n return { response: senderJid };\n }\n if (directPeerIdentity(senderJid) === directPeerIdentity(params.state.selfJid)) {\n return {\n response: graphParameterError(\n \"(#100) Invalid parameter: senderJid\",\n \"senderJid must not identify the configured WhatsApp self identity.\",\n ),\n };\n }\n const isGroupChat = isWhatsAppGroupJid(chatJid);\n if (!isGroupChat && directPeerIdentity(chatJid) !== directPeerIdentity(senderJid)) {\n return {\n response: graphParameterError(\n \"(#100) Invalid parameter: senderJid\",\n \"senderJid must identify the direct chat peer.\",\n ),\n };\n }\n const text = readMessageText(params.body.text);\n const audio = readAdminAudio(params.body.audio);\n if (audio instanceof Response) {\n return { response: audio };\n }\n if ((text === undefined) === (audio === undefined)) {\n return {\n response: graphParameterError(\n \"(#100) Invalid inbound WhatsApp event\",\n \"An inbound WhatsApp event requires exactly one of text or audio.\",\n ),\n };\n }\n const messageIdReservation = reserveMessageId(\n params.state,\n readTrimmedString(params.body.messageId),\n );\n if (messageIdReservation instanceof Response) {\n return { response: messageIdReservation };\n }\n const messageBase = {\n key: {\n fromMe: false,\n id: messageIdReservation.id,\n ...(isGroupChat ? { participant: senderJid } : {}),\n remoteJid: isGroupChat ? chatJid : directPeerIdentity(chatJid),\n },\n messageTimestamp: Math.floor(Date.now() / 1_000),\n pushName: readTrimmedString(params.body.pushName) ?? \"Test User\",\n };\n const audioFixture = audio\n ? createWhatsAppAudioFixture({ audio, messageId: messageIdReservation.id, state: params.state })\n : undefined;\n const message: WhatsAppBaileysMessage = text\n ? createWhatsAppMessage({\n fromMe: false,\n id: messageIdReservation.id,\n pushName: messageBase.pushName,\n remoteJid: messageBase.key.remoteJid,\n senderJid: isGroupChat ? senderJid : undefined,\n text,\n })\n : {\n ...messageBase,\n message: { audioMessage: audioFixture!.audioMessage },\n };\n const timestamp = String(message.messageTimestamp);\n const webhook = {\n entry: [\n {\n changes: [\n {\n field: \"messages\",\n value: {\n contacts: [\n {\n profile: { name: readTrimmedString(params.body.pushName) ?? \"Test User\" },\n wa_id: waIdFromJid(senderJid),\n },\n ],\n messages: [\n {\n from: waIdFromJid(senderJid),\n id: message.key.id,\n ...(text\n ? { text: { body: text }, type: \"text\" }\n : {\n audio: {\n id: message.key.id,\n mime_type: audio!.mimeType,\n },\n type: \"audio\",\n }),\n timestamp,\n },\n ],\n messaging_product: \"whatsapp\",\n metadata: {\n display_phone_number: params.state.displayPhoneNumber,\n phone_number_id: params.state.phoneNumberId,\n },\n },\n },\n ],\n id: \"TEST_WABA\",\n },\n ],\n object: \"whatsapp_business_account\",\n };\n return {\n mediaFixture: audioFixture?.mediaFixture,\n message,\n messageIdReservation,\n webhook,\n };\n}\n\nasync function handleRequest(params: { request: IncomingMessage; state: WhatsAppServerState }) {\n const url = new URL(params.request.url ?? \"/\", \"http://127.0.0.1\");\n\n if (url.pathname.startsWith(\"/_crabline/media/whatsapp/\")) {\n if (params.request.method !== \"GET\") {\n drainRequestBody(params.request);\n return new Response(\"not found\", { status: 404 });\n }\n purgeExpiredWhatsAppMedia(params.state);\n const fixture = params.state.mediaByPath.get(url.pathname);\n if (fixture) {\n fixture.expiresAt = Math.min(\n fixture.expiresAt,\n Date.now() + WHATSAPP_MEDIA_DOWNLOAD_GRACE_MS,\n );\n }\n return fixture\n ? new Response(new Uint8Array(fixture.content), {\n headers: { \"content-type\": fixture.mimeType },\n })\n : new Response(\"not found\", { status: 404 });\n }\n\n if (url.pathname === \"/_crabline/admin/whatsapp/inbound\") {\n if (params.request.method !== \"POST\") {\n drainRequestBody(params.request);\n return new Response(\"not found\", { status: 404 });\n }\n if (!hasAdminToken(params.request, params.state.adminToken)) {\n drainRequestBody(params.request);\n return adminAuthError();\n }\n const body = await parseUnknownRequestBody(params.request);\n if (!isJsonObject(body)) {\n return graphParameterError(\n \"(#100) Invalid parameter: request body\",\n \"The request body must be a JSON object.\",\n );\n }\n const result = await handleAdminInbound({ body, state: params.state });\n if (result.response) {\n return result.response;\n }\n const event: WhatsAppRecorderEvent = {\n at: new Date().toISOString(),\n body,\n method: params.request.method,\n path: url.pathname,\n query: queryRecord(url),\n type: \"admin\",\n };\n const preparedDelivery = result.message\n ? params.state.prepareInboundMessage(result.message)\n : undefined;\n if (result.message && !preparedDelivery) {\n result.messageIdReservation?.cancel();\n return graphError({\n code: 4,\n details: \"The pending WhatsApp inbound queue is full.\",\n message: \"(#4) Application request limit reached.\",\n status: 503,\n type: \"OAuthException\",\n });\n }\n if (result.mediaFixture && !reserveWhatsAppMedia(params.state, result.mediaFixture)) {\n preparedDelivery?.cancel();\n result.messageIdReservation?.cancel();\n return graphError({\n code: 4,\n details: \"The WhatsApp media fixture capacity is full.\",\n message: \"(#4) Application request limit reached.\",\n status: 503,\n type: \"OAuthException\",\n });\n }\n if (result.message) {\n event.message = result.message;\n }\n try {\n await appendEvent(params.state, event);\n } catch (error) {\n if (!(error instanceof ServerRecorderCommittedError)) {\n preparedDelivery?.cancel();\n if (result.mediaFixture) {\n removeWhatsAppMedia(params.state, result.mediaFixture.path);\n }\n result.messageIdReservation?.cancel();\n throw error;\n }\n result.messageIdReservation?.commit();\n if (result.message && preparedDelivery) {\n try {\n await preparedDelivery.commit();\n rememberInboundMessageId(params.state, result.message.key.id);\n } catch (deliveryError) {\n const reconciliationError = new AggregateError(\n [error, deliveryError],\n \"WhatsApp recorder append committed, but inbound delivery reconciliation failed.\",\n );\n reconciliationError.cause = deliveryError;\n throw reconciliationError;\n }\n }\n throw error;\n }\n if (result.message && preparedDelivery) {\n try {\n const delivery = await preparedDelivery.commit();\n result.messageIdReservation?.commit();\n rememberInboundMessageId(params.state, result.message.key.id);\n return whatsappOk({ delivery, message: result.message, webhook: result.webhook });\n } catch (error) {\n if (result.mediaFixture) {\n removeWhatsAppMedia(params.state, result.mediaFixture.path);\n }\n result.messageIdReservation?.cancel();\n throw error;\n }\n }\n if (result.mediaFixture) {\n removeWhatsAppMedia(params.state, result.mediaFixture.path);\n }\n result.messageIdReservation?.cancel();\n return graphParameterError(\"(#100) Invalid inbound WhatsApp event\");\n }\n\n const phoneNumberPath = `/${params.state.graphVersion}/${params.state.phoneNumberId}`;\n const messagesPath = `${phoneNumberPath}/messages`;\n if (!requireAuth(params.request, params.state)) {\n drainRequestBody(params.request);\n return graphAuthError();\n }\n if (url.pathname === phoneNumberPath && params.request.method === \"GET\") {\n const body = queryRecord(url);\n await appendEvent(params.state, {\n accepted: true,\n at: new Date().toISOString(),\n body,\n method: params.request.method,\n path: url.pathname,\n query: body,\n type: \"api\",\n });\n return jsonResponse({\n display_phone_number: params.state.displayPhoneNumber,\n id: params.state.phoneNumberId,\n quality_rating: \"GREEN\",\n verified_name: \"Crabline Test Bot\",\n });\n }\n if (url.pathname === messagesPath) {\n if (params.request.method !== \"POST\") {\n drainRequestBody(params.request);\n return new Response(\"not found\", { status: 404 });\n }\n const body = await parseUnknownRequestBody(params.request);\n const event: WhatsAppRecorderEvent = {\n at: new Date().toISOString(),\n body,\n method: params.request.method,\n path: url.pathname,\n query: queryRecord(url),\n type: \"api\",\n };\n let response: Response;\n if (!isJsonObject(body)) {\n response = graphParameterError(\n \"(#100) Invalid parameter: request body\",\n \"The request body must be a JSON object.\",\n );\n } else if (\"status\" in body || \"message_id\" in body) {\n response = handleMessageStatus(params.state, body);\n event.accepted = response.ok;\n } else {\n const prepared = prepareSendMessage({ body, state: params.state });\n if (!(prepared instanceof Response)) {\n response = prepared.commit();\n event.accepted = true;\n await appendEvent(params.state, event);\n return response;\n }\n response = prepared;\n }\n event.accepted ??= false;\n await appendEvent(params.state, event);\n return response;\n }\n drainRequestBody(params.request);\n return new Response(\"not found\", { status: 404 });\n}\n\nexport async function startWhatsAppServer(\n params: StartWhatsAppServerParams = {},\n): Promise<StartedWhatsAppServer> {\n const host = params.host ?? \"127.0.0.1\";\n if (!isLoopbackHost(host)) {\n throw new Error(\n \"WhatsApp server requires a loopback host because its HTTP and WebSocket endpoints carry credentials over cleartext.\",\n );\n }\n if (\n params.accessToken !== undefined &&\n (!params.accessToken.trim() || params.accessToken !== params.accessToken.trim())\n ) {\n throw new Error(\"WhatsApp accessToken must not be empty or whitespace-padded.\");\n }\n if (\n params.adminToken !== undefined &&\n (!params.adminToken.trim() || params.adminToken !== params.adminToken.trim())\n ) {\n throw new Error(\"WhatsApp adminToken must not be empty or whitespace-padded.\");\n }\n const graphVersion = params.graphVersion ?? DEFAULT_GRAPH_VERSION;\n if (!WHATSAPP_GRAPH_VERSION_RE.test(graphVersion)) {\n throw new Error(`Invalid WhatsApp Graph API version: ${graphVersion}.`);\n }\n const phoneNumberId = params.phoneNumberId ?? \"100000000000000\";\n if (!/^\\d+$/u.test(phoneNumberId)) {\n throw new Error(\"WhatsApp phoneNumberId must contain only digits.\");\n }\n const maxPendingInboundMessages = resolveMaxPendingWhatsAppInboundMessages(\n params.maxPendingInboundMessages,\n );\n const selfJid = canonicalizeWhatsAppUserJid(params.selfJid ?? \"15550000000@s.whatsapp.net\");\n if (!selfJid) {\n throw new Error(\"WhatsApp selfJid must be a WhatsApp user JID.\");\n }\n const state: WhatsAppServerState = {\n accessToken: params.accessToken ?? createDefaultAccessToken(),\n adminToken: params.adminToken ?? randomBytes(24).toString(\"hex\"),\n baseUrl: \"\",\n prepareInboundMessage: () => undefined,\n displayPhoneNumber: params.displayPhoneNumber ?? \"15550000000\",\n graphVersion,\n inboundMessageIds: new Set(),\n mediaByPath: new Map(),\n mediaBytes: 0,\n pendingMessageIds: new Set(),\n recentMessageIds: new Map(),\n nextMessageId: 1n,\n onEvent: params.onEvent,\n phoneNumberId,\n recorderPath: params.recorderPath ?? path.resolve(\".crabline\", \"servers\", \"whatsapp.jsonl\"),\n selfJid,\n };\n const httpServer = await startHttpJsonServer({\n handle: (request) => handleRequest({ request, state }),\n handleError: (error) => {\n if (error instanceof InvalidJsonBodyError) {\n return graphParameterError(\n \"(#100) Invalid parameter: request body\",\n \"The request body must be valid JSON.\",\n );\n }\n if (error instanceof RequestBodyTooLargeError) {\n return graphError({\n code: 100,\n details: \"The request body exceeds the supported size limit.\",\n message: \"(#100) Request body is too large.\",\n status: 413,\n });\n }\n return undefined;\n },\n host,\n port: params.port ?? 0,\n serverName: \"WhatsApp\",\n });\n const baseUrl = httpServer.baseUrl;\n state.baseUrl = baseUrl;\n const apiRoot = `${baseUrl}/${state.graphVersion}`;\n const phoneNumberUrl = `${apiRoot}/${state.phoneNumberId}`;\n const messagesUrl = `${phoneNumberUrl}/messages`;\n const baileysWebSocketUrl = `${baseUrl.replace(\n /^http/u,\n \"ws\",\n )}/ws/chat?access_token=${encodeURIComponent(state.accessToken)}`;\n const baileysWebSocketOptions = {\n accessToken: state.accessToken,\n appendEvent: (event: ServerRequestEvent) => appendEvent(state, event),\n httpServer: httpServer.server,\n maxPendingInboundMessages,\n messageAcceptanceTimeoutMs: params.messageAcceptanceTimeoutMs,\n path: \"/ws/chat\",\n selfJid: state.selfJid,\n };\n let baileysWebSocketServer;\n try {\n baileysWebSocketServer = attachWhatsAppBaileysWebSocketServer(baileysWebSocketOptions);\n } catch (error) {\n try {\n await httpServer.close();\n } catch (closeError) {\n const aggregateError = new AggregateError(\n [error, closeError],\n \"WhatsApp WebSocket startup failed and HTTP rollback also failed.\",\n );\n aggregateError.cause = error;\n throw aggregateError;\n }\n throw error;\n }\n state.prepareInboundMessage = (message) => baileysWebSocketServer.prepareInboundMessage(message);\n return {\n async close() {\n const results = await Promise.allSettled([\n baileysWebSocketServer.close(),\n httpServer.close(),\n ]);\n const errors = results.flatMap((result) =>\n result.status === \"rejected\" ? [result.reason] : [],\n );\n state.mediaByPath.clear();\n state.mediaBytes = 0;\n if (errors.length === 1) {\n throw errors[0];\n }\n if (errors.length > 1) {\n throw new AggregateError(errors, \"WhatsApp server shutdown failed.\");\n }\n },\n manifest: {\n accessToken: state.accessToken,\n adminToken: state.adminToken,\n baseUrl,\n endpoints: {\n adminInboundUrl: `${baseUrl}/_crabline/admin/whatsapp/inbound`,\n apiRoot,\n baileysWebSocketUrl,\n messagesUrl,\n phoneNumberUrl,\n },\n env: {\n CLOUD_API_ACCESS_TOKEN: state.accessToken,\n CLOUD_API_VERSION: state.graphVersion,\n WA_BASE_URL: baseUrl,\n WA_PHONE_NUMBER_ID: state.phoneNumberId,\n },\n graphVersion: state.graphVersion,\n phoneNumberId: state.phoneNumberId,\n provider: \"whatsapp\",\n recorderPath: state.recorderPath,\n selfJid: state.selfJid,\n version: 1,\n },\n };\n}\n\nfunction readMessageText(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value : undefined;\n}\n"]}
1
+ {"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../../src/servers/whatsapp.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage } from \"node:http\";\nimport { createCipheriv, createHash, createHmac, hkdfSync, randomBytes } from \"node:crypto\";\nimport path from \"node:path\";\nimport {\n adminAuthError,\n createServerClose,\n constantTimeTokenEqual,\n drainRequestBody,\n hasAdminToken,\n InvalidJsonBodyError,\n isJsonObject,\n isLoopbackHost,\n jsonResponse,\n parseUnknownRequestBody,\n queryRecord,\n readTrimmedString,\n RequestBodyTooLargeError,\n startHttpJsonServer,\n type ServerRequestEvent,\n} from \"./http.js\";\nimport {\n createServerRecorder,\n type ServerRecorder,\n ServerRecorderCommittedError,\n type ServerEventObserver,\n} from \"./recorder.js\";\nimport {\n attachWhatsAppBaileysWebSocketServer,\n resolveMaxPendingWhatsAppInboundMessages,\n type PreparedWhatsAppBaileysInboundDelivery,\n type WhatsAppBaileysInboundMessage,\n} from \"./whatsapp-baileys-websocket.js\";\nimport {\n canonicalizeWhatsAppChatJid,\n canonicalizeWhatsAppUserCorrelationJid,\n canonicalizeWhatsAppUserJid,\n isWhatsAppGroupJid,\n} from \"./whatsapp-jid.js\";\n\nconst WHATSAPP_CLOUD_RECIPIENT_RE = /^\\d{7,15}$/u;\nconst WHATSAPP_GRAPH_VERSION_RE = /^v\\d+\\.\\d+$/u;\nconst WHATSAPP_GENERATED_MESSAGE_ID_RE = /^wamid\\.FAKE(\\d{8,})$/u;\nconst DEFAULT_GRAPH_VERSION = \"v25.0\";\nconst MAX_WHATSAPP_READABLE_MESSAGE_IDS = 10_000;\nconst MAX_WHATSAPP_RECENT_MESSAGE_IDS = 10_000;\nconst MAX_WHATSAPP_MESSAGE_ID_BYTES = 128;\nconst MAX_WHATSAPP_TEXT_MESSAGE_CHARACTERS = 4_096;\nconst MAX_WHATSAPP_MEDIA_FIXTURES = 1_000;\nconst MAX_WHATSAPP_MEDIA_BYTES = 16 * 1024 * 1024;\nconst WHATSAPP_MEDIA_TTL_MS = 5 * 60 * 1_000;\nconst WHATSAPP_MEDIA_DOWNLOAD_GRACE_MS = 30 * 1_000;\n\nfunction createDefaultAccessToken(): string {\n return `EAA${randomBytes(24).toString(\"base64url\")}`;\n}\n\ntype WhatsAppServerState = {\n accessToken: string;\n adminToken: string;\n baseUrl: string;\n displayPhoneNumber: string;\n prepareInboundMessage(\n message: WhatsAppBaileysInboundMessage,\n ): PreparedWhatsAppBaileysInboundDelivery | undefined;\n graphVersion: string;\n inboundMessageIds: Set<string>;\n mediaByPath: Map<string, { content: Buffer; expiresAt: number; mimeType: string }>;\n mediaBytes: number;\n pendingMessageIds: Set<string>;\n recentMessageIds: Map<string, true>;\n nextMessageId: bigint;\n recorder: ServerRecorder;\n phoneNumberId: string;\n recorderPath: string;\n selfJid: string;\n};\n\nexport type WhatsAppBaileysMessage = WhatsAppBaileysInboundMessage;\n\nexport type WhatsAppServerManifest = {\n accessToken: string;\n adminToken: string;\n baseUrl: string;\n endpoints: {\n adminInboundUrl: string;\n apiRoot: string;\n baileysWebSocketUrl: string;\n messagesUrl: string;\n phoneNumberUrl: string;\n };\n env: {\n CLOUD_API_ACCESS_TOKEN: string;\n CLOUD_API_VERSION: string;\n WA_BASE_URL: string;\n WA_PHONE_NUMBER_ID: string;\n };\n graphVersion: string;\n phoneNumberId: string;\n provider: \"whatsapp\";\n recorderPath: string;\n selfJid: string;\n version: 1;\n};\n\nexport type StartedWhatsAppServer = {\n close(): Promise<void>;\n manifest: WhatsAppServerManifest;\n};\n\nexport type StartWhatsAppServerParams = {\n accessToken?: string | undefined;\n adminToken?: string | undefined;\n displayPhoneNumber?: string | undefined;\n graphVersion?: string | undefined;\n host?: string | undefined;\n maxPendingInboundMessages?: number | undefined;\n messageAcceptanceTimeoutMs?: number | undefined;\n onEvent?: ServerEventObserver | undefined;\n phoneNumberId?: string | undefined;\n port?: number | undefined;\n recorderPath?: string | undefined;\n selfJid?: string | undefined;\n};\n\ntype WhatsAppAdminInboundResult = {\n mediaFixture?: WhatsAppMediaFixture | undefined;\n message?: WhatsAppBaileysMessage | undefined;\n messageIdReservation?: WhatsAppMessageIdReservation | undefined;\n response?: Response | undefined;\n webhook?: Record<string, unknown> | undefined;\n};\n\ntype WhatsAppRecorderEvent = ServerRequestEvent & {\n accepted?: boolean | undefined;\n message?: WhatsAppBaileysMessage | undefined;\n};\n\nfunction whatsappOk(value: Record<string, unknown> = {}): Response {\n return jsonResponse({ ok: true, ...value });\n}\n\nfunction graphError(params: {\n code?: number | undefined;\n details?: string | undefined;\n message: string;\n status?: number | undefined;\n type?: string | undefined;\n}): Response {\n return jsonResponse(\n {\n error: {\n code: params.code ?? 100,\n ...(params.details\n ? {\n error_data: {\n details: params.details,\n messaging_product: \"whatsapp\",\n },\n }\n : {}),\n fbtrace_id: \"A1B2C3D4E5F\",\n message: params.message,\n type: params.type ?? \"OAuthException\",\n },\n },\n params.status ?? 400,\n );\n}\n\nfunction graphParameterError(message: string, details?: string): Response {\n return graphError({ code: 100, details, message, status: 400 });\n}\n\nfunction graphAuthError(): Response {\n return graphError({\n code: 190,\n message: \"Invalid OAuth access token.\",\n status: 401,\n });\n}\n\nasync function appendEvent(state: WhatsAppServerState, event: WhatsAppRecorderEvent) {\n await state.recorder.record(event);\n}\n\nfunction requireWhatsAppChatJid(value: unknown): string | Response {\n const stringValue = readTrimmedString(value);\n const canonical = stringValue ? canonicalizeWhatsAppChatJid(stringValue) : undefined;\n if (!canonical) {\n return graphParameterError(\n \"(#100) Invalid parameter: chatJid\",\n \"chatJid must be a WhatsApp user or group JID.\",\n );\n }\n return canonical;\n}\n\nfunction requireWhatsAppSenderJid(value: unknown): string | Response {\n const stringValue = readTrimmedString(value);\n const canonical = stringValue ? canonicalizeWhatsAppUserJid(stringValue) : undefined;\n if (!canonical) {\n return graphParameterError(\n \"(#100) Invalid parameter: senderJid\",\n \"senderJid must be a WhatsApp user JID.\",\n );\n }\n return canonical;\n}\n\nfunction requireCloudRecipient(value: unknown): string | Response {\n const recipient = readTrimmedString(value);\n if (!recipient || !WHATSAPP_CLOUD_RECIPIENT_RE.test(recipient)) {\n return graphParameterError(\n \"(#100) Invalid parameter: to\",\n \"to must be a WhatsApp phone number in international format without punctuation.\",\n );\n }\n return recipient;\n}\n\nfunction requireAuth(request: IncomingMessage, state: WhatsAppServerState): boolean {\n const authorization = request.headers.authorization;\n if (typeof authorization !== \"string\") {\n return false;\n }\n const match = /^Bearer +(.+)$/iu.exec(authorization.trimStart());\n const providedToken = match?.[1];\n return providedToken ? constantTimeTokenEqual(providedToken, state.accessToken) : false;\n}\n\ntype WhatsAppMessageIdReservation = {\n cancel(): void;\n commit(): void;\n id: string;\n};\n\n/** @internal */\nexport function isWhatsAppMessageIdInUse(\n state: {\n inboundMessageIds: ReadonlySet<string>;\n pendingMessageIds: ReadonlySet<string>;\n recentMessageIds: ReadonlyMap<string, true>;\n },\n id: string,\n): boolean {\n return (\n state.inboundMessageIds.has(id) ||\n state.pendingMessageIds.has(id) ||\n state.recentMessageIds.has(id)\n );\n}\n\nfunction reserveMessageId(\n state: WhatsAppServerState,\n requestedId?: string,\n): WhatsAppMessageIdReservation | Response {\n let id = requestedId;\n if (id) {\n if (Buffer.byteLength(id, \"utf8\") > MAX_WHATSAPP_MESSAGE_ID_BYTES) {\n return graphParameterError(\n \"(#100) Invalid parameter: messageId\",\n `messageId must not exceed ${MAX_WHATSAPP_MESSAGE_ID_BYTES} UTF-8 bytes.`,\n );\n }\n if (isWhatsAppMessageIdInUse(state, id)) {\n return graphParameterError(\n \"(#100) Invalid parameter: messageId\",\n \"messageId must be unique within this WhatsApp server.\",\n );\n }\n } else {\n do {\n id = `wamid.FAKE${String(state.nextMessageId++).padStart(8, \"0\")}`;\n } while (isWhatsAppMessageIdInUse(state, id));\n }\n state.pendingMessageIds.add(id);\n let settled = false;\n return {\n cancel() {\n if (!settled) {\n settled = true;\n state.pendingMessageIds.delete(id);\n }\n },\n commit() {\n if (settled) {\n return;\n }\n settled = true;\n state.pendingMessageIds.delete(id);\n state.recentMessageIds.delete(id);\n state.recentMessageIds.set(id, true);\n if (state.recentMessageIds.size > MAX_WHATSAPP_RECENT_MESSAGE_IDS) {\n const oldestId = state.recentMessageIds.keys().next().value;\n if (oldestId !== undefined) {\n state.recentMessageIds.delete(oldestId);\n }\n }\n const generatedSequence = WHATSAPP_GENERATED_MESSAGE_ID_RE.exec(id)?.[1];\n if (generatedSequence) {\n const sequence = BigInt(generatedSequence);\n if (sequence >= state.nextMessageId) {\n state.nextMessageId = sequence + 1n;\n }\n }\n },\n id,\n };\n}\n\nfunction waIdFromJid(jid: string): string {\n const correlationJid = canonicalizeWhatsAppUserCorrelationJid(jid);\n return correlationJid?.split(\"@\", 1)[0] ?? jid;\n}\n\nfunction directPeerIdentity(jid: string): string {\n return canonicalizeWhatsAppUserCorrelationJid(jid) ?? jid;\n}\n\nfunction requireMessagingProduct(body: Record<string, unknown>): Response | undefined {\n const messagingProduct = readTrimmedString(body.messaging_product);\n if (messagingProduct !== \"whatsapp\") {\n return graphParameterError(\n \"(#100) Invalid parameter: messaging_product\",\n 'messaging_product must be \"whatsapp\".',\n );\n }\n return undefined;\n}\n\nfunction readTextMessageBody(body: Record<string, unknown>): string | Response {\n const type = readTrimmedString(body.type);\n if (!type) {\n return graphParameterError(\n \"(#100) Missing required parameter: type\",\n 'A WhatsApp text send requires type to be \"text\".',\n );\n }\n if (type !== \"text\") {\n return graphParameterError(\n \"(#100) Unsupported message type\",\n \"This test API currently supports WhatsApp text message sends.\",\n );\n }\n const textPayload = body.text;\n const text =\n textPayload && typeof textPayload === \"object\"\n ? readMessageText((textPayload as Record<string, unknown>).body)\n : undefined;\n if (text === undefined) {\n return graphParameterError(\n \"(#100) Missing required parameter: text.body\",\n \"A WhatsApp text send requires text.body.\",\n );\n }\n if ([...text].length > MAX_WHATSAPP_TEXT_MESSAGE_CHARACTERS) {\n return graphParameterError(\n \"(#100) Invalid parameter: text.body\",\n `text.body must not exceed ${MAX_WHATSAPP_TEXT_MESSAGE_CHARACTERS} characters.`,\n );\n }\n return text;\n}\n\nfunction createWhatsAppMessage(params: {\n fromMe: boolean;\n id: string;\n pushName?: string | undefined;\n remoteJid: string;\n senderJid?: string | undefined;\n text: string;\n}) {\n return {\n key: {\n fromMe: params.fromMe,\n id: params.id,\n ...(params.senderJid ? { participant: params.senderJid } : {}),\n remoteJid: params.remoteJid,\n },\n message: {\n conversation: params.text,\n },\n messageTimestamp: Math.floor(Date.now() / 1000),\n pushName: params.pushName ?? (params.fromMe ? \"Test Bot\" : \"Test User\"),\n };\n}\n\ntype WhatsAppAdminAudio = {\n content: Buffer;\n mimeType: string;\n ptt: boolean;\n};\n\ntype WhatsAppMediaFixture = {\n content: Buffer;\n mimeType: string;\n path: string;\n};\n\nfunction readAdminAudio(value: unknown): WhatsAppAdminAudio | Response | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (!isJsonObject(value)) {\n return graphParameterError(\n \"(#100) Invalid parameter: audio\",\n \"audio must be an object containing inline base64 content and an audio MIME type.\",\n );\n }\n const contentBase64 = typeof value.contentBase64 === \"string\" ? value.contentBase64 : undefined;\n if (\n !contentBase64 ||\n !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u.test(contentBase64)\n ) {\n return graphParameterError(\n \"(#100) Invalid parameter: audio.contentBase64\",\n \"audio.contentBase64 must contain non-empty canonical base64.\",\n );\n }\n const mimeType = readTrimmedString(value.mimeType);\n if (!mimeType?.toLowerCase().startsWith(\"audio/\")) {\n return graphParameterError(\n \"(#100) Invalid parameter: audio.mimeType\",\n \"audio.mimeType must be an audio MIME type.\",\n );\n }\n if (value.ptt !== undefined && typeof value.ptt !== \"boolean\") {\n return graphParameterError(\n \"(#100) Invalid parameter: audio.ptt\",\n \"audio.ptt must be a boolean when provided.\",\n );\n }\n const content = Buffer.from(contentBase64, \"base64\");\n if (content.byteLength === 0 || content.toString(\"base64\") !== contentBase64) {\n return graphParameterError(\n \"(#100) Invalid parameter: audio.contentBase64\",\n \"audio.contentBase64 must decode to non-empty content.\",\n );\n }\n return { content, mimeType, ptt: value.ptt ?? false };\n}\n\nfunction createWhatsAppAudioFixture(params: {\n audio: WhatsAppAdminAudio;\n messageId: string;\n state: WhatsAppServerState;\n}) {\n const mediaKey = randomBytes(32);\n const expandedKey = Buffer.from(\n hkdfSync(\"sha256\", mediaKey, Buffer.alloc(32), Buffer.from(\"WhatsApp Audio Keys\", \"utf8\"), 112),\n );\n const iv = expandedKey.subarray(0, 16);\n const cipherKey = expandedKey.subarray(16, 48);\n const macKey = expandedKey.subarray(48, 80);\n const cipher = createCipheriv(\"aes-256-cbc\", cipherKey, iv);\n const ciphertext = Buffer.concat([cipher.update(params.audio.content), cipher.final()]);\n const mac = createHmac(\"sha256\", macKey).update(iv).update(ciphertext).digest().subarray(0, 10);\n const encrypted = Buffer.concat([ciphertext, mac]);\n const mediaCapability = randomBytes(32).toString(\"base64url\");\n const encodedMessageId = Buffer.from(params.messageId, \"utf8\").toString(\"base64url\");\n const mediaPath = `/_crabline/media/whatsapp/${encodedMessageId}/${mediaCapability}`;\n return {\n audioMessage: {\n fileEncSha256: createHash(\"sha256\").update(encrypted).digest(),\n fileLength: params.audio.content.byteLength,\n fileSha256: createHash(\"sha256\").update(params.audio.content).digest(),\n mediaKey,\n mediaKeyTimestamp: Math.floor(Date.now() / 1_000),\n mimetype: params.audio.mimeType,\n ptt: params.audio.ptt,\n url: `${params.state.baseUrl}${mediaPath}`,\n },\n mediaFixture: {\n content: encrypted,\n mimeType: \"application/octet-stream\",\n path: mediaPath,\n },\n };\n}\n\nfunction removeWhatsAppMedia(state: WhatsAppServerState, mediaPath: string): void {\n const fixture = state.mediaByPath.get(mediaPath);\n if (!fixture) {\n return;\n }\n state.mediaByPath.delete(mediaPath);\n state.mediaBytes -= fixture.content.byteLength;\n}\n\nfunction purgeExpiredWhatsAppMedia(state: WhatsAppServerState, now = Date.now()): void {\n for (const [mediaPath, fixture] of state.mediaByPath) {\n if (fixture.expiresAt <= now) {\n removeWhatsAppMedia(state, mediaPath);\n }\n }\n}\n\nfunction reserveWhatsAppMedia(state: WhatsAppServerState, fixture: WhatsAppMediaFixture): boolean {\n purgeExpiredWhatsAppMedia(state);\n if (\n state.mediaByPath.size >= MAX_WHATSAPP_MEDIA_FIXTURES ||\n state.mediaBytes + fixture.content.byteLength > MAX_WHATSAPP_MEDIA_BYTES\n ) {\n return false;\n }\n state.mediaByPath.set(fixture.path, {\n content: fixture.content,\n expiresAt: Date.now() + WHATSAPP_MEDIA_TTL_MS,\n mimeType: fixture.mimeType,\n });\n state.mediaBytes += fixture.content.byteLength;\n return true;\n}\n\ntype PreparedWhatsAppSend = {\n commit(): Response;\n};\n\nfunction prepareSendMessage(params: {\n body: Record<string, unknown>;\n state: WhatsAppServerState;\n}): PreparedWhatsAppSend | Response {\n const productError = requireMessagingProduct(params.body);\n if (productError) {\n return productError;\n }\n const recipientType = readTrimmedString(params.body.recipient_type);\n if (recipientType && recipientType !== \"individual\") {\n return graphParameterError(\n \"(#100) Invalid parameter: recipient_type\",\n 'recipient_type must be \"individual\".',\n );\n }\n const to = requireCloudRecipient(params.body.to);\n if (to instanceof Response) {\n return to;\n }\n const text = readTextMessageBody(params.body);\n if (text instanceof Response) {\n return text;\n }\n return {\n commit() {\n const reservation = reserveMessageId(params.state);\n if (reservation instanceof Response) {\n return reservation;\n }\n reservation.commit();\n const message = createWhatsAppMessage({\n fromMe: true,\n id: reservation.id,\n remoteJid: `${to}@s.whatsapp.net`,\n text,\n });\n return jsonResponse({\n contacts: [\n {\n input: to,\n wa_id: to,\n },\n ],\n messages: [{ id: message.key.id }],\n messaging_product: \"whatsapp\",\n });\n },\n };\n}\n\nfunction handleMessageStatus(state: WhatsAppServerState, body: Record<string, unknown>): Response {\n const productError = requireMessagingProduct(body);\n if (productError) {\n return productError;\n }\n if (readTrimmedString(body.status) !== \"read\") {\n return graphParameterError(\n \"(#100) Invalid parameter: status\",\n 'status must be \"read\" for message status updates.',\n );\n }\n const messageId = readTrimmedString(body.message_id);\n if (!messageId) {\n return graphParameterError(\n \"(#100) Missing required parameter: message_id\",\n \"A message status update requires message_id.\",\n );\n }\n if (!state.inboundMessageIds.has(messageId)) {\n return graphParameterError(\n \"(#100) Invalid parameter: message_id\",\n \"message_id must reference an accepted inbound message.\",\n );\n }\n return jsonResponse({ success: true });\n}\n\nfunction rememberInboundMessageId(state: WhatsAppServerState, messageId: string): void {\n state.inboundMessageIds.delete(messageId);\n state.inboundMessageIds.add(messageId);\n if (state.inboundMessageIds.size > MAX_WHATSAPP_READABLE_MESSAGE_IDS) {\n const oldest = state.inboundMessageIds.values().next().value;\n if (oldest !== undefined) {\n state.inboundMessageIds.delete(oldest);\n }\n }\n}\n\nasync function handleAdminInbound(params: {\n body: Record<string, unknown>;\n state: WhatsAppServerState;\n}): Promise<WhatsAppAdminInboundResult> {\n const chatJid = requireWhatsAppChatJid(params.body.chatJid ?? params.body.chatId);\n if (chatJid instanceof Response) {\n return { response: chatJid };\n }\n const senderJid = requireWhatsAppSenderJid(params.body.senderJid ?? params.body.from);\n if (senderJid instanceof Response) {\n return { response: senderJid };\n }\n if (directPeerIdentity(senderJid) === directPeerIdentity(params.state.selfJid)) {\n return {\n response: graphParameterError(\n \"(#100) Invalid parameter: senderJid\",\n \"senderJid must not identify the configured WhatsApp self identity.\",\n ),\n };\n }\n const isGroupChat = isWhatsAppGroupJid(chatJid);\n if (!isGroupChat && directPeerIdentity(chatJid) !== directPeerIdentity(senderJid)) {\n return {\n response: graphParameterError(\n \"(#100) Invalid parameter: senderJid\",\n \"senderJid must identify the direct chat peer.\",\n ),\n };\n }\n const text = readMessageText(params.body.text);\n const audio = readAdminAudio(params.body.audio);\n if (audio instanceof Response) {\n return { response: audio };\n }\n if ((text === undefined) === (audio === undefined)) {\n return {\n response: graphParameterError(\n \"(#100) Invalid inbound WhatsApp event\",\n \"An inbound WhatsApp event requires exactly one of text or audio.\",\n ),\n };\n }\n const messageIdReservation = reserveMessageId(\n params.state,\n readTrimmedString(params.body.messageId),\n );\n if (messageIdReservation instanceof Response) {\n return { response: messageIdReservation };\n }\n const messageBase = {\n key: {\n fromMe: false,\n id: messageIdReservation.id,\n ...(isGroupChat ? { participant: senderJid } : {}),\n remoteJid: isGroupChat ? chatJid : directPeerIdentity(chatJid),\n },\n messageTimestamp: Math.floor(Date.now() / 1_000),\n pushName: readTrimmedString(params.body.pushName) ?? \"Test User\",\n };\n const audioFixture = audio\n ? createWhatsAppAudioFixture({ audio, messageId: messageIdReservation.id, state: params.state })\n : undefined;\n const message: WhatsAppBaileysMessage = text\n ? createWhatsAppMessage({\n fromMe: false,\n id: messageIdReservation.id,\n pushName: messageBase.pushName,\n remoteJid: messageBase.key.remoteJid,\n senderJid: isGroupChat ? senderJid : undefined,\n text,\n })\n : {\n ...messageBase,\n message: { audioMessage: audioFixture!.audioMessage },\n };\n const timestamp = String(message.messageTimestamp);\n const webhook = {\n entry: [\n {\n changes: [\n {\n field: \"messages\",\n value: {\n contacts: [\n {\n profile: { name: readTrimmedString(params.body.pushName) ?? \"Test User\" },\n wa_id: waIdFromJid(senderJid),\n },\n ],\n messages: [\n {\n from: waIdFromJid(senderJid),\n id: message.key.id,\n ...(text\n ? { text: { body: text }, type: \"text\" }\n : {\n audio: {\n id: message.key.id,\n mime_type: audio!.mimeType,\n },\n type: \"audio\",\n }),\n timestamp,\n },\n ],\n messaging_product: \"whatsapp\",\n metadata: {\n display_phone_number: params.state.displayPhoneNumber,\n phone_number_id: params.state.phoneNumberId,\n },\n },\n },\n ],\n id: \"TEST_WABA\",\n },\n ],\n object: \"whatsapp_business_account\",\n };\n return {\n mediaFixture: audioFixture?.mediaFixture,\n message,\n messageIdReservation,\n webhook,\n };\n}\n\nasync function handleRequest(params: { request: IncomingMessage; state: WhatsAppServerState }) {\n const url = new URL(params.request.url ?? \"/\", \"http://127.0.0.1\");\n\n if (url.pathname.startsWith(\"/_crabline/media/whatsapp/\")) {\n if (params.request.method !== \"GET\") {\n drainRequestBody(params.request);\n return new Response(\"not found\", { status: 404 });\n }\n purgeExpiredWhatsAppMedia(params.state);\n const fixture = params.state.mediaByPath.get(url.pathname);\n if (fixture) {\n fixture.expiresAt = Math.min(\n fixture.expiresAt,\n Date.now() + WHATSAPP_MEDIA_DOWNLOAD_GRACE_MS,\n );\n }\n return fixture\n ? new Response(new Uint8Array(fixture.content), {\n headers: { \"content-type\": fixture.mimeType },\n })\n : new Response(\"not found\", { status: 404 });\n }\n\n if (url.pathname === \"/_crabline/admin/whatsapp/inbound\") {\n if (params.request.method !== \"POST\") {\n drainRequestBody(params.request);\n return new Response(\"not found\", { status: 404 });\n }\n if (!hasAdminToken(params.request, params.state.adminToken)) {\n drainRequestBody(params.request);\n return adminAuthError();\n }\n const body = await parseUnknownRequestBody(params.request);\n if (!isJsonObject(body)) {\n return graphParameterError(\n \"(#100) Invalid parameter: request body\",\n \"The request body must be a JSON object.\",\n );\n }\n const result = await handleAdminInbound({ body, state: params.state });\n if (result.response) {\n return result.response;\n }\n const event: WhatsAppRecorderEvent = {\n at: new Date().toISOString(),\n body,\n method: params.request.method,\n path: url.pathname,\n query: queryRecord(url),\n type: \"admin\",\n };\n const preparedDelivery = result.message\n ? params.state.prepareInboundMessage(result.message)\n : undefined;\n if (result.message && !preparedDelivery) {\n result.messageIdReservation?.cancel();\n return graphError({\n code: 4,\n details: \"The pending WhatsApp inbound queue is full.\",\n message: \"(#4) Application request limit reached.\",\n status: 503,\n type: \"OAuthException\",\n });\n }\n if (result.mediaFixture && !reserveWhatsAppMedia(params.state, result.mediaFixture)) {\n preparedDelivery?.cancel();\n result.messageIdReservation?.cancel();\n return graphError({\n code: 4,\n details: \"The WhatsApp media fixture capacity is full.\",\n message: \"(#4) Application request limit reached.\",\n status: 503,\n type: \"OAuthException\",\n });\n }\n if (result.message) {\n event.message = result.message;\n }\n try {\n await appendEvent(params.state, event);\n } catch (error) {\n if (!(error instanceof ServerRecorderCommittedError)) {\n preparedDelivery?.cancel();\n if (result.mediaFixture) {\n removeWhatsAppMedia(params.state, result.mediaFixture.path);\n }\n result.messageIdReservation?.cancel();\n throw error;\n }\n result.messageIdReservation?.commit();\n if (result.message && preparedDelivery) {\n try {\n await preparedDelivery.commit();\n rememberInboundMessageId(params.state, result.message.key.id);\n } catch (deliveryError) {\n const reconciliationError = new AggregateError(\n [error, deliveryError],\n \"WhatsApp recorder append committed, but inbound delivery reconciliation failed.\",\n );\n reconciliationError.cause = deliveryError;\n throw reconciliationError;\n }\n }\n throw error;\n }\n if (result.message && preparedDelivery) {\n try {\n const delivery = await preparedDelivery.commit();\n result.messageIdReservation?.commit();\n rememberInboundMessageId(params.state, result.message.key.id);\n return whatsappOk({ delivery, message: result.message, webhook: result.webhook });\n } catch (error) {\n if (result.mediaFixture) {\n removeWhatsAppMedia(params.state, result.mediaFixture.path);\n }\n result.messageIdReservation?.cancel();\n throw error;\n }\n }\n if (result.mediaFixture) {\n removeWhatsAppMedia(params.state, result.mediaFixture.path);\n }\n result.messageIdReservation?.cancel();\n return graphParameterError(\"(#100) Invalid inbound WhatsApp event\");\n }\n\n const phoneNumberPath = `/${params.state.graphVersion}/${params.state.phoneNumberId}`;\n const messagesPath = `${phoneNumberPath}/messages`;\n if (!requireAuth(params.request, params.state)) {\n drainRequestBody(params.request);\n return graphAuthError();\n }\n if (url.pathname === phoneNumberPath && params.request.method === \"GET\") {\n const body = queryRecord(url);\n await appendEvent(params.state, {\n accepted: true,\n at: new Date().toISOString(),\n body,\n method: params.request.method,\n path: url.pathname,\n query: body,\n type: \"api\",\n });\n return jsonResponse({\n display_phone_number: params.state.displayPhoneNumber,\n id: params.state.phoneNumberId,\n quality_rating: \"GREEN\",\n verified_name: \"Crabline Test Bot\",\n });\n }\n if (url.pathname === messagesPath) {\n if (params.request.method !== \"POST\") {\n drainRequestBody(params.request);\n return new Response(\"not found\", { status: 404 });\n }\n const body = await parseUnknownRequestBody(params.request);\n const event: WhatsAppRecorderEvent = {\n at: new Date().toISOString(),\n body,\n method: params.request.method,\n path: url.pathname,\n query: queryRecord(url),\n type: \"api\",\n };\n let response: Response;\n if (!isJsonObject(body)) {\n response = graphParameterError(\n \"(#100) Invalid parameter: request body\",\n \"The request body must be a JSON object.\",\n );\n } else if (\"status\" in body || \"message_id\" in body) {\n response = handleMessageStatus(params.state, body);\n event.accepted = response.ok;\n } else {\n const prepared = prepareSendMessage({ body, state: params.state });\n if (!(prepared instanceof Response)) {\n response = prepared.commit();\n event.accepted = true;\n await appendEvent(params.state, event);\n return response;\n }\n response = prepared;\n }\n event.accepted ??= false;\n await appendEvent(params.state, event);\n return response;\n }\n drainRequestBody(params.request);\n return new Response(\"not found\", { status: 404 });\n}\n\nexport async function startWhatsAppServer(\n params: StartWhatsAppServerParams = {},\n): Promise<StartedWhatsAppServer> {\n const host = params.host ?? \"127.0.0.1\";\n if (!isLoopbackHost(host)) {\n throw new Error(\n \"WhatsApp server requires a loopback host because its HTTP and WebSocket endpoints carry credentials over cleartext.\",\n );\n }\n if (\n params.accessToken !== undefined &&\n (!params.accessToken.trim() || params.accessToken !== params.accessToken.trim())\n ) {\n throw new Error(\"WhatsApp accessToken must not be empty or whitespace-padded.\");\n }\n if (\n params.adminToken !== undefined &&\n (!params.adminToken.trim() || params.adminToken !== params.adminToken.trim())\n ) {\n throw new Error(\"WhatsApp adminToken must not be empty or whitespace-padded.\");\n }\n const graphVersion = params.graphVersion ?? DEFAULT_GRAPH_VERSION;\n if (!WHATSAPP_GRAPH_VERSION_RE.test(graphVersion)) {\n throw new Error(`Invalid WhatsApp Graph API version: ${graphVersion}.`);\n }\n const phoneNumberId = params.phoneNumberId ?? \"100000000000000\";\n if (!/^\\d+$/u.test(phoneNumberId)) {\n throw new Error(\"WhatsApp phoneNumberId must contain only digits.\");\n }\n const maxPendingInboundMessages = resolveMaxPendingWhatsAppInboundMessages(\n params.maxPendingInboundMessages,\n );\n const selfJid = canonicalizeWhatsAppUserJid(params.selfJid ?? \"15550000000@s.whatsapp.net\");\n if (!selfJid) {\n throw new Error(\"WhatsApp selfJid must be a WhatsApp user JID.\");\n }\n const recorderPath =\n params.recorderPath ?? path.resolve(\".crabline\", \"servers\", \"whatsapp.jsonl\");\n const state: WhatsAppServerState = {\n accessToken: params.accessToken ?? createDefaultAccessToken(),\n adminToken: params.adminToken ?? randomBytes(24).toString(\"hex\"),\n baseUrl: \"\",\n prepareInboundMessage: () => undefined,\n displayPhoneNumber: params.displayPhoneNumber ?? \"15550000000\",\n graphVersion,\n inboundMessageIds: new Set(),\n mediaByPath: new Map(),\n mediaBytes: 0,\n pendingMessageIds: new Set(),\n recentMessageIds: new Map(),\n nextMessageId: 1n,\n recorder: createServerRecorder({ recorderPath, onEvent: params.onEvent }),\n phoneNumberId,\n recorderPath,\n selfJid,\n };\n const httpServer = await startHttpJsonServer({\n handle: (request) => handleRequest({ request, state }),\n handleError: (error) => {\n if (error instanceof InvalidJsonBodyError) {\n return graphParameterError(\n \"(#100) Invalid parameter: request body\",\n \"The request body must be valid JSON.\",\n );\n }\n if (error instanceof RequestBodyTooLargeError) {\n return graphError({\n code: 100,\n details: \"The request body exceeds the supported size limit.\",\n message: \"(#100) Request body is too large.\",\n status: 413,\n });\n }\n return undefined;\n },\n host,\n port: params.port ?? 0,\n serverName: \"WhatsApp\",\n });\n const baseUrl = httpServer.baseUrl;\n state.baseUrl = baseUrl;\n const apiRoot = `${baseUrl}/${state.graphVersion}`;\n const phoneNumberUrl = `${apiRoot}/${state.phoneNumberId}`;\n const messagesUrl = `${phoneNumberUrl}/messages`;\n const baileysWebSocketUrl = `${baseUrl.replace(\n /^http/u,\n \"ws\",\n )}/ws/chat?access_token=${encodeURIComponent(state.accessToken)}`;\n const baileysWebSocketOptions = {\n accessToken: state.accessToken,\n appendEvent: (event: ServerRequestEvent) => appendEvent(state, event),\n httpServer: httpServer.server,\n maxPendingInboundMessages,\n messageAcceptanceTimeoutMs: params.messageAcceptanceTimeoutMs,\n path: \"/ws/chat\",\n selfJid: state.selfJid,\n };\n let baileysWebSocketServer;\n try {\n baileysWebSocketServer = attachWhatsAppBaileysWebSocketServer(baileysWebSocketOptions);\n } catch (error) {\n try {\n await httpServer.close();\n } catch (closeError) {\n const aggregateError = new AggregateError(\n [error, closeError],\n \"WhatsApp WebSocket startup failed and HTTP rollback also failed.\",\n );\n aggregateError.cause = error;\n throw aggregateError;\n }\n throw error;\n }\n state.prepareInboundMessage = (message) => baileysWebSocketServer.prepareInboundMessage(message);\n return {\n close: createServerClose(\n state.recorder,\n async () => {\n try {\n await baileysWebSocketServer.close();\n } finally {\n state.mediaByPath.clear();\n state.mediaBytes = 0;\n }\n },\n () => httpServer.close(),\n ),\n manifest: {\n accessToken: state.accessToken,\n adminToken: state.adminToken,\n baseUrl,\n endpoints: {\n adminInboundUrl: `${baseUrl}/_crabline/admin/whatsapp/inbound`,\n apiRoot,\n baileysWebSocketUrl,\n messagesUrl,\n phoneNumberUrl,\n },\n env: {\n CLOUD_API_ACCESS_TOKEN: state.accessToken,\n CLOUD_API_VERSION: state.graphVersion,\n WA_BASE_URL: baseUrl,\n WA_PHONE_NUMBER_ID: state.phoneNumberId,\n },\n graphVersion: state.graphVersion,\n phoneNumberId: state.phoneNumberId,\n provider: \"whatsapp\",\n recorderPath: state.recorderPath,\n selfJid: state.selfJid,\n version: 1,\n },\n };\n}\n\nfunction readMessageText(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value : undefined;\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  import { randomBytes } from "node:crypto";
2
2
  import { validateHeaderValue, } from "node:http";
3
3
  import path from "node:path";
4
- import { adminAuthError, drainRequestBody, hasAdminToken, InvalidJsonBodyError, isJsonObject, isLoopbackHost, jsonResponse, parseUnknownRequestBody, queryRecord, readTrimmedString, RequestBodyTooLargeError, startHttpJsonServer, } from "./http.js";
5
- import { recordServerEvent } from "./recorder.js";
4
+ import { adminAuthError, createServerClose, drainRequestBody, hasAdminToken, InvalidJsonBodyError, isJsonObject, isLoopbackHost, jsonResponse, parseUnknownRequestBody, queryRecord, readTrimmedString, RequestBodyTooLargeError, startHttpJsonServer, } from "./http.js";
5
+ import { createServerRecorder } from "./recorder.js";
6
6
  import { resolveMaxPendingInboundEvents } from "./pending-events.js";
7
7
  import { postWebhookRequest, validateWebhookTarget, } from "./webhook-target.js";
8
8
  const DEFAULT_WEBHOOK_DELIVERY_TIMEOUT_MS = 5_000;
@@ -12,7 +12,7 @@ const MAX_ZALO_REDACTION_DEPTH = 32;
12
12
  const MAX_WEBHOOK_DELIVERY_TIMEOUT_MS = 30_000;
13
13
  const MAX_ZALO_WEBHOOK_SECRET_BYTES = 256;
14
14
  async function appendEvent(state, event) {
15
- await recordServerEvent({ event, onEvent: state.onEvent, recorderPath: state.recorderPath });
15
+ await state.recorder.record(event);
16
16
  }
17
17
  function zaloOk(result) {
18
18
  return jsonResponse(result === undefined ? { ok: true } : { ok: true, result });
@@ -724,6 +724,7 @@ async function handleZaloMethod(request, response, state, url, method) {
724
724
  }
725
725
  export async function startZaloServer(params = {}) {
726
726
  const host = params.host ?? "127.0.0.1";
727
+ const recorderPath = params.recorderPath ?? path.resolve(".crabline", "servers", "zalo.jsonl");
727
728
  const state = {
728
729
  activeWebhookRequests: new Set(),
729
730
  activeWebhookValidations: new Set(),
@@ -739,10 +740,10 @@ export async function startZaloServer(params = {}) {
739
740
  maxPendingInboundEvents: resolveMaxPendingInboundEvents(params.maxPendingInboundEvents),
740
741
  nextMessage: 1,
741
742
  nextUpdateOrder: 1,
742
- onEvent: params.onEvent,
743
+ recorder: createServerRecorder({ recorderPath, onEvent: params.onEvent }),
743
744
  pendingInboundAdmissions: 0,
744
745
  pendingRequest: undefined,
745
- recorderPath: params.recorderPath ?? path.resolve(".crabline", "servers", "zalo.jsonl"),
746
+ recorderPath,
746
747
  retainedUpdateBytes: 0,
747
748
  retainedUpdateCount: 0,
748
749
  reservedUpdateOrders: new Set(),
@@ -801,7 +802,7 @@ export async function startZaloServer(params = {}) {
801
802
  version: 1,
802
803
  };
803
804
  return {
804
- async close() {
805
+ close: createServerClose(state.recorder, async () => {
805
806
  state.closing = true;
806
807
  for (const request of state.activeWebhookRequests) {
807
808
  request.destroy(new Error("Zalo server is shutting down."));
@@ -813,7 +814,7 @@ export async function startZaloServer(params = {}) {
813
814
  settlePendingUpdate(state, state.pendingRequest, { kind: "shutdown" });
814
815
  }
815
816
  await httpServer.close();
816
- },
817
+ }),
817
818
  manifest,
818
819
  };
819
820
  }