@openclaw/crabline 0.1.9 → 0.1.10

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 (189) hide show
  1. package/README.md +47 -22
  2. package/assets/crabline-banner.svg +20 -0
  3. package/dist/src/bin/crabline.js.map +1 -1
  4. package/dist/src/cli/program.d.ts +25 -1
  5. package/dist/src/cli/program.js +579 -82
  6. package/dist/src/cli/program.js.map +1 -1
  7. package/dist/src/config/load.js +59 -6
  8. package/dist/src/config/load.js.map +1 -1
  9. package/dist/src/config/schema.d.ts +116 -92
  10. package/dist/src/config/schema.js +179 -73
  11. package/dist/src/config/schema.js.map +1 -1
  12. package/dist/src/core/errors.js +9 -2
  13. package/dist/src/core/errors.js.map +1 -1
  14. package/dist/src/core/exit-codes.js.map +1 -1
  15. package/dist/src/core/matcher.js +7 -6
  16. package/dist/src/core/matcher.js.map +1 -1
  17. package/dist/src/core/message-template.js.map +1 -1
  18. package/dist/src/core/nonces.d.ts +1 -0
  19. package/dist/src/core/nonces.js +4 -2
  20. package/dist/src/core/nonces.js.map +1 -1
  21. package/dist/src/core/reporters.d.ts +1 -0
  22. package/dist/src/core/reporters.js +42 -4
  23. package/dist/src/core/reporters.js.map +1 -1
  24. package/dist/src/core/run.d.ts +3 -0
  25. package/dist/src/core/run.js +415 -107
  26. package/dist/src/core/run.js.map +1 -1
  27. package/dist/src/core/safe-regex.d.ts +3 -0
  28. package/dist/src/core/safe-regex.js +21 -0
  29. package/dist/src/core/safe-regex.js.map +1 -0
  30. package/dist/src/index.d.ts +2 -2
  31. package/dist/src/index.js +1 -1
  32. package/dist/src/index.js.map +1 -1
  33. package/dist/src/openclaw/artifact-generation.d.ts +38 -0
  34. package/dist/src/openclaw/artifact-generation.js +314 -0
  35. package/dist/src/openclaw/artifact-generation.js.map +1 -0
  36. package/dist/src/openclaw/bridges/matrix.js +97 -12
  37. package/dist/src/openclaw/bridges/matrix.js.map +1 -1
  38. package/dist/src/openclaw/bridges/mattermost.js +32 -10
  39. package/dist/src/openclaw/bridges/mattermost.js.map +1 -1
  40. package/dist/src/openclaw/bridges/signal.js +55 -18
  41. package/dist/src/openclaw/bridges/signal.js.map +1 -1
  42. package/dist/src/openclaw/bridges/slack.js +85 -7
  43. package/dist/src/openclaw/bridges/slack.js.map +1 -1
  44. package/dist/src/openclaw/bridges/telegram.js +124 -30
  45. package/dist/src/openclaw/bridges/telegram.js.map +1 -1
  46. package/dist/src/openclaw/bridges/whatsapp.js +78 -17
  47. package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
  48. package/dist/src/openclaw/bridges/zalo.js +14 -5
  49. package/dist/src/openclaw/bridges/zalo.js.map +1 -1
  50. package/dist/src/openclaw/outbound-contract.d.ts +5 -0
  51. package/dist/src/openclaw/outbound-contract.js +40 -0
  52. package/dist/src/openclaw/outbound-contract.js.map +1 -0
  53. package/dist/src/openclaw/private-file.d.ts +26 -0
  54. package/dist/src/openclaw/private-file.js +411 -0
  55. package/dist/src/openclaw/private-file.js.map +1 -0
  56. package/dist/src/openclaw/shared.d.ts +21 -2
  57. package/dist/src/openclaw/shared.js +115 -18
  58. package/dist/src/openclaw/shared.js.map +1 -1
  59. package/dist/src/openclaw/smoke-lock.d.ts +63 -0
  60. package/dist/src/openclaw/smoke-lock.js +949 -0
  61. package/dist/src/openclaw/smoke-lock.js.map +1 -0
  62. package/dist/src/openclaw.d.ts +16 -8
  63. package/dist/src/openclaw.js +194 -52
  64. package/dist/src/openclaw.js.map +1 -1
  65. package/dist/src/providers/builtin/discord.d.ts +10 -1
  66. package/dist/src/providers/builtin/discord.js +144 -18
  67. package/dist/src/providers/builtin/discord.js.map +1 -1
  68. package/dist/src/providers/builtin/external-webhook-auth.d.ts +11 -0
  69. package/dist/src/providers/builtin/external-webhook-auth.js +10 -0
  70. package/dist/src/providers/builtin/external-webhook-auth.js.map +1 -0
  71. package/dist/src/providers/builtin/feishu.d.ts +19 -2
  72. package/dist/src/providers/builtin/feishu.js +307 -25
  73. package/dist/src/providers/builtin/feishu.js.map +1 -1
  74. package/dist/src/providers/builtin/googlechat.d.ts +20 -1
  75. package/dist/src/providers/builtin/googlechat.js +178 -19
  76. package/dist/src/providers/builtin/googlechat.js.map +1 -1
  77. package/dist/src/providers/builtin/imessage.d.ts +4 -0
  78. package/dist/src/providers/builtin/imessage.js +26 -11
  79. package/dist/src/providers/builtin/imessage.js.map +1 -1
  80. package/dist/src/providers/builtin/loopback.js +92 -30
  81. package/dist/src/providers/builtin/loopback.js.map +1 -1
  82. package/dist/src/providers/builtin/matrix.d.ts +11 -1
  83. package/dist/src/providers/builtin/matrix.js +53 -29
  84. package/dist/src/providers/builtin/matrix.js.map +1 -1
  85. package/dist/src/providers/builtin/mattermost.d.ts +10 -0
  86. package/dist/src/providers/builtin/mattermost.js +38 -15
  87. package/dist/src/providers/builtin/mattermost.js.map +1 -1
  88. package/dist/src/providers/builtin/msteams.d.ts +17 -1
  89. package/dist/src/providers/builtin/msteams.js +113 -14
  90. package/dist/src/providers/builtin/msteams.js.map +1 -1
  91. package/dist/src/providers/builtin/native-local-mock.d.ts +2 -9
  92. package/dist/src/providers/builtin/native-local-mock.js +12 -35
  93. package/dist/src/providers/builtin/native-local-mock.js.map +1 -1
  94. package/dist/src/providers/builtin/script.d.ts +11 -15
  95. package/dist/src/providers/builtin/script.js +566 -104
  96. package/dist/src/providers/builtin/script.js.map +1 -1
  97. package/dist/src/providers/builtin/slack.d.ts +6 -0
  98. package/dist/src/providers/builtin/slack.js +99 -40
  99. package/dist/src/providers/builtin/slack.js.map +1 -1
  100. package/dist/src/providers/builtin/telegram.d.ts +6 -0
  101. package/dist/src/providers/builtin/telegram.js +64 -43
  102. package/dist/src/providers/builtin/telegram.js.map +1 -1
  103. package/dist/src/providers/builtin/whatsapp.d.ts +28 -8
  104. package/dist/src/providers/builtin/whatsapp.js +567 -30
  105. package/dist/src/providers/builtin/whatsapp.js.map +1 -1
  106. package/dist/src/providers/builtin/zalo.js +30 -19
  107. package/dist/src/providers/builtin/zalo.js.map +1 -1
  108. package/dist/src/providers/catalog.d.ts +3 -3
  109. package/dist/src/providers/catalog.js +3 -3
  110. package/dist/src/providers/catalog.js.map +1 -1
  111. package/dist/src/providers/local-mock.d.ts +11 -2
  112. package/dist/src/providers/local-mock.js +322 -96
  113. package/dist/src/providers/local-mock.js.map +1 -1
  114. package/dist/src/providers/native-ids.d.ts +1 -0
  115. package/dist/src/providers/native-ids.js +6 -1
  116. package/dist/src/providers/native-ids.js.map +1 -1
  117. package/dist/src/providers/recorder.d.ts +30 -2
  118. package/dist/src/providers/recorder.js +539 -70
  119. package/dist/src/providers/recorder.js.map +1 -1
  120. package/dist/src/providers/registry.d.ts +25 -1
  121. package/dist/src/providers/registry.js +280 -40
  122. package/dist/src/providers/registry.js.map +1 -1
  123. package/dist/src/providers/signed-jwt.d.ts +29 -0
  124. package/dist/src/providers/signed-jwt.js +202 -0
  125. package/dist/src/providers/signed-jwt.js.map +1 -0
  126. package/dist/src/providers/slack-ids.js.map +1 -1
  127. package/dist/src/providers/target-normalizers.d.ts +26 -0
  128. package/dist/src/providers/target-normalizers.js +276 -0
  129. package/dist/src/providers/target-normalizers.js.map +1 -0
  130. package/dist/src/providers/types.d.ts +5 -0
  131. package/dist/src/providers/types.js.map +1 -1
  132. package/dist/src/providers/webhook-server.d.ts +2 -0
  133. package/dist/src/providers/webhook-server.js +72 -25
  134. package/dist/src/providers/webhook-server.js.map +1 -1
  135. package/dist/src/servers/http.d.ts +23 -3
  136. package/dist/src/servers/http.js +213 -20
  137. package/dist/src/servers/http.js.map +1 -1
  138. package/dist/src/servers/index.js +20 -21
  139. package/dist/src/servers/index.js.map +1 -1
  140. package/dist/src/servers/matrix.js +465 -51
  141. package/dist/src/servers/matrix.js.map +1 -1
  142. package/dist/src/servers/mattermost.d.ts +5 -0
  143. package/dist/src/servers/mattermost.js +306 -58
  144. package/dist/src/servers/mattermost.js.map +1 -1
  145. package/dist/src/servers/pending-events.d.ts +2 -0
  146. package/dist/src/servers/pending-events.js +11 -0
  147. package/dist/src/servers/pending-events.js.map +1 -0
  148. package/dist/src/servers/recorder.d.ts +5 -0
  149. package/dist/src/servers/recorder.js +46 -3
  150. package/dist/src/servers/recorder.js.map +1 -1
  151. package/dist/src/servers/signal.d.ts +2 -0
  152. package/dist/src/servers/signal.js +444 -56
  153. package/dist/src/servers/signal.js.map +1 -1
  154. package/dist/src/servers/slack.d.ts +5 -0
  155. package/dist/src/servers/slack.js +515 -49
  156. package/dist/src/servers/slack.js.map +1 -1
  157. package/dist/src/servers/telegram.d.ts +111 -0
  158. package/dist/src/servers/telegram.js +811 -152
  159. package/dist/src/servers/telegram.js.map +1 -1
  160. package/dist/src/servers/webhook-target.d.ts +40 -0
  161. package/dist/src/servers/webhook-target.js +349 -0
  162. package/dist/src/servers/webhook-target.js.map +1 -0
  163. package/dist/src/servers/websocket.d.ts +2 -0
  164. package/dist/src/servers/websocket.js +29 -0
  165. package/dist/src/servers/websocket.js.map +1 -0
  166. package/dist/src/servers/whatsapp-baileys-websocket.d.ts +65 -1
  167. package/dist/src/servers/whatsapp-baileys-websocket.js +723 -99
  168. package/dist/src/servers/whatsapp-baileys-websocket.js.map +1 -1
  169. package/dist/src/servers/whatsapp-jid.d.ts +5 -0
  170. package/dist/src/servers/whatsapp-jid.js +32 -0
  171. package/dist/src/servers/whatsapp-jid.js.map +1 -0
  172. package/dist/src/servers/whatsapp-wire/binary-node.d.ts +5 -0
  173. package/dist/src/servers/whatsapp-wire/binary-node.js +87 -20
  174. package/dist/src/servers/whatsapp-wire/binary-node.js.map +1 -1
  175. package/dist/src/servers/whatsapp-wire/crypto.d.ts +6 -1
  176. package/dist/src/servers/whatsapp-wire/crypto.js +99 -45
  177. package/dist/src/servers/whatsapp-wire/crypto.js.map +1 -1
  178. package/dist/src/servers/whatsapp-wire/handshake.js +39 -4
  179. package/dist/src/servers/whatsapp-wire/handshake.js.map +1 -1
  180. package/dist/src/servers/whatsapp-wire/signal.js.map +1 -1
  181. package/dist/src/servers/whatsapp.d.ts +12 -7
  182. package/dist/src/servers/whatsapp.js +269 -107
  183. package/dist/src/servers/whatsapp.js.map +1 -1
  184. package/dist/src/servers/zalo.d.ts +14 -0
  185. package/dist/src/servers/zalo.js +521 -88
  186. package/dist/src/servers/zalo.js.map +1 -1
  187. package/docs/channel-setup.md +197 -19
  188. package/fixtures/examples/crabline.example.yaml +10 -0
  189. package/package.json +20 -15
@@ -1 +1 @@
1
- {"version":3,"file":"zalo.js","sourceRoot":"","sources":["../../../src/servers/zalo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"zalo.js","sourceRoot":"","sources":["../../../src/servers/zalo.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport {\n validateHeaderValue,\n type ClientRequest,\n type IncomingMessage,\n type ServerResponse,\n} from \"node:http\";\nimport path from \"node:path\";\nimport {\n adminAuthError,\n drainRequestBody,\n hasAdminToken,\n InvalidJsonBodyError,\n isJsonObject,\n isLoopbackHost,\n jsonResponse,\n parseUnknownRequestBody,\n queryRecord,\n readTrimmedString,\n RequestBodyTooLargeError,\n startHttpJsonServer,\n type HttpJsonHandlerResult,\n type ServerRequestEvent,\n} from \"./http.js\";\nimport { recordServerEvent, type ServerEventObserver } from \"./recorder.js\";\nimport { resolveMaxPendingInboundEvents } from \"./pending-events.js\";\nimport {\n postWebhookRequest,\n validateWebhookTarget,\n type WebhookAddress,\n} from \"./webhook-target.js\";\n\ntype ZaloChatType = \"GROUP\" | \"PRIVATE\";\n\nconst DEFAULT_WEBHOOK_DELIVERY_TIMEOUT_MS = 5_000;\nconst MAX_ACTIVE_ZALO_WEBHOOK_VALIDATIONS = 8;\nconst MAX_WEBHOOK_DELIVERY_TIMEOUT_MS = 30_000;\nconst MAX_ZALO_WEBHOOK_SECRET_BYTES = 256;\n\ntype ZaloServerEvent = ServerRequestEvent & {\n accepted?: boolean | undefined;\n};\n\ntype ZaloMessage = {\n chat: { chat_type: ZaloChatType; id: string };\n date: number;\n from: { display_name: string; id: string; is_bot: boolean };\n message_id: string;\n photo_url?: string;\n text?: string;\n};\n\ntype ZaloUpdate = {\n event_name: \"message.image.received\" | \"message.text.received\";\n message: ZaloMessage;\n};\n\ntype PendingUpdateResult =\n | { kind: \"conflict\" | \"disconnect\" | \"shutdown\" | \"timeout\" }\n | { kind: \"update\"; update: ZaloUpdate };\n\ntype PendingUpdateRequest = {\n active: boolean;\n onDisconnect(): void;\n request: IncomingMessage;\n response: ServerResponse;\n resolve(result: PendingUpdateResult): void;\n timeout: NodeJS.Timeout | undefined;\n};\n\ntype ZaloValidatedWebhookTarget = {\n addresses: WebhookAddress[] | undefined;\n};\n\ntype ZaloServerState = {\n activeWebhookRequests: Set<ClientRequest>;\n activeWebhookValidations: Set<AbortController>;\n adminToken: string;\n allowLoopbackHttpWebhook: boolean;\n botId: string;\n botName: string;\n botToken: string;\n closing: boolean;\n failedUpdateOrders: Set<number>;\n inboundAdmission: Promise<void>;\n maxPendingInboundEvents: number;\n nextMessage: number;\n nextUpdateOrder: number;\n onEvent: ServerEventObserver | undefined;\n pendingRequest: PendingUpdateRequest | undefined;\n recorderPath: string;\n reservedUpdateOrders: Set<number>;\n restrictWebhookTargets: boolean;\n updateOrders: WeakMap<ZaloUpdate, number>;\n updates: ZaloUpdate[];\n webhook: { secretToken: string; updatedAt: number; url: string } | undefined;\n webhookDeliveryTimeoutMs: number;\n};\n\nexport type ZaloServerManifest = {\n adminToken: string;\n baseUrl: string;\n botId: string;\n botToken: string;\n endpoints: {\n adminInboundUrl: string;\n apiRoot: string;\n };\n env: {\n ZALO_API_URL: string;\n ZALO_BOT_TOKEN: string;\n };\n provider: \"zalo\";\n recorderPath: string;\n version: 1;\n};\n\nexport type StartedZaloServer = {\n close(): Promise<void>;\n manifest: ZaloServerManifest;\n};\n\nexport type StartZaloServerParams = {\n adminToken?: string | undefined;\n botId?: string | undefined;\n botName?: string | undefined;\n botToken?: string | undefined;\n host?: string | undefined;\n onEvent?: ServerEventObserver | undefined;\n port?: number | undefined;\n recorderPath?: string | undefined;\n maxPendingInboundEvents?: number | undefined;\n webhookDeliveryTimeoutMs?: number | undefined;\n};\n\nasync function appendEvent(state: ZaloServerState, event: ZaloServerEvent): Promise<void> {\n await recordServerEvent({ event, onEvent: state.onEvent, recorderPath: state.recorderPath });\n}\n\nfunction zaloOk(result?: unknown): Response {\n return jsonResponse(result === undefined ? { ok: true } : { ok: true, result });\n}\n\nfunction zaloError(description: string, status: number): Response {\n return jsonResponse({ description, error_code: status, ok: false }, status);\n}\n\nfunction messageId(state: ZaloServerState): string {\n return `${Date.now().toString(16)}${(state.nextMessage++).toString(16).padStart(6, \"0\")}`;\n}\n\nfunction readChatType(value: unknown): ZaloChatType {\n return readTrimmedString(value)?.toUpperCase() === \"GROUP\" ? \"GROUP\" : \"PRIVATE\";\n}\n\nfunction requestParams(url: URL, body: Record<string, unknown>): Record<string, unknown> {\n return { ...Object.fromEntries(url.searchParams.entries()), ...body };\n}\n\nconst SENSITIVE_PARAM_NAMES = new Set([\n \"accesskey\",\n \"accesstoken\",\n \"apikey\",\n \"auth\",\n \"authorization\",\n \"authtoken\",\n \"bearertoken\",\n \"clientsecret\",\n \"consumersecret\",\n \"credential\",\n \"credentials\",\n \"idtoken\",\n \"key\",\n \"oauthtoken\",\n \"password\",\n \"passwd\",\n \"privatekey\",\n \"refreshtoken\",\n \"secret\",\n \"secretkey\",\n \"secrettoken\",\n \"sessiontoken\",\n \"signature\",\n \"signingsecret\",\n \"token\",\n \"webhooksecret\",\n]);\n\nfunction isSensitiveParam(name: string): boolean {\n const canonicalName = name\n .normalize(\"NFKC\")\n .replace(/[^A-Za-z0-9]/gu, \"\")\n .toLowerCase();\n return (\n SENSITIVE_PARAM_NAMES.has(canonicalName) ||\n /(?:^|[_-])(?:access[_-]?token|api[_-]?key|authorization|key|password|secret|signature|token)(?:$|[_-])/iu.test(\n name,\n )\n );\n}\n\nfunction redactParams(params: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(params).map(([key, value]) => [\n key,\n isSensitiveParam(key)\n ? \"<redacted>\"\n : key === \"url\" && typeof value === \"string\"\n ? redactUrlCredentials(value)\n : value,\n ]),\n );\n}\n\nfunction redactSensitiveSearchParams(searchParams: URLSearchParams): boolean {\n let redacted = false;\n for (const key of searchParams.keys()) {\n if (isSensitiveParam(key)) {\n searchParams.set(key, \"<redacted>\");\n redacted = true;\n }\n }\n return redacted;\n}\n\nfunction redactMalformedUrlCredentials(value: string): string {\n const credentialRedacted = value.replace(\n /^(\\s*)((?:[a-z][a-z0-9+.-]*:)?\\/\\/)[^/?#]*@/iu,\n \"$1$2<redacted>@\",\n );\n const queryStart = credentialRedacted.indexOf(\"?\");\n const fragmentStart = credentialRedacted.indexOf(\"#\", queryStart + 1);\n if (queryStart < 0 || (fragmentStart >= 0 && fragmentStart < queryStart)) {\n return credentialRedacted;\n }\n const queryEnd = fragmentStart >= 0 ? fragmentStart : credentialRedacted.length;\n const searchParams = new URLSearchParams(credentialRedacted.slice(queryStart + 1, queryEnd));\n if (!redactSensitiveSearchParams(searchParams)) {\n return credentialRedacted;\n }\n const search = searchParams.toString().replaceAll(\"%3Credacted%3E\", \"<redacted>\");\n return `${credentialRedacted.slice(0, queryStart)}?${search}${credentialRedacted.slice(queryEnd)}`;\n}\n\nfunction redactUrlCredentials(value: string): string {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n return redactMalformedUrlCredentials(value);\n }\n const hasCredentials = Boolean(url.username || url.password);\n const redactedQuery = redactSensitiveSearchParams(url.searchParams);\n if (!hasCredentials && !redactedQuery) {\n return value;\n }\n const search = url.search.replaceAll(\"%3Credacted%3E\", \"<redacted>\");\n return `${url.protocol}//${hasCredentials ? \"<redacted>@\" : \"\"}${url.host}${url.pathname}${search}${url.hash}`;\n}\n\nfunction requireParam(body: Record<string, unknown>, name: string): string | Response {\n return readTrimmedString(body[name]) ?? zaloError(`${name} is required`, 400);\n}\n\nfunction firstError(...values: Array<string | Response>): Response | undefined {\n return values.find((value): value is Response => value instanceof Response);\n}\n\nfunction webhookDeliveryTimeoutMs(value: number | undefined): number {\n if (value === undefined || !Number.isFinite(value)) {\n return DEFAULT_WEBHOOK_DELIVERY_TIMEOUT_MS;\n }\n return Math.max(1, Math.min(Math.floor(value), MAX_WEBHOOK_DELIVERY_TIMEOUT_MS));\n}\n\nasync function validateWebhookUrl(\n url: URL,\n state: Pick<ZaloServerState, \"allowLoopbackHttpWebhook\" | \"restrictWebhookTargets\">,\n signal?: AbortSignal,\n): Promise<Response | ZaloValidatedWebhookTarget> {\n const target = await validateWebhookTarget({\n allowLoopbackHttp: state.allowLoopbackHttpWebhook,\n restrictPrivateAddresses: state.restrictWebhookTargets,\n signal,\n url,\n });\n if (\"error\" in target) {\n return target.error === \"unresolvable\"\n ? zaloError(\"url host could not be resolved\", 400)\n : target.error === \"private-address\"\n ? zaloError(\"url must not target a private or link-local address\", 400)\n : zaloError(\"url must use HTTPS\", 400);\n }\n return target;\n}\n\nfunction validateZaloWebhookSecret(secretToken: string): Response | undefined {\n if (Buffer.byteLength(secretToken) > MAX_ZALO_WEBHOOK_SECRET_BYTES) {\n return zaloError(`secret_token must not exceed ${MAX_ZALO_WEBHOOK_SECRET_BYTES} bytes`, 400);\n }\n try {\n validateHeaderValue(\"x-bot-api-secret-token\", secretToken);\n } catch {\n return zaloError(\"secret_token contains invalid HTTP header characters\", 400);\n }\n return undefined;\n}\n\nasync function validateWebhookUrlWithDeadline(\n url: URL,\n state: ZaloServerState,\n deadlineAt: number,\n): Promise<Response | ZaloValidatedWebhookTarget> {\n const remainingMs = deadlineAt - Date.now();\n if (remainingMs <= 0) {\n throw webhookTimeoutError(state.webhookDeliveryTimeoutMs);\n }\n const validation = new AbortController();\n state.activeWebhookValidations.add(validation);\n const timer = setTimeout(\n () => validation.abort(webhookTimeoutError(state.webhookDeliveryTimeoutMs)),\n remainingMs,\n );\n timer.unref();\n try {\n return await validateWebhookUrl(url, state, validation.signal);\n } finally {\n clearTimeout(timer);\n state.activeWebhookValidations.delete(validation);\n }\n}\n\nfunction webhookTimeoutError(timeoutMs: number): DOMException {\n return new DOMException(`Webhook delivery timed out after ${timeoutMs}ms`, \"TimeoutError\");\n}\n\n/** @internal */\nexport async function postZaloWebhook(params: {\n activeRequests?: Set<ClientRequest>;\n addresses?: WebhookAddress[] | undefined;\n body: string;\n shouldCancel?: (() => boolean) | undefined;\n timeoutMs: number;\n url: URL;\n verificationValue: string;\n}): Promise<number> {\n const activeRequests = params.activeRequests ?? new Set<ClientRequest>();\n const deadlineAt = Date.now() + params.timeoutMs;\n const addresses =\n params.addresses && params.addresses.length > 0 ? params.addresses : [undefined];\n let lastError: unknown;\n for (const [index, address] of addresses.entries()) {\n if (params.shouldCancel?.()) {\n throw new Error(\"Webhook delivery cancelled.\");\n }\n const remainingMs = deadlineAt - Date.now();\n if (remainingMs <= 0) {\n throw webhookTimeoutError(params.timeoutMs);\n }\n const attemptsRemaining = addresses.length - index;\n const attemptTimeoutMs = Math.max(1, Math.floor(remainingMs / attemptsRemaining));\n try {\n return await postWebhookRequest({\n activeRequests,\n address,\n body: params.body,\n headerEntries: [[\"x-bot-api-secret-token\", params.verificationValue]],\n timeoutMs: attemptTimeoutMs,\n url: params.url,\n });\n } catch (error) {\n if (params.shouldCancel?.()) {\n throw error;\n }\n lastError = error;\n if (\n error instanceof DOMException &&\n error.name === \"TimeoutError\" &&\n attemptsRemaining === 1\n ) {\n throw webhookTimeoutError(params.timeoutMs);\n }\n }\n }\n throw lastError;\n}\n\nfunction nextUpdate(\n request: IncomingMessage,\n response: ServerResponse,\n state: ZaloServerState,\n): HttpJsonHandlerResult | undefined {\n if (request.aborted || request.socket.destroyed || response.destroyed) {\n return undefined;\n }\n const update = state.updates[0];\n if (!update) {\n return undefined;\n }\n const order = pollingUpdateOrder(state, update);\n if (\n state.failedUpdateOrders.has(order) &&\n [...state.reservedUpdateOrders].some((reservedOrder) => reservedOrder < order)\n ) {\n return undefined;\n }\n state.updates.shift();\n reservePollingUpdate(state, update);\n return reservedUpdateResponse(state, update);\n}\n\nfunction pollingUpdateOrder(state: ZaloServerState, update: ZaloUpdate): number {\n const existing = state.updateOrders.get(update);\n if (existing !== undefined) {\n return existing;\n }\n const order = state.nextUpdateOrder++;\n state.updateOrders.set(update, order);\n return order;\n}\n\nfunction queuePollingUpdate(state: ZaloServerState, update: ZaloUpdate): void {\n const order = pollingUpdateOrder(state, update);\n const insertionIndex = state.updates.findIndex(\n (queued) => pollingUpdateOrder(state, queued) > order,\n );\n if (insertionIndex < 0) {\n state.updates.push(update);\n } else {\n state.updates.splice(insertionIndex, 0, update);\n }\n}\n\nfunction reservePollingUpdate(state: ZaloServerState, update: ZaloUpdate): void {\n const order = pollingUpdateOrder(state, update);\n state.failedUpdateOrders.delete(order);\n state.reservedUpdateOrders.add(order);\n}\n\nfunction flushPendingPollingUpdate(state: ZaloServerState): void {\n const pending = state.pendingRequest;\n const update = state.updates[0];\n if (!pending || !update) {\n return;\n }\n if (!isPendingUpdateRequestLive(pending)) {\n settlePendingUpdate(state, pending, { kind: \"disconnect\" });\n return;\n }\n const order = pollingUpdateOrder(state, update);\n if (\n state.failedUpdateOrders.has(order) &&\n [...state.reservedUpdateOrders].some((reservedOrder) => reservedOrder < order)\n ) {\n return;\n }\n state.updates.shift();\n reservePollingUpdate(state, update);\n settlePendingUpdate(state, pending, { kind: \"update\", update });\n}\n\nfunction reservedUpdateResponse(state: ZaloServerState, update: ZaloUpdate): HttpJsonHandlerResult {\n let settled = false;\n const release = () => {\n if (settled) {\n return false;\n }\n settled = true;\n state.reservedUpdateOrders.delete(pollingUpdateOrder(state, update));\n return true;\n };\n return {\n onWriteFailure() {\n if (!release()) {\n return;\n }\n state.failedUpdateOrders.add(pollingUpdateOrder(state, update));\n queuePollingUpdate(state, update);\n flushPendingPollingUpdate(state);\n },\n onWriteSuccess() {\n if (release()) {\n flushPendingPollingUpdate(state);\n }\n },\n response: zaloOk(update),\n };\n}\n\nfunction settlePendingUpdate(\n state: ZaloServerState,\n pending: PendingUpdateRequest,\n result: PendingUpdateResult,\n): boolean {\n if (!pending.active) {\n return false;\n }\n pending.active = false;\n if (state.pendingRequest === pending) {\n state.pendingRequest = undefined;\n }\n if (pending.timeout) {\n clearTimeout(pending.timeout);\n }\n pending.request.socket.off(\"close\", pending.onDisconnect);\n pending.request.off(\"aborted\", pending.onDisconnect);\n pending.response.off(\"close\", pending.onDisconnect);\n pending.resolve(result);\n return true;\n}\n\nfunction isPendingUpdateRequestLive(pending: PendingUpdateRequest): boolean {\n return (\n !pending.request.aborted && !pending.request.socket.destroyed && !pending.response.destroyed\n );\n}\n\nasync function waitForUpdate(\n request: IncomingMessage,\n response: ServerResponse,\n state: ZaloServerState,\n timeoutSeconds: number,\n): Promise<HttpJsonHandlerResult> {\n if (request.aborted || request.socket.destroyed || response.destroyed) {\n return zaloError(\"Client closed request\", 499);\n }\n const previous = state.pendingRequest;\n if (previous) {\n settlePendingUpdate(state, previous, { kind: \"conflict\" });\n }\n const queued = nextUpdate(request, response, state);\n if (queued) {\n return queued;\n }\n if (timeoutSeconds <= 0) {\n return zaloError(\"Request timeout\", 408);\n }\n const result = await new Promise<PendingUpdateResult>((resolve) => {\n const pending: PendingUpdateRequest = {\n active: true,\n onDisconnect: () => {\n settlePendingUpdate(state, pending, { kind: \"disconnect\" });\n },\n request,\n response,\n resolve,\n timeout: undefined,\n };\n state.pendingRequest = pending;\n request.once(\"aborted\", pending.onDisconnect);\n request.socket.once(\"close\", pending.onDisconnect);\n response.once(\"close\", pending.onDisconnect);\n pending.timeout = setTimeout(() => {\n settlePendingUpdate(state, pending, { kind: \"timeout\" });\n }, timeoutSeconds * 1000);\n pending.timeout.unref();\n if (request.socket.destroyed || response.destroyed) {\n pending.onDisconnect();\n }\n });\n switch (result.kind) {\n case \"conflict\":\n return zaloError(\"Conflict: terminated by other getUpdates request\", 409);\n case \"disconnect\":\n return zaloError(\"Client closed request\", 499);\n case \"shutdown\":\n return zaloError(\"Server shutting down\", 503);\n case \"timeout\":\n return zaloError(\"Request timeout\", 408);\n case \"update\":\n return reservedUpdateResponse(state, result.update);\n }\n}\n\nfunction deliverPollingUpdate(state: ZaloServerState, update: ZaloUpdate): boolean {\n pollingUpdateOrder(state, update);\n if (state.updates.length > 0) {\n if (state.updates.length + state.reservedUpdateOrders.size >= state.maxPendingInboundEvents) {\n return false;\n }\n queuePollingUpdate(state, update);\n flushPendingPollingUpdate(state);\n return true;\n }\n const pending = state.pendingRequest;\n if (pending) {\n if (isPendingUpdateRequestLive(pending)) {\n reservePollingUpdate(state, update);\n settlePendingUpdate(state, pending, { kind: \"update\", update });\n return true;\n }\n settlePendingUpdate(state, pending, { kind: \"disconnect\" });\n }\n if (state.updates.length + state.reservedUpdateOrders.size >= state.maxPendingInboundEvents) {\n return false;\n }\n queuePollingUpdate(state, update);\n return true;\n}\n\nasync function deliverWebhookUpdate(\n state: ZaloServerState,\n webhook: NonNullable<ZaloServerState[\"webhook\"]>,\n update: ZaloUpdate,\n): Promise<Response | undefined> {\n const deadlineAt = Date.now() + state.webhookDeliveryTimeoutMs;\n const url = new URL(webhook.url);\n let target: Response | ZaloValidatedWebhookTarget;\n try {\n target = await validateWebhookUrlWithDeadline(url, state, deadlineAt);\n } catch (error) {\n if (error instanceof DOMException && error.name === \"TimeoutError\") {\n return zaloError(`Webhook delivery timed out after ${state.webhookDeliveryTimeoutMs}ms`, 502);\n }\n throw error;\n }\n if (target instanceof Response) {\n return target;\n }\n try {\n const remainingMs = deadlineAt - Date.now();\n if (remainingMs <= 0) {\n throw webhookTimeoutError(state.webhookDeliveryTimeoutMs);\n }\n const status = await postZaloWebhook({\n activeRequests: state.activeWebhookRequests,\n addresses: target.addresses,\n body: JSON.stringify(update),\n shouldCancel: () => state.closing,\n timeoutMs: remainingMs,\n url,\n verificationValue: webhook.secretToken,\n });\n if (status < 200 || status >= 300) {\n return zaloError(`Webhook delivery failed with HTTP ${status}`, 502);\n }\n } catch (error) {\n if (error instanceof DOMException && error.name === \"TimeoutError\") {\n return zaloError(`Webhook delivery timed out after ${state.webhookDeliveryTimeoutMs}ms`, 502);\n }\n return zaloError(\n `Webhook delivery failed: ${error instanceof Error ? error.message : String(error)}`,\n 502,\n );\n }\n return undefined;\n}\n\nasync function handleAdminInbound(\n request: IncomingMessage,\n state: ZaloServerState,\n url: URL,\n): Promise<Response> {\n if (!hasAdminToken(request, state.adminToken)) {\n drainRequestBody(request);\n return adminAuthError();\n }\n const parsedBody = await parseUnknownRequestBody(request);\n if (!isJsonObject(parsedBody)) {\n return zaloError(\"Bad Request: can't parse JSON object\", 400);\n }\n const body = parsedBody;\n const chatId = requireParam(body, \"chatId\");\n const senderId = requireParam(body, \"senderId\");\n const text = requireParam(body, \"text\");\n if (chatId instanceof Response || senderId instanceof Response || text instanceof Response) {\n return [chatId, senderId, text].find((value) => value instanceof Response) as Response;\n }\n let releaseAdmission!: () => void;\n const previousAdmission = state.inboundAdmission;\n state.inboundAdmission = new Promise<void>((resolve) => {\n releaseAdmission = resolve;\n });\n await previousAdmission;\n try {\n if (\n !state.webhook?.url &&\n state.updates.length + state.reservedUpdateOrders.size >= state.maxPendingInboundEvents\n ) {\n return zaloError(\n `Pending inbound queue is full (${state.maxPendingInboundEvents} updates)`,\n 429,\n );\n }\n const update: ZaloUpdate = {\n event_name: \"message.text.received\",\n message: {\n chat: { chat_type: readChatType(body.chatType), id: chatId },\n date: Date.now(),\n from: {\n display_name: readTrimmedString(body.senderName) ?? senderId,\n id: senderId,\n is_bot: false,\n },\n message_id: messageId(state),\n text,\n },\n };\n await appendEvent(state, {\n at: new Date().toISOString(),\n body,\n method: request.method ?? \"POST\",\n path: url.pathname,\n query: queryRecord(url),\n type: \"admin\",\n });\n if (state.webhook?.url) {\n const error = await deliverWebhookUpdate(state, state.webhook, update);\n if (error) {\n return error;\n }\n } else if (!deliverPollingUpdate(state, update)) {\n return zaloError(\n `Pending inbound queue is full (${state.maxPendingInboundEvents} updates)`,\n 429,\n );\n }\n return zaloOk(update);\n } finally {\n releaseAdmission();\n }\n}\n\nasync function handleZaloMethod(\n request: IncomingMessage,\n response: ServerResponse,\n state: ZaloServerState,\n url: URL,\n method: string,\n): Promise<HttpJsonHandlerResult> {\n const parsedBody = await parseUnknownRequestBody(request);\n if (!isJsonObject(parsedBody)) {\n return zaloError(\"Bad Request: can't parse JSON object\", 400);\n }\n const body = requestParams(url, parsedBody);\n const event: ZaloServerEvent = {\n at: new Date().toISOString(),\n ...(Object.keys(body).length > 0 ? { body: redactParams(body) } : {}),\n method: request.method ?? \"GET\",\n path: `/bot<redacted>/${method}`,\n query: redactParams(queryRecord(url)) as Record<string, string>,\n type: \"api\",\n };\n\n if (method === \"sendMessage\" || method === \"sendPhoto\") {\n const chatId = requireParam(body, \"chat_id\");\n const content = requireParam(body, method === \"sendMessage\" ? \"text\" : \"photo\");\n const error = firstError(chatId, content);\n const sendResponse = error ?? zaloOk({ date: Date.now(), message_id: messageId(state) });\n event.accepted = sendResponse.ok;\n try {\n await appendEvent(state, event);\n } catch (appendError) {\n if (!event.accepted) {\n throw appendError;\n }\n }\n return sendResponse;\n }\n\n await appendEvent(state, event);\n\n if (method === \"getMe\") {\n return zaloOk({\n account_name: state.botName,\n account_type: \"BASIC\",\n can_join_groups: true,\n id: state.botId,\n });\n }\n if (method === \"getUpdates\") {\n if (state.webhook?.url) {\n return zaloError(\"Webhook is configured; delete it before using getUpdates\", 400);\n }\n const parsedTimeout = Number(readTrimmedString(body.timeout) ?? \"30\");\n const timeout = Number.isFinite(parsedTimeout) ? Math.max(0, Math.min(parsedTimeout, 50)) : 30;\n return await waitForUpdate(request, response, state, timeout);\n }\n if (method === \"sendChatAction\") {\n const chatId = requireParam(body, \"chat_id\");\n const action = requireParam(body, \"action\");\n const error = firstError(chatId, action);\n if (error) {\n return error;\n }\n if (action !== \"typing\" && action !== \"upload_photo\") {\n return zaloError(\"action must be typing or upload_photo\", 400);\n }\n return zaloOk();\n }\n if (method === \"setWebhook\") {\n const webhookUrl = requireParam(body, \"url\");\n const secretToken = requireParam(body, \"secret_token\");\n const error = firstError(webhookUrl, secretToken);\n if (error) {\n return error;\n }\n if (typeof webhookUrl !== \"string\" || typeof secretToken !== \"string\") {\n return zaloError(\"Invalid webhook parameters\", 400);\n }\n const secretError = validateZaloWebhookSecret(secretToken);\n if (secretError) {\n return secretError;\n }\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(webhookUrl);\n } catch {\n return zaloError(\"url must be a valid HTTPS URL\", 400);\n }\n if (state.activeWebhookValidations.size >= MAX_ACTIVE_ZALO_WEBHOOK_VALIDATIONS) {\n return zaloError(\"Too many webhook validations\", 429);\n }\n let target: Response | ZaloValidatedWebhookTarget;\n try {\n target = await validateWebhookUrlWithDeadline(\n parsedUrl,\n state,\n Date.now() + state.webhookDeliveryTimeoutMs,\n );\n } catch {\n return zaloError(\"url host could not be resolved\", 400);\n }\n if (target instanceof Response) {\n return target;\n }\n if (state.reservedUpdateOrders.size > 0) {\n return zaloError(\"Polling deliveries are still in progress\", 409);\n }\n const webhook = { secretToken, updatedAt: Date.now(), url: parsedUrl.href };\n if (state.pendingRequest) {\n settlePendingUpdate(state, state.pendingRequest, { kind: \"conflict\" });\n }\n state.webhook = webhook;\n return zaloOk({ updated_at: webhook.updatedAt, url: webhook.url });\n }\n if (method === \"deleteWebhook\") {\n const updatedAt = Date.now();\n state.webhook = undefined;\n return zaloOk({ updated_at: updatedAt, url: \"\" });\n }\n if (method === \"getWebhookInfo\") {\n return zaloOk(\n state.webhook ? { updated_at: state.webhook.updatedAt, url: state.webhook.url } : { url: \"\" },\n );\n }\n return zaloError(\"Bad request - invalid API name\", 400);\n}\n\nexport async function startZaloServer(\n params: StartZaloServerParams = {},\n): Promise<StartedZaloServer> {\n const host = params.host ?? \"127.0.0.1\";\n const state: ZaloServerState = {\n activeWebhookRequests: new Set(),\n activeWebhookValidations: new Set(),\n adminToken: params.adminToken ?? randomBytes(24).toString(\"hex\"),\n allowLoopbackHttpWebhook: isLoopbackHost(host),\n botId: params.botId ?? \"1459232241454765289\",\n botName: params.botName ?? \"bot.crabline\",\n botToken:\n params.botToken ??\n (isLoopbackHost(host) ? \"crabline-zalo-bot-token\" : randomBytes(32).toString(\"base64url\")),\n closing: false,\n failedUpdateOrders: new Set(),\n inboundAdmission: Promise.resolve(),\n maxPendingInboundEvents: resolveMaxPendingInboundEvents(params.maxPendingInboundEvents),\n nextMessage: 1,\n nextUpdateOrder: 1,\n onEvent: params.onEvent,\n pendingRequest: undefined,\n recorderPath: params.recorderPath ?? path.resolve(\".crabline\", \"servers\", \"zalo.jsonl\"),\n reservedUpdateOrders: new Set(),\n restrictWebhookTargets: true,\n updateOrders: new WeakMap(),\n updates: [],\n webhook: undefined,\n webhookDeliveryTimeoutMs: webhookDeliveryTimeoutMs(params.webhookDeliveryTimeoutMs),\n };\n const httpServer = await startHttpJsonServer({\n handle: async (request, response) => {\n const url = new URL(request.url ?? \"/\", `http://${request.headers.host ?? host}`);\n if (request.method === \"POST\" && url.pathname === \"/crabline/zalo/inbound\") {\n return await handleAdminInbound(request, state, url);\n }\n const match = /^\\/bot([^/]+)\\/([^/]+)$/u.exec(url.pathname);\n if (!match || (request.method !== \"GET\" && request.method !== \"POST\")) {\n return zaloError(\"Not found\", 404);\n }\n if (match[1] !== state.botToken) {\n drainRequestBody(request);\n return zaloError(\"Unauthorized\", 401);\n }\n return await handleZaloMethod(request, response, state, url, match[2] ?? \"\");\n },\n handleError: (error) => {\n if (error instanceof InvalidJsonBodyError) {\n return zaloError(\"Bad Request: can't parse JSON object\", 400);\n }\n if (error instanceof RequestBodyTooLargeError) {\n return zaloError(\"Request Entity Too Large\", 413);\n }\n return undefined;\n },\n host,\n port: params.port ?? 0,\n serverName: \"Zalo\",\n });\n const manifest: ZaloServerManifest = {\n adminToken: state.adminToken,\n baseUrl: httpServer.baseUrl,\n botId: state.botId,\n botToken: state.botToken,\n endpoints: {\n adminInboundUrl: `${httpServer.baseUrl}/crabline/zalo/inbound`,\n apiRoot: httpServer.baseUrl,\n },\n env: {\n ZALO_API_URL: httpServer.baseUrl,\n ZALO_BOT_TOKEN: state.botToken,\n },\n provider: \"zalo\",\n recorderPath: state.recorderPath,\n version: 1,\n };\n return {\n async close() {\n state.closing = true;\n for (const request of state.activeWebhookRequests) {\n request.destroy(new Error(\"Zalo server is shutting down.\"));\n }\n for (const validation of state.activeWebhookValidations) {\n validation.abort(new Error(\"Zalo server is shutting down.\"));\n }\n if (state.pendingRequest) {\n settlePendingUpdate(state, state.pendingRequest, { kind: \"shutdown\" });\n }\n await httpServer.close();\n },\n manifest,\n };\n}\n"]}
@@ -32,6 +32,11 @@ Built-in adapters infer `platform` from `adapter`. `platform` is required only
32
32
  for `adapter: script`, where Crabline needs to know which OpenClaw channel the
33
33
  bridge profile represents.
34
34
 
35
+ Each provider selects exactly one adapter and may include only that adapter's
36
+ config block. For example, `adapter: slack` may use `slack:`, but it cannot also
37
+ contain `telegram:` or `script:`. When migrating an older mixed provider entry,
38
+ remove stale config blocks or split them into separate provider ids.
39
+
35
40
  ## Built-In Local Mocks
36
41
 
37
42
  | Adapter | Default Webhook Path | Default Port |
@@ -70,10 +75,115 @@ Provider credential fields such as `botToken`, `accessToken`, `baseURL`, or
70
75
  `serverUrl` are optional mock metadata. They are not required for local mock
71
76
  execution.
72
77
 
78
+ Optional webhook credentials enforce each provider's native authentication
79
+ header before JSON parsing or recorder writes:
80
+
81
+ - Discord `publicKey` or `DISCORD_PUBLIC_KEY` verifies
82
+ `X-Signature-Ed25519` over `X-Signature-Timestamp` plus the raw request body.
83
+ - Google Chat `endpointUrl` verifies Google ID tokens for the configured HTTP
84
+ audience. `googleChatProjectNumber` selects project-number JWT verification
85
+ instead. Authenticated Pub/Sub delivery uses `pubsubAudience` plus
86
+ `pubsubServiceAccountEmail`; `pubsubAudience` falls back to `endpointUrl`
87
+ when omitted, and `credentials.client_email` remains the service-account
88
+ email fallback when inline credentials are configured. Wrapped Pub/Sub
89
+ `message.data` must be canonical base64 before Google Chat event
90
+ normalization.
91
+ Google Workspace add-on `chat.messagePayload` events are rejected until the
92
+ adapter can bind the verified request to a configured add-on deployment
93
+ identity.
94
+ - Microsoft Teams `appId` or `TEAMS_APP_ID` verifies Bot Connector bearer
95
+ tokens, including the activity channel and exact `serviceUrl`. An `appId` is
96
+ required when the webhook host is non-loopback or `publicUrl` is set; an
97
+ unauthenticated webhook remains available only on loopback.
98
+ - Matrix webhook ingress currently has no provider-native authentication mode,
99
+ so it is restricted to loopback hosts and cannot set `publicUrl`.
100
+ - Mattermost and iMessage webhook ingress currently have no provider-native
101
+ authentication mode, so those adapter webhooks are restricted to loopback
102
+ hosts and cannot set `publicUrl`. Their API credentials do not authenticate
103
+ inbound callbacks.
104
+ - Feishu `verificationToken` or `FEISHU_VERIFICATION_TOKEN` verifies plaintext
105
+ callback tokens on loopback and remains an additional check when configured
106
+ with encryption. Externally reachable webhooks require `encryptKey` or
107
+ `FEISHU_ENCRYPT_KEY` to verify `X-Lark-Signature` and decrypt encrypted event
108
+ envelopes before challenge handling or event normalization.
109
+ - Slack `signingSecret` or `SLACK_SIGNING_SECRET` verifies
110
+ `X-Slack-Request-Timestamp` and `X-Slack-Signature`; it is required when the
111
+ webhook host is non-loopback or `publicUrl` is set.
112
+ - Telegram `secretToken` or `TELEGRAM_WEBHOOK_SECRET_TOKEN` verifies
113
+ `X-Telegram-Bot-Api-Secret-Token`.
114
+ - Zalo `webhookSecret` or `ZALO_WEBHOOK_SECRET` verifies
115
+ `X-Bot-Api-Secret-Token`.
116
+
117
+ The built-in `whatsapp` adapter implements Meta's GET verification challenge
118
+ and requires `X-Hub-Signature-256` on POST requests. Set `whatsapp.appSecret`
119
+ and `whatsapp.verifyToken` (or `WHATSAPP_APP_SECRET` and
120
+ `WHATSAPP_VERIFY_TOKEN`) before starting its webhook.
121
+
122
+ ## Script Bridge Config
123
+
124
+ Script providers use only the `script:` config block. Their required `platform`
125
+ labels the OpenClaw channel represented by the bridge; it does not allow the
126
+ matching built-in block such as `slack:` or `telegram:`. Move any behavior from
127
+ those blocks into the commands or command environment when migrating:
128
+
129
+ Treat manifests containing script providers as executable, trusted code.
130
+ Crabline runs their declared commands with the configured environment, so load
131
+ them only from sources you trust and review changes before use.
132
+
133
+ ```yaml
134
+ providers:
135
+ slack-openclaw:
136
+ adapter: script
137
+ platform: slack
138
+ capabilities: [probe, send, roundtrip]
139
+ env:
140
+ - OPENCLAW_URL
141
+ - OPENCLAW_TOKEN
142
+ script:
143
+ commands:
144
+ probe: node ./scripts/openclaw-bridge-probe.mjs
145
+ send: node ./scripts/openclaw-bridge-send.mjs
146
+ waitForInbound: node ./scripts/openclaw-bridge-wait.mjs
147
+ ```
148
+
149
+ The complete multi-channel script fixture is available in
150
+ `fixtures/examples/openclaw-bridge.yaml`.
151
+
152
+ Each command receives one JSON document on stdin. Every payload contains the
153
+ parsed `fixture` plus `provider.config`, `provider.id`, and
154
+ `provider.manifestPath`. `send` adds `outbound` with `mode`, `nonce`, normalized
155
+ `target`, and `text`; `waitForInbound` adds `wait` with `excludeIds`, `nonce`,
156
+ `since`, normalized `target`, and `timeoutMs`. A stateless wait bridge must
157
+ exclude messages whose IDs are listed in `excludeIds` while retaining later
158
+ messages with the same timestamp. Crabline retains at most 1024 unmatched IDs
159
+ per wait. `watch` adds `watch` with optional `since` and normalized `target`.
160
+
161
+ Non-watch commands must write exactly one JSON value to stdout:
162
+
163
+ - `probe`: `{ "healthy": boolean, "details"?: string[] }`
164
+ - `send`: `{ "accepted": boolean, "messageId": string, "threadId": string }`
165
+ - `waitForInbound`: either `{ "timeout": true }` or
166
+ `{ "message": { "author": "assistant" | "system" | "user", "id": string,
167
+ "sentAt": string, "text": string, "threadId": string, "raw"?: unknown } }`
168
+
169
+ `watch` writes one message object per JSONL line using the same message schema.
170
+ Blank lines are ignored. Non-watch stdout plus stderr is limited to 1 MiB.
171
+ Watch stderr, each JSONL line, and any unterminated buffered line are each
172
+ limited to 1 MiB. Commands inherit the process environment, use the configured
173
+ `cwd` and `shell`. Non-watch commands are terminated at their operation timeout;
174
+ watch commands are terminated when cancellation fires.
175
+
73
176
  ## Local Provider Servers
74
177
 
75
178
  Server-backed channels currently include Mattermost, Matrix, Signal, Slack,
76
- Telegram, and WhatsApp.
179
+ Telegram, WhatsApp, and Zalo. Loopback binds retain stable local credentials for
180
+ fixture compatibility. Non-loopback binds generate fresh provider-shaped
181
+ credentials unless the corresponding token or secret option is supplied.
182
+
183
+ Serve credential flags take precedence over their optional environment
184
+ fallbacks: `--admin-token` over `CRABLINE_ADMIN_TOKEN`, `--access-token` over
185
+ `CRABLINE_ACCESS_TOKEN`, `--bot-token` over `CRABLINE_BOT_TOKEN`, and
186
+ `--signing-secret` over `CRABLINE_SIGNING_SECRET`.
77
187
 
78
188
  ### Mattermost
79
189
 
@@ -130,6 +240,10 @@ separate OpenClaw bridge.
130
240
  Local provider servers sit below OpenClaw's normal channel adapters. QA starts
131
241
  the server, writes the emitted runtime manifest into OpenClaw config/env, and
132
242
  then OpenClaw talks to the local provider instead of the public provider.
243
+ Recorder-to-outbound translation requires the server-owned `accepted: true`
244
+ outcome together with the provider's exact send method and path. Rejected
245
+ requests and lookalike route suffixes can remain diagnostic recorder entries,
246
+ but they are never exposed as successful outbound deliveries.
133
247
 
134
248
  Slack:
135
249
 
@@ -223,7 +337,7 @@ The admin ingress accepts JSON like:
223
337
 
224
338
  OpenClaw consumes that message through Telegram `getUpdates`; outbound adapter
225
339
  sends are recorded through Telegram `sendMessage` and the media send endpoints
226
- `sendPhoto`, `sendDocument`, `sendVideo`, and `sendAnimation`.
340
+ `sendPhoto`, `sendDocument`, `sendVideo`, `sendAudio`, and `sendAnimation`.
227
341
 
228
342
  WhatsApp:
229
343
 
@@ -233,30 +347,36 @@ crabline --json serve whatsapp --ready-file .crabline/whatsapp-server.json
233
347
 
234
348
  Manifest fields:
235
349
 
236
- - `endpoints.apiRoot`: Crabline WhatsApp local provider API root
350
+ - `endpoints.apiRoot`: versioned WhatsApp Graph API root
351
+ - `endpoints.phoneNumberUrl`: provider-native phone-number resource
237
352
  - `endpoints.baileysWebSocketUrl`: Baileys-compatible WebSocket URL for
238
353
  `waWebSocketUrl`, including the local provider access token query parameter
239
354
  - `accessToken`: bearer token for local provider requests
240
355
  - `adminToken`: value for the `X-Crabline-Admin-Token` header on admin ingress
241
- - `selfJid`: local authenticated WhatsApp user JID
242
- - `env.CRABLINE_WHATSAPP_ACCESS_TOKEN`: same value as `accessToken`
243
- - `env.CRABLINE_WHATSAPP_API_ROOT`: same value as `endpoints.apiRoot`
244
- - `env.CRABLINE_WHATSAPP_BAILEYS_WEB_SOCKET_URL`: same value as
245
- `endpoints.baileysWebSocketUrl`
246
- - `env.CRABLINE_WHATSAPP_RECORDER_PATH`: recorder file for HTTP traffic and
247
- Baileys WebSocket stanzas
248
- - `env.CRABLINE_WHATSAPP_SELF_JID`: local authenticated WhatsApp user JID
356
+ - `selfJid`: canonical local authenticated WhatsApp user JID; legacy `@c.us`
357
+ input is normalized to `@s.whatsapp.net`
358
+ - `env.CLOUD_API_ACCESS_TOKEN`: same value as `accessToken`
359
+ - `env.CLOUD_API_VERSION`: Graph API version used by the local server
360
+ - `env.WA_BASE_URL`: local Graph API origin
361
+ - `env.WA_PHONE_NUMBER_ID`: local sender phone-number resource ID
249
362
  - `endpoints.adminInboundUrl`: authenticated admin ingress for test user
250
363
  messages using the WhatsApp Business webhook payload shape
251
- - `endpoints.messagesUrl`: text send endpoint for Graph-style callers
252
- - `endpoints.presenceUrl`: presence endpoint for Graph-style callers
364
+ - `endpoints.messagesUrl`: provider-native Cloud API message and status endpoint
365
+ - `endpoints.statusUrl`: alias for the same provider-native status endpoint
253
366
  - `recorderPath`: JSONL provider traffic recorder for HTTP traffic and Baileys
254
- WebSocket stanzas
367
+ WebSocket stanzas. Multi-message webhook deliveries use one versioned batch
368
+ line that Crabline's recorder APIs flatten into individual events.
255
369
 
256
370
  Pass `endpoints.baileysWebSocketUrl` to Baileys as `waWebSocketUrl` when a
257
- runtime needs to connect through the local provider. The local server completes
371
+ runtime needs to connect through the local provider. Cloud API-compatible
372
+ clients can send text messages through
373
+ `POST /v25.0/<phone-number-id>/messages` with a bearer token. The local server completes
258
374
  the Baileys Noise handshake, serves bootstrap/device/prekey queries, and records
259
- encrypted outbound WebSocket stanzas. The WebSocket endpoint rejects clients
375
+ encrypted outbound WebSocket stanzas. Direct `msg` and `pkmsg` text sends are
376
+ also recorded as normalized accepted-send evidence for the OpenClaw bridge.
377
+ Group outbound uses sender-key `skmsg` encryption and is outside this supported
378
+ subset, so OpenClaw Crabline outbound targets are direct users only. Group
379
+ inbound injection remains supported. The WebSocket endpoint rejects clients
260
380
  that do not present the access token embedded in the manifest URL. The admin
261
381
  token is generated randomly unless `--admin-token <token>` is provided.
262
382
 
@@ -293,11 +413,16 @@ adapter.
293
413
  The server accepts the provider-native `/bot<TOKEN>/<METHOD>` API shape over
294
414
  GET or POST. It implements bot identity, single-update long polling, text and
295
415
  photo sends, chat actions, and webhook lifecycle calls. A configured webhook
296
- receives the native Zalo `{ ok, result }` event envelope with
416
+ receives the native Zalo `{ event_name, message }` update directly with
297
417
  `X-Bot-Api-Secret-Token`;
298
418
  otherwise injected messages are returned by `getUpdates`. Provider errors use
299
419
  Zalo's `{ ok, error_code, description }` shape.
300
420
 
421
+ `setWebhook` requires HTTPS, matching Zalo's public API. A loopback-bound
422
+ Crabline server also accepts a loopback HTTP URL for independent local client
423
+ tests. Non-loopback binds reject webhook destinations that resolve to private,
424
+ loopback, or link-local addresses.
425
+
301
426
  The authenticated admin ingress is only a test control plane. Post a message
302
427
  such as:
303
428
 
@@ -353,12 +478,25 @@ as `telegram:`, `discord:`, or `slack:`.
353
478
  - Slack threads: `1700000000.000100`
354
479
  - Telegram chats: `-1001234567890` or `@channelusername`
355
480
  - Telegram topics: `42`
356
- - WhatsApp users: `15551234567@s.whatsapp.net`
357
- - WhatsApp groups: `120363001234567890@g.us`
481
+ - Built-in WhatsApp Cloud API users: digits-only `wa_id` values such as
482
+ `15551234567`
483
+ - OpenClaw WhatsApp bridge users: `15551234567@s.whatsapp.net`
484
+ (legacy `15551234567@c.us` inputs are accepted and canonicalized)
485
+ - OpenClaw WhatsApp bridge groups: `120363001234567890@g.us`
358
486
  - Discord channels and threads: Discord snowflake ids such as
359
487
  `123456789012345678`
360
488
  - Google Chat spaces: `spaces/AAAABbbbCCC`
361
489
  - Google Chat threads: `spaces/AAAABbbbCCC/threads/BBBBccccDDD`
490
+ - Matrix rooms: scoped ids such as `!abcdef:matrix.org` or Matrix v12
491
+ domainless room ids
492
+ - Zalo users, OAs, and chats: provider-native non-whitespace string ids such as
493
+ `user-1` or `group-1`
494
+
495
+ OpenClaw bridge QA targets reserve the exact forms `dm:<id>`, `group:<id>`,
496
+ `channel:<id>`, and `thread:<id>/<thread-id>`. Reserved forms require non-blank
497
+ components, and inbound thread IDs are trimmed before the matching QA target is
498
+ emitted. Numeric Telegram DM IDs must be positive; group, channel, and thread
499
+ chat IDs must be negative. Zero is invalid for every Telegram target kind.
362
500
 
363
501
  ## Smoke CI Guidance
364
502
 
@@ -379,6 +517,46 @@ execution:
379
517
  That means "run Telegram-shaped behavior through the mock Telegram backend."
380
518
  It does not mean "connect to live Telegram."
381
519
 
520
+ Crabline provider-readiness runs claim their output directory exclusively across
521
+ processes. `runOpenClawCrablineProviderReadiness` probes the selected local
522
+ provider API; it does not claim that OpenClaw started or completed a channel
523
+ roundtrip. Real OpenClaw channel proof comes from QA scenarios that launch the
524
+ gateway and run its normal channel adapter against the local provider.
525
+
526
+ Crabline stages the manifest, capability report, and provider-readiness report
527
+ inside one owner-only generation directory under the legacy
528
+ `.crabline-smoke-artifacts/` store name, atomically installs the complete
529
+ directory, and then atomically switches the single `current.json` pointer.
530
+ Readers therefore see either the prior complete generation or the next complete
531
+ generation, never per-file mixtures. Setup, probe, cleanup, staging, or
532
+ ownership failures leave the prior pointer unchanged. Crash-leftover staging
533
+ directories and installed-but-uncommitted generations remain owner-only and are
534
+ not removed automatically: a lease that can expire cannot safely authorize a
535
+ resumed stale process to delete another publisher's generation.
536
+
537
+ POSIX generation directories use mode `0700` and files use mode `0600`. Windows
538
+ hosts require `powershell.exe` with `Set-Acl`; Crabline resolves it from the
539
+ absolute local `SystemRoot` and applies a protected, inheritable DACL containing
540
+ only the current user SID to an empty generation directory before creating
541
+ sensitive files. Directory and file identities are verified throughout
542
+ publication. If `SystemRoot`, the ACL tooling, or identity verification is
543
+ unavailable, publication aborts without switching the pointer. Readiness results
544
+ contain `capabilityReport` and `providerReadiness` payloads while their manifest,
545
+ capability, and provider-readiness paths identify the authoritative immutable
546
+ generation.
547
+
548
+ Lock owners record both PID and process-start identity. Dead owners, and stale
549
+ locks whose PID was reused by the next Crabline process, are reclaimed on the
550
+ next run. New lock owners renew a 10-minute lease while the readiness run
551
+ remains active, so a live run retains exclusive ownership beyond the initial
552
+ lease. A heartbeat failure or lost ownership aborts publication before the
553
+ generation is committed. Recovery first atomically moves a stale candidate away
554
+ from the heartbeat path, then revalidates its token-specific lease before
555
+ deletion; a renewal that wins the rename race is restored rather than reclaimed.
556
+ The lease also bounds stale locks when an unrelated live process has inherited
557
+ the abandoned PID. Older owner records remain PID-protected for compatibility
558
+ and are reclaimed only after their recorded process exits.
559
+
382
560
  For release or live verification, use OpenClaw's live driver:
383
561
 
384
562
  ```yaml
@@ -10,6 +10,7 @@ providers:
10
10
  telegram:
11
11
  adapter: telegram
12
12
  telegram:
13
+ # secretToken: test-token-placeholder
13
14
  recorder:
14
15
  path: ./.crabline/recorders/telegram.jsonl
15
16
  webhook:
@@ -30,6 +31,7 @@ providers:
30
31
  slack:
31
32
  adapter: slack
32
33
  slack:
34
+ # signingSecret: test-token-placeholder
33
35
  recorder:
34
36
  path: ./.crabline/recorders/slack.jsonl
35
37
  webhook:
@@ -40,6 +42,8 @@ providers:
40
42
  whatsapp:
41
43
  adapter: whatsapp
42
44
  whatsapp:
45
+ appSecret: placeholder
46
+ verifyToken: placeholder
43
47
  recorder:
44
48
  path: ./.crabline/recorders/whatsapp.jsonl
45
49
  webhook:
@@ -50,6 +54,7 @@ providers:
50
54
  msteams:
51
55
  adapter: msteams
52
56
  msteams:
57
+ # appId: teams-app-id-placeholder # Required for non-loopback/public webhooks.
53
58
  recorder:
54
59
  path: ./.crabline/recorders/msteams.jsonl
55
60
  webhook:
@@ -60,6 +65,8 @@ providers:
60
65
  googlechat:
61
66
  adapter: googlechat
62
67
  googlechat:
68
+ # pubsubAudience: https://example.test/googlechat/webhook
69
+ # pubsubServiceAccountEmail: chat-push@example.iam.gserviceaccount.com
63
70
  recorder:
64
71
  path: ./.crabline/recorders/googlechat.jsonl
65
72
  webhook:
@@ -70,6 +77,8 @@ providers:
70
77
  feishu:
71
78
  adapter: feishu
72
79
  feishu:
80
+ # verificationToken: sample
81
+ # encryptKey: encrypt-key-placeholder
73
82
  recorder:
74
83
  path: ./.crabline/recorders/feishu.jsonl
75
84
  webhook:
@@ -90,6 +99,7 @@ providers:
90
99
  zalo:
91
100
  adapter: zalo
92
101
  zalo:
102
+ # webhookSecret: test-token-placeholder
93
103
  recorder:
94
104
  path: ./.crabline/recorders/zalo.jsonl
95
105
  webhook:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/crabline",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Standalone CLI for deterministic messaging provider E2E tests",
5
5
  "homepage": "https://github.com/openclaw/crabline#readme",
6
6
  "bugs": {
@@ -15,6 +15,7 @@
15
15
  "crabline": "dist/src/bin/crabline.js"
16
16
  },
17
17
  "files": [
18
+ "assets/crabline-banner.svg",
18
19
  "dist/src",
19
20
  "README.md",
20
21
  "docs/channel-setup.md",
@@ -30,9 +31,9 @@
30
31
  }
31
32
  },
32
33
  "scripts": {
33
- "prebuild": "rm -rf dist",
34
- "build": "tsgo -p tsconfig.build.json",
35
- "clean": "rm -rf dist coverage",
34
+ "prebuild": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
35
+ "build": "tsc -p tsconfig.build.json",
36
+ "clean": "node -e \"const fs = require('node:fs'); for (const path of ['dist', 'coverage']) fs.rmSync(path, { recursive: true, force: true })\"",
36
37
  "dev": "tsx src/bin/crabline.ts",
37
38
  "doctor": "tsx src/bin/crabline.ts doctor",
38
39
  "fixtures": "tsx src/bin/crabline.ts fixtures",
@@ -44,31 +45,35 @@
44
45
  "test": "vitest run",
45
46
  "test:coverage": "vitest run --coverage",
46
47
  "test:watch": "vitest",
47
- "typecheck": "tsgo -p tsconfig.test.json",
48
+ "typecheck": "tsc -p tsconfig.test.json",
48
49
  "verify": "pnpm lint && pnpm test:coverage",
49
50
  "check": "pnpm verify"
50
51
  },
51
52
  "dependencies": {
53
+ "@types/node": "^22.20.1",
52
54
  "commander": "^15.0.0",
53
55
  "curve25519-js": "^0.0.4",
56
+ "libsignal": "6.0.0",
54
57
  "picocolors": "^1.1.1",
58
+ "proper-lockfile": "4.1.2",
59
+ "re2js": "2.8.6",
55
60
  "ws": "^8.21.0",
56
61
  "yaml": "^2.9.0",
57
62
  "zod": "^4.4.3"
58
63
  },
59
64
  "devDependencies": {
60
- "@types/node": "^26.0.1",
65
+ "@types/proper-lockfile": "4.1.4",
61
66
  "@types/ws": "^8.18.1",
62
- "@typescript/native-preview": "7.0.0-dev.20260630.1",
63
- "@vitest/coverage-v8": "^4.1.9",
67
+ "@typescript/native": "npm:typescript@^7.0.2",
68
+ "@vitest/coverage-v8": "^4.1.10",
64
69
  "baileys": "7.0.0-rc13",
65
- "matrix-js-sdk": "41.6.0",
66
- "oxfmt": "^0.56.0",
67
- "oxlint": "^1.69.0",
68
- "oxlint-tsgolint": "^0.23.0",
69
- "tsx": "^4.22.4",
70
- "typescript": "^6.0.3",
71
- "vitest": "^4.1.9"
70
+ "matrix-js-sdk": "41.9.0",
71
+ "oxfmt": "^0.58.0",
72
+ "oxlint": "^1.73.0",
73
+ "oxlint-tsgolint": "^0.24.0",
74
+ "tsx": "^4.23.0",
75
+ "typescript": "npm:@typescript/typescript6@^6.0.2",
76
+ "vitest": "^4.1.10"
72
77
  },
73
78
  "engines": {
74
79
  "node": ">=22"