@openclaw/crabline 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -23
- package/dist/src/bin/crabline.js +3 -1
- package/dist/src/bin/crabline.js.map +1 -1
- package/dist/src/cli/program.d.ts +5 -1
- package/dist/src/cli/program.js +281 -52
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/config/load.js +39 -3
- package/dist/src/config/load.js.map +1 -1
- package/dist/src/config/schema.d.ts +20 -0
- package/dist/src/config/schema.js +163 -35
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/core/errors.d.ts +1 -0
- package/dist/src/core/errors.js +6 -3
- package/dist/src/core/errors.js.map +1 -1
- package/dist/src/core/http-path.d.ts +1 -0
- package/dist/src/core/http-path.js +14 -0
- package/dist/src/core/http-path.js.map +1 -0
- package/dist/src/core/matcher.d.ts +3 -1
- package/dist/src/core/matcher.js +58 -2
- package/dist/src/core/matcher.js.map +1 -1
- package/dist/src/core/nonces.d.ts +2 -0
- package/dist/src/core/nonces.js +11 -1
- package/dist/src/core/nonces.js.map +1 -1
- package/dist/src/core/reporters.d.ts +5 -0
- package/dist/src/core/reporters.js +26 -2
- package/dist/src/core/reporters.js.map +1 -1
- package/dist/src/core/run.d.ts +3 -1
- package/dist/src/core/run.js +178 -66
- package/dist/src/core/run.js.map +1 -1
- package/dist/src/index.d.ts +12 -10
- package/dist/src/index.js +6 -5
- package/dist/src/index.js.map +1 -1
- package/dist/src/matrix-ids.d.ts +5 -0
- package/dist/src/matrix-ids.js +83 -0
- package/dist/src/matrix-ids.js.map +1 -0
- package/dist/src/openclaw/artifact-generation.d.ts +7 -6
- package/dist/src/openclaw/artifact-generation.js +385 -41
- package/dist/src/openclaw/artifact-generation.js.map +1 -1
- package/dist/src/openclaw/bridges/discord.d.ts +1 -0
- package/dist/src/openclaw/bridges/discord.js +149 -0
- package/dist/src/openclaw/bridges/discord.js.map +1 -0
- package/dist/src/openclaw/bridges/matrix.js +22 -5
- package/dist/src/openclaw/bridges/matrix.js.map +1 -1
- package/dist/src/openclaw/bridges/mattermost.js +14 -9
- package/dist/src/openclaw/bridges/mattermost.js.map +1 -1
- package/dist/src/openclaw/bridges/probe-response.d.ts +1 -0
- package/dist/src/openclaw/bridges/probe-response.js +5 -0
- package/dist/src/openclaw/bridges/probe-response.js.map +1 -0
- package/dist/src/openclaw/bridges/signal.js +16 -7
- package/dist/src/openclaw/bridges/signal.js.map +1 -1
- package/dist/src/openclaw/bridges/slack.js +117 -24
- package/dist/src/openclaw/bridges/slack.js.map +1 -1
- package/dist/src/openclaw/bridges/telegram.js +46 -20
- package/dist/src/openclaw/bridges/telegram.js.map +1 -1
- package/dist/src/openclaw/bridges/whatsapp.js +33 -17
- package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
- package/dist/src/openclaw/bridges/zalo.js +9 -4
- package/dist/src/openclaw/bridges/zalo.js.map +1 -1
- package/dist/src/openclaw/outbound-contract.js +3 -0
- package/dist/src/openclaw/outbound-contract.js.map +1 -1
- package/dist/src/openclaw/private-file.d.ts +38 -3
- package/dist/src/openclaw/private-file.js +2008 -87
- package/dist/src/openclaw/private-file.js.map +1 -1
- package/dist/src/openclaw/{smoke-lock.d.ts → provider-readiness-lock.d.ts} +14 -5
- package/dist/src/openclaw/provider-readiness-lock.js +1320 -0
- package/dist/src/openclaw/provider-readiness-lock.js.map +1 -0
- package/dist/src/openclaw/shared.d.ts +10 -17
- package/dist/src/openclaw/shared.js +53 -19
- package/dist/src/openclaw/shared.js.map +1 -1
- package/dist/src/openclaw.d.ts +3 -5
- package/dist/src/openclaw.js +245 -60
- package/dist/src/openclaw.js.map +1 -1
- package/dist/src/platform/process-owned-lock.d.ts +11 -0
- package/dist/src/platform/process-owned-lock.js +1698 -0
- package/dist/src/platform/process-owned-lock.js.map +1 -0
- package/dist/src/platform/recorder-directory.d.ts +1 -0
- package/dist/src/platform/recorder-directory.js +14 -0
- package/dist/src/platform/recorder-directory.js.map +1 -0
- package/dist/src/platform/windows-acl.d.ts +18 -0
- package/dist/src/platform/windows-acl.js +1367 -0
- package/dist/src/platform/windows-acl.js.map +1 -0
- package/dist/src/platform/windows-lock-root.d.ts +13 -0
- package/dist/src/platform/windows-lock-root.js +98 -0
- package/dist/src/platform/windows-lock-root.js.map +1 -0
- package/dist/src/providers/builtin/discord.d.ts +4 -0
- package/dist/src/providers/builtin/discord.js +52 -9
- package/dist/src/providers/builtin/discord.js.map +1 -1
- package/dist/src/providers/builtin/external-webhook-auth.d.ts +1 -0
- package/dist/src/providers/builtin/external-webhook-auth.js +38 -1
- package/dist/src/providers/builtin/external-webhook-auth.js.map +1 -1
- package/dist/src/providers/builtin/feishu.d.ts +1 -0
- package/dist/src/providers/builtin/feishu.js +96 -26
- package/dist/src/providers/builtin/feishu.js.map +1 -1
- package/dist/src/providers/builtin/googlechat.d.ts +1 -0
- package/dist/src/providers/builtin/googlechat.js +95 -26
- package/dist/src/providers/builtin/googlechat.js.map +1 -1
- package/dist/src/providers/builtin/imessage.js +60 -17
- package/dist/src/providers/builtin/imessage.js.map +1 -1
- package/dist/src/providers/builtin/loopback.js +88 -35
- package/dist/src/providers/builtin/loopback.js.map +1 -1
- package/dist/src/providers/builtin/matrix.d.ts +2 -2
- package/dist/src/providers/builtin/matrix.js +78 -21
- package/dist/src/providers/builtin/matrix.js.map +1 -1
- package/dist/src/providers/builtin/mattermost.d.ts +11 -7
- package/dist/src/providers/builtin/mattermost.js +138 -24
- package/dist/src/providers/builtin/mattermost.js.map +1 -1
- package/dist/src/providers/builtin/msteams.d.ts +1 -0
- package/dist/src/providers/builtin/msteams.js +118 -38
- package/dist/src/providers/builtin/msteams.js.map +1 -1
- package/dist/src/providers/builtin/native-local-mock.js +4 -4
- package/dist/src/providers/builtin/native-local-mock.js.map +1 -1
- package/dist/src/providers/builtin/script.js +1057 -146
- package/dist/src/providers/builtin/script.js.map +1 -1
- package/dist/src/providers/builtin/slack.d.ts +8 -1
- package/dist/src/providers/builtin/slack.js +327 -24
- package/dist/src/providers/builtin/slack.js.map +1 -1
- package/dist/src/providers/builtin/telegram.d.ts +1 -1
- package/dist/src/providers/builtin/telegram.js +55 -14
- package/dist/src/providers/builtin/telegram.js.map +1 -1
- package/dist/src/providers/builtin/whatsapp.d.ts +4 -3
- package/dist/src/providers/builtin/whatsapp.js +157 -29
- package/dist/src/providers/builtin/whatsapp.js.map +1 -1
- package/dist/src/providers/builtin/zalo.d.ts +5 -2
- package/dist/src/providers/builtin/zalo.js +31 -7
- package/dist/src/providers/builtin/zalo.js.map +1 -1
- package/dist/src/providers/catalog.d.ts +1 -1
- package/dist/src/providers/catalog.js +1 -1
- package/dist/src/providers/catalog.js.map +1 -1
- package/dist/src/providers/local-mock.d.ts +4 -0
- package/dist/src/providers/local-mock.js +162 -35
- package/dist/src/providers/local-mock.js.map +1 -1
- package/dist/src/providers/native-ids.d.ts +2 -0
- package/dist/src/providers/native-ids.js +3 -0
- package/dist/src/providers/native-ids.js.map +1 -1
- package/dist/src/providers/recorder.d.ts +14 -3
- package/dist/src/providers/recorder.js +521 -41
- package/dist/src/providers/recorder.js.map +1 -1
- package/dist/src/providers/registry.d.ts +1 -0
- package/dist/src/providers/registry.js +65 -20
- package/dist/src/providers/registry.js.map +1 -1
- package/dist/src/providers/signed-jwt.d.ts +6 -1
- package/dist/src/providers/signed-jwt.js +241 -50
- package/dist/src/providers/signed-jwt.js.map +1 -1
- package/dist/src/providers/slack-ids.d.ts +1 -0
- package/dist/src/providers/slack-ids.js +5 -0
- package/dist/src/providers/slack-ids.js.map +1 -1
- package/dist/src/providers/target-normalizers.d.ts +9 -1
- package/dist/src/providers/target-normalizers.js +177 -58
- package/dist/src/providers/target-normalizers.js.map +1 -1
- package/dist/src/providers/webhook-server.d.ts +3 -0
- package/dist/src/providers/webhook-server.js +268 -47
- package/dist/src/providers/webhook-server.js.map +1 -1
- package/dist/src/servers/discord.d.ts +40 -0
- package/dist/src/servers/discord.js +842 -0
- package/dist/src/servers/discord.js.map +1 -0
- package/dist/src/servers/http.d.ts +14 -2
- package/dist/src/servers/http.js +229 -58
- package/dist/src/servers/http.js.map +1 -1
- package/dist/src/servers/index.d.ts +10 -4
- package/dist/src/servers/index.js +4 -0
- package/dist/src/servers/index.js.map +1 -1
- package/dist/src/servers/matrix.d.ts +3 -0
- package/dist/src/servers/matrix.js +268 -110
- package/dist/src/servers/matrix.js.map +1 -1
- package/dist/src/servers/mattermost.d.ts +5 -0
- package/dist/src/servers/mattermost.js +389 -91
- package/dist/src/servers/mattermost.js.map +1 -1
- package/dist/src/servers/recorder.d.ts +11 -0
- package/dist/src/servers/recorder.js +1072 -69
- package/dist/src/servers/recorder.js.map +1 -1
- package/dist/src/servers/signal.d.ts +1 -0
- package/dist/src/servers/signal.js +279 -44
- package/dist/src/servers/signal.js.map +1 -1
- package/dist/src/servers/slack.d.ts +15 -0
- package/dist/src/servers/slack.js +270 -54
- package/dist/src/servers/slack.js.map +1 -1
- package/dist/src/servers/telegram-identity.d.ts +6 -0
- package/dist/src/servers/telegram-identity.js +27 -0
- package/dist/src/servers/telegram-identity.js.map +1 -0
- package/dist/src/servers/telegram.d.ts +17 -6
- package/dist/src/servers/telegram.js +1218 -107
- package/dist/src/servers/telegram.js.map +1 -1
- package/dist/src/servers/webhook-target.d.ts +12 -4
- package/dist/src/servers/webhook-target.js +226 -28
- package/dist/src/servers/webhook-target.js.map +1 -1
- package/dist/src/servers/whatsapp-baileys-websocket.d.ts +60 -1
- package/dist/src/servers/whatsapp-baileys-websocket.js +782 -112
- package/dist/src/servers/whatsapp-baileys-websocket.js.map +1 -1
- package/dist/src/servers/whatsapp-jid.d.ts +1 -0
- package/dist/src/servers/whatsapp-jid.js +9 -5
- package/dist/src/servers/whatsapp-jid.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/binary-node.d.ts +1 -0
- package/dist/src/servers/whatsapp-wire/binary-node.js +37 -13
- package/dist/src/servers/whatsapp-wire/binary-node.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/crypto.d.ts +3 -0
- package/dist/src/servers/whatsapp-wire/crypto.js +23 -8
- package/dist/src/servers/whatsapp-wire/crypto.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/handshake.d.ts +9 -3
- package/dist/src/servers/whatsapp-wire/handshake.js +173 -12
- package/dist/src/servers/whatsapp-wire/handshake.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/signal.js +3 -3
- package/dist/src/servers/whatsapp-wire/signal.js.map +1 -1
- package/dist/src/servers/whatsapp.d.ts +7 -1
- package/dist/src/servers/whatsapp.js +149 -25
- package/dist/src/servers/whatsapp.js.map +1 -1
- package/dist/src/servers/zalo.d.ts +1 -0
- package/dist/src/servers/zalo.js +193 -82
- package/dist/src/servers/zalo.js.map +1 -1
- package/docs/channel-setup.md +251 -64
- package/fixtures/examples/crabline.example.yaml +3 -2
- package/package.json +18 -10
- package/dist/src/openclaw/smoke-lock.js +0 -1004
- package/dist/src/openclaw/smoke-lock.js.map +0 -1
- package/fixtures/examples/openclaw-bridge.yaml +0 -125
|
@@ -1 +1 @@
|
|
|
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"]}
|
|
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 DEFAULT_MAX_PENDING_INBOUND_BYTES = 64 * 1024 * 1024;\nconst MAX_ACTIVE_ZALO_WEBHOOK_VALIDATIONS = 8;\nconst MAX_ZALO_REDACTION_DEPTH = 32;\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 inboundAdmission: Promise<void>;\n maxPendingInboundBytes: number;\n maxPendingInboundEvents: number;\n nextMessage: number;\n nextUpdateOrder: number;\n onEvent: ServerEventObserver | undefined;\n pendingInboundAdmissions: number;\n pendingRequest: PendingUpdateRequest | undefined;\n recorderPath: string;\n retainedUpdateBytes: number;\n retainedUpdateCount: number;\n reservedUpdateOrders: Set<number>;\n restrictWebhookTargets: boolean;\n updateBytes: WeakMap<ZaloUpdate, number>;\n updateOrders: WeakMap<ZaloUpdate, number>;\n updates: ZaloUpdate[];\n webhook: { secretToken: string; updatedAt: number; url: string } | undefined;\n webhookDeliveryTimeoutMs: number;\n webhookTransitionPending: boolean;\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 maxPendingInboundBytes?: number | 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 normalizedName = name.normalize(\"NFKC\");\n const canonicalName = normalizedName.replace(/[^A-Za-z0-9]/gu, \"\").toLowerCase();\n return (\n SENSITIVE_PARAM_NAMES.has(canonicalName) ||\n /[a-z0-9](?:credentials?|keys?|passwords?|passwds?|secrets?|signatures?|tokens?)$/u.test(\n canonicalName,\n ) ||\n /(?:^|[_-])(?:access[_-]?token|api[_-]?key|authorization|key|password|secret|signature|token)(?:$|[_-])/iu.test(\n normalizedName,\n )\n );\n}\n\nfunction isUrlParam(name: string): boolean {\n return /(?:urls?|uris?)$/iu.test(name.normalize(\"NFKC\").replace(/[^A-Za-z0-9]/gu, \"\"));\n}\n\nfunction redactParamValue(value: unknown, key: string, depth: number): unknown {\n if (isSensitiveParam(key)) {\n return \"<redacted>\";\n }\n if (Array.isArray(value)) {\n if (depth >= MAX_ZALO_REDACTION_DEPTH) {\n return \"<redacted>\";\n }\n return value.map((entry) => redactParamValue(entry, key, depth + 1));\n }\n if (isJsonObject(value)) {\n if (depth >= MAX_ZALO_REDACTION_DEPTH) {\n return \"<redacted>\";\n }\n return redactParams(value, depth + 1);\n }\n if (\n typeof value === \"string\" &&\n (isUrlParam(key) || /^(?:\\s*[a-z][a-z0-9+.-]*:)?\\/\\//iu.test(value))\n ) {\n return redactUrlCredentials(value);\n }\n return value;\n}\n\nfunction redactParams(params: Record<string, unknown>, depth = 0): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(params).map(([key, value]) => [key, redactParamValue(value, key, depth)]),\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 redactUrlFragment(value: string): string {\n const fragmentStart = value.indexOf(\"#\");\n return fragmentStart < 0 ? value : `${value.slice(0, fragmentStart)}#<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 if (credentialRedacted === value) {\n return \"<redacted>\";\n }\n const fragmentRedacted = redactUrlFragment(credentialRedacted);\n const queryStart = fragmentRedacted.indexOf(\"?\");\n const fragmentStart = fragmentRedacted.indexOf(\"#\", queryStart + 1);\n if (queryStart < 0 || (fragmentStart >= 0 && fragmentStart < queryStart)) {\n return fragmentRedacted;\n }\n const queryEnd = fragmentStart >= 0 ? fragmentStart : fragmentRedacted.length;\n const searchParams = new URLSearchParams(fragmentRedacted.slice(queryStart + 1, queryEnd));\n if (!redactSensitiveSearchParams(searchParams)) {\n return fragmentRedacted;\n }\n const search = searchParams.toString().replaceAll(\"%3Credacted%3E\", \"<redacted>\");\n return `${fragmentRedacted.slice(0, queryStart)}?${search}${fragmentRedacted.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 const hasFragment = url.hash.length > 0;\n if (!hasCredentials && !redactedQuery) {\n return hasFragment ? redactUrlFragment(value) : value;\n }\n const search = url.search.replaceAll(\"%3Credacted%3E\", \"<redacted>\");\n return `${url.protocol}//${hasCredentials ? \"<redacted>@\" : \"\"}${url.host}${url.pathname}${search}${hasFragment ? \"#<redacted>\" : \"\"}`;\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\nfunction maxPendingInboundBytes(value: number | undefined): number {\n if (value === undefined) {\n return DEFAULT_MAX_PENDING_INBOUND_BYTES;\n }\n if (!Number.isSafeInteger(value) || value < 1) {\n throw new Error(\"maxPendingInboundBytes must be a positive safe integer.\");\n }\n return value;\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 if (hasEarlierReservedPollingUpdate(state, update)) {\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 pollingUpdateBytes(state: ZaloServerState, update: ZaloUpdate): number {\n const existing = state.updateBytes.get(update);\n if (existing !== undefined) {\n return existing;\n }\n const bytes = Buffer.byteLength(JSON.stringify(update), \"utf8\");\n state.updateBytes.set(update, bytes);\n return bytes;\n}\n\nfunction retainPollingUpdate(state: ZaloServerState, update: ZaloUpdate): boolean {\n const bytes = pollingUpdateBytes(state, update);\n if (\n state.retainedUpdateCount >= state.maxPendingInboundEvents ||\n state.retainedUpdateBytes + bytes > state.maxPendingInboundBytes\n ) {\n state.updateBytes.delete(update);\n return false;\n }\n state.retainedUpdateCount += 1;\n state.retainedUpdateBytes += bytes;\n return true;\n}\n\nfunction releasePollingUpdate(state: ZaloServerState, update: ZaloUpdate): void {\n const bytes = state.updateBytes.get(update);\n if (bytes === undefined) {\n throw new Error(\"Zalo polling update retention was released without a reservation.\");\n }\n state.updateBytes.delete(update);\n state.retainedUpdateCount -= 1;\n state.retainedUpdateBytes -= bytes;\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 hasEarlierReservedPollingUpdate(state: ZaloServerState, update: ZaloUpdate): boolean {\n const order = pollingUpdateOrder(state, update);\n return [...state.reservedUpdateOrders].some((reservedOrder) => reservedOrder < order);\n}\n\nfunction reservePollingUpdate(state: ZaloServerState, update: ZaloUpdate): void {\n const order = pollingUpdateOrder(state, update);\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 if (hasEarlierReservedPollingUpdate(state, update)) {\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 releaseReservation = () => {\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 (!releaseReservation()) {\n return;\n }\n queuePollingUpdate(state, update);\n flushPendingPollingUpdate(state);\n },\n onWriteSuccess() {\n if (releaseReservation()) {\n releasePollingUpdate(state, update);\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): void {\n pollingUpdateOrder(state, update);\n if (state.updates.length > 0 || hasEarlierReservedPollingUpdate(state, update)) {\n queuePollingUpdate(state, update);\n flushPendingPollingUpdate(state);\n return;\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;\n }\n settlePendingUpdate(state, pending, { kind: \"disconnect\" });\n }\n queuePollingUpdate(state, update);\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 if (state.webhookTransitionPending) {\n drainRequestBody(request);\n return zaloError(\"Webhook configuration is in progress\", 409);\n }\n const retainedUpdates = state.webhook?.url === undefined ? state.retainedUpdateCount : 0;\n if (retainedUpdates + state.pendingInboundAdmissions >= state.maxPendingInboundEvents) {\n drainRequestBody(request);\n return zaloError(\n `Pending inbound queue is full (${state.maxPendingInboundEvents} updates)`,\n 429,\n );\n }\n state.pendingInboundAdmissions += 1;\n let releaseAdmission!: () => void;\n const previousAdmission = state.inboundAdmission;\n state.inboundAdmission = new Promise<void>((resolve) => {\n releaseAdmission = resolve;\n });\n let admissionPending = true;\n let retainedPollingUpdate: ZaloUpdate | undefined;\n try {\n const parsedBody = await parseUnknownRequestBody(request);\n await previousAdmission;\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 const webhook = state.webhook;\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 if (!webhook?.url) {\n if (!retainPollingUpdate(state, update)) {\n return zaloError(\n `Pending inbound queue is full (${state.maxPendingInboundEvents} updates)`,\n 429,\n );\n }\n retainedPollingUpdate = update;\n state.pendingInboundAdmissions -= 1;\n admissionPending = false;\n }\n await appendEvent(state, {\n at: new Date().toISOString(),\n body: redactParams(body),\n method: request.method ?? \"POST\",\n path: url.pathname,\n query: redactParams(queryRecord(url)) as Record<string, string>,\n type: \"admin\",\n });\n if (webhook?.url) {\n const error = await deliverWebhookUpdate(state, webhook, update);\n if (error) {\n return error;\n }\n } else {\n deliverPollingUpdate(state, update);\n retainedPollingUpdate = undefined;\n }\n return zaloOk(update);\n } finally {\n if (retainedPollingUpdate) {\n releasePollingUpdate(state, retainedPollingUpdate);\n }\n await previousAdmission;\n releaseAdmission();\n if (admissionPending) {\n state.pendingInboundAdmissions -= 1;\n }\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 if (method === \"getMe\") {\n const getMeResponse = zaloOk({\n account_name: state.botName,\n account_type: \"BASIC\",\n can_join_groups: true,\n id: state.botId,\n });\n event.accepted = getMeResponse.ok;\n await appendEvent(state, event);\n return getMeResponse;\n }\n\n if (method !== \"setWebhook\") {\n await appendEvent(state, event);\n }\n if (method === \"getUpdates\") {\n if (state.webhook?.url || state.webhookTransitionPending) {\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 reject = async (result: Response): Promise<Response> => {\n if (isJsonObject(event.body) && \"url\" in event.body) {\n event.body.url = \"<redacted>\";\n }\n await appendEvent(state, event);\n return result;\n };\n const webhookUrl = requireParam(body, \"url\");\n const secretToken = requireParam(body, \"secret_token\");\n const error = firstError(webhookUrl, secretToken);\n if (error) {\n return await reject(error);\n }\n if (typeof webhookUrl !== \"string\" || typeof secretToken !== \"string\") {\n return await reject(zaloError(\"Invalid webhook parameters\", 400));\n }\n const secretError = validateZaloWebhookSecret(secretToken);\n if (secretError) {\n return await reject(secretError);\n }\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(webhookUrl);\n } catch {\n return await reject(zaloError(\"url must be a valid HTTPS URL\", 400));\n }\n if (state.activeWebhookValidations.size >= MAX_ACTIVE_ZALO_WEBHOOK_VALIDATIONS) {\n return await reject(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 await reject(zaloError(\"url host could not be resolved\", 400));\n }\n if (target instanceof Response) {\n return await reject(target);\n }\n if (state.webhookTransitionPending || state.reservedUpdateOrders.size > 0) {\n return await reject(zaloError(\"Polling deliveries are still in progress\", 409));\n }\n const webhook = { secretToken, updatedAt: Date.now(), url: parsedUrl.href };\n state.webhookTransitionPending = true;\n try {\n await state.inboundAdmission;\n if (state.reservedUpdateOrders.size > 0) {\n return await reject(zaloError(\"Polling deliveries are still in progress\", 409));\n }\n await appendEvent(state, event);\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 } finally {\n state.webhookTransitionPending = false;\n }\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 inboundAdmission: Promise.resolve(),\n maxPendingInboundBytes: maxPendingInboundBytes(params.maxPendingInboundBytes),\n maxPendingInboundEvents: resolveMaxPendingInboundEvents(params.maxPendingInboundEvents),\n nextMessage: 1,\n nextUpdateOrder: 1,\n onEvent: params.onEvent,\n pendingInboundAdmissions: 0,\n pendingRequest: undefined,\n recorderPath: params.recorderPath ?? path.resolve(\".crabline\", \"servers\", \"zalo.jsonl\"),\n retainedUpdateBytes: 0,\n retainedUpdateCount: 0,\n reservedUpdateOrders: new Set(),\n restrictWebhookTargets: true,\n updateBytes: new WeakMap(),\n updateOrders: new WeakMap(),\n updates: [],\n webhook: undefined,\n webhookDeliveryTimeoutMs: webhookDeliveryTimeoutMs(params.webhookDeliveryTimeoutMs),\n webhookTransitionPending: false,\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"]}
|