@openclaw/zalo 2026.7.1-beta.6 → 2026.7.2-beta.1

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/dist/api.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { n as zaloDmPolicy, r as zaloSetupAdapter, t as createZaloSetupWizardProxy } from "./setup-core-fwCh0QUi.js";
2
- import { t as zaloPlugin } from "./channel-BOWhJVyl.js";
2
+ import { t as zaloPlugin } from "./channel-C_73K8pR.js";
3
3
  import { n as resolveZaloRuntimeGroupPolicy } from "./group-access-8qHRzDHx.js";
4
4
  import { zaloSetupWizard } from "./setup-api.js";
5
5
  export { createZaloSetupWizardProxy, resolveZaloRuntimeGroupPolicy, zaloDmPolicy, zaloPlugin, zaloSetupAdapter, zaloSetupWizard };
@@ -1,5 +1,5 @@
1
1
  import { c as listZaloAccountIds, f as buildSecretInputSchema, l as resolveDefaultZaloAccountId, r as zaloSetupAdapter, s as listEnabledZaloAccounts, t as createZaloSetupWizardProxy, u as resolveZaloAccount } from "./setup-core-fwCh0QUi.js";
2
- import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-Bno_huZF.js";
2
+ import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-Bxvjh0Hq.js";
3
3
  import { describeWebhookAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
4
4
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
5
5
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
@@ -7,7 +7,7 @@ import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter, createSco
7
7
  import { buildChannelConfigSchema, createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
8
8
  import { defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-outbound";
9
9
  import { buildOpenGroupPolicyRestrictSendersWarning, buildOpenGroupPolicyWarning, createOpenProviderGroupPolicyWarningCollector } from "openclaw/plugin-sdk/channel-policy";
10
- import { createEmptyChannelResult, createRawChannelSendResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
10
+ import { createAttachedChannelResultAdapter, createEmptyChannelResult } from "openclaw/plugin-sdk/channel-send-result";
11
11
  import { buildTokenChannelStatusSummary } from "openclaw/plugin-sdk/channel-status";
12
12
  import { createStaticReplyToModeResolver } from "openclaw/plugin-sdk/conversation-runtime";
13
13
  import { createChannelDirectoryAdapter, listResolvedDirectoryUserEntriesFromAllowFrom } from "openclaw/plugin-sdk/directory-runtime";
@@ -19,7 +19,7 @@ import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coer
19
19
  import { buildChannelOutboundSessionRoute, stripChannelTargetPrefix, stripTargetKindPrefix } from "openclaw/plugin-sdk/core";
20
20
  import { jsonResult, readStringParam } from "openclaw/plugin-sdk/channel-actions";
21
21
  import { extractToolSend } from "openclaw/plugin-sdk/tool-send";
22
- import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
22
+ import { createChannelApprovalAuth } from "openclaw/plugin-sdk/approval-auth-runtime";
23
23
  import { AllowFromListSchema, DmPolicySchema, GroupPolicySchema, MarkdownConfigSchema, buildCatchallMultiAccountChannelSchema } from "openclaw/plugin-sdk/channel-config-schema";
24
24
  import { z } from "zod";
25
25
  import { coerceStatusIssueAccountId, readStatusIssueFields } from "openclaw/plugin-sdk/extension-shared";
@@ -75,20 +75,16 @@ function normalizeZaloApproverId(value) {
75
75
  const normalized = String(value).trim().replace(/^(zalo|zl):/i, "").trim();
76
76
  return /^\d+$/.test(normalized) ? normalized : void 0;
77
77
  }
78
- const zaloApprovalAuth = createResolvedApproverActionAuthAdapter({
78
+ const zaloApprovalAuth = createChannelApprovalAuth({
79
79
  channelLabel: "Zalo",
80
- resolveApprovers: ({ cfg, accountId }) => {
81
- const account = resolveZaloAccount({
80
+ resolveInputs: ({ cfg, accountId }) => {
81
+ return { allowFrom: resolveZaloAccount({
82
82
  cfg,
83
83
  accountId
84
- }).config;
85
- return resolveApprovalApprovers({
86
- allowFrom: account.allowFrom,
87
- normalizeApprover: normalizeZaloApproverId
88
- });
84
+ }).config.allowFrom };
89
85
  },
90
- normalizeSenderId: (value) => normalizeZaloApproverId(value)
91
- });
86
+ normalizeApprover: normalizeZaloApproverId
87
+ }).approvalAuth;
92
88
  const ZaloConfigSchema = buildCatchallMultiAccountChannelSchema(z.object({
93
89
  name: z.string().optional(),
94
90
  enabled: z.boolean().optional(),
@@ -180,24 +176,27 @@ function looksLikeZaloChatId(raw, normalized) {
180
176
  const target = normalizeZaloMessagingTarget(normalized ?? raw);
181
177
  return Boolean(target);
182
178
  }
183
- const loadZaloChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-CEPgF8Zo.js"));
179
+ const loadZaloChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-DiilvQ99.js"));
184
180
  const zaloSetupWizard = createZaloSetupWizardProxy(async () => (await import("./setup-surface-8eRimod9.js")).zaloSetupWizard);
185
181
  const zaloTextChunkLimit = 2e3;
186
- const zaloRawSendResultAdapter = createRawChannelSendResultAdapter({
182
+ async function sendZaloDelivery(ctx) {
183
+ const result = await (await loadZaloChannelRuntime()).sendZaloText({
184
+ to: ctx.to,
185
+ text: ctx.text,
186
+ accountId: ctx.accountId ?? void 0,
187
+ mediaUrl: ctx.mediaUrl,
188
+ cfg: ctx.cfg
189
+ });
190
+ if (!result.ok) throw new Error(result.error ?? `Failed to send Zalo ${ctx.mediaUrl ? "media" : "message"}`);
191
+ return {
192
+ messageId: result.messageId ?? "",
193
+ receipt: result.receipt
194
+ };
195
+ }
196
+ const zaloSendResultAdapter = createAttachedChannelResultAdapter({
187
197
  channel: "zalo",
188
- sendText: async ({ to, text, accountId, cfg }) => await (await loadZaloChannelRuntime()).sendZaloText({
189
- to,
190
- text,
191
- accountId: accountId ?? void 0,
192
- cfg
193
- }),
194
- sendMedia: async ({ to, text, mediaUrl, accountId, cfg }) => await (await loadZaloChannelRuntime()).sendZaloText({
195
- to,
196
- text,
197
- accountId: accountId ?? void 0,
198
- mediaUrl,
199
- cfg
200
- })
198
+ sendText: sendZaloDelivery,
199
+ sendMedia: sendZaloDelivery
201
200
  });
202
201
  const zaloMessageAdapter = defineChannelMessageAdapter({
203
202
  id: "zalo",
@@ -207,19 +206,8 @@ const zaloMessageAdapter = defineChannelMessageAdapter({
207
206
  messageSendingHooks: true
208
207
  } },
209
208
  send: {
210
- text: async ({ to, text, accountId, cfg }) => await (await loadZaloChannelRuntime()).sendZaloText({
211
- to,
212
- text,
213
- accountId: accountId ?? void 0,
214
- cfg
215
- }),
216
- media: async ({ to, text, mediaUrl, accountId, cfg }) => await (await loadZaloChannelRuntime()).sendZaloText({
217
- to,
218
- text,
219
- accountId: accountId ?? void 0,
220
- mediaUrl,
221
- cfg
222
- })
209
+ text: sendZaloDelivery,
210
+ media: sendZaloDelivery
223
211
  }
224
212
  });
225
213
  const zaloConfigAdapter = createScopedChannelConfigAdapter({
@@ -363,12 +351,12 @@ const zaloPlugin = createChatChannelPlugin({
363
351
  ctx,
364
352
  textChunkLimit: zaloTextChunkLimit,
365
353
  chunker: chunkTextForOutbound,
366
- sendText: (nextCtx) => zaloRawSendResultAdapter.sendText(nextCtx),
367
- sendMedia: (nextCtx) => zaloRawSendResultAdapter.sendMedia(nextCtx),
354
+ sendText: (nextCtx) => zaloSendResultAdapter.sendText(nextCtx),
355
+ sendMedia: (nextCtx) => zaloSendResultAdapter.sendMedia(nextCtx),
368
356
  emptyResult: createEmptyChannelResult("zalo"),
369
357
  onResult: ctx.onDeliveryResult
370
358
  }),
371
- ...zaloRawSendResultAdapter
359
+ ...zaloSendResultAdapter
372
360
  }
373
361
  });
374
362
  //#endregion
@@ -1,2 +1,2 @@
1
- import { t as zaloPlugin } from "./channel-BOWhJVyl.js";
1
+ import { t as zaloPlugin } from "./channel-C_73K8pR.js";
2
2
  export { zaloPlugin };
@@ -86,7 +86,7 @@ async function startZaloGatewayAccount(ctx) {
86
86
  setStatus: ctx.setStatus
87
87
  });
88
88
  ctx.log?.info(`[${account.accountId}] starting provider${zaloBotLabel} mode=${mode}`);
89
- const { monitorZaloProvider } = await import("./monitor-fgcJhAZL.js");
89
+ const { monitorZaloProvider } = await import("./monitor-alx9kzIY.js");
90
90
  return monitorZaloProvider({
91
91
  token,
92
92
  account,
@@ -12,7 +12,7 @@ import { registerPluginHttpRoute, resolveWebhookPath } from "openclaw/plugin-sdk
12
12
  import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
13
13
  import { formatInboundMediaUnavailableText } from "openclaw/plugin-sdk/channel-inbound";
14
14
  import { resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
15
- import { waitForAbortSignal } from "openclaw/plugin-sdk/runtime-env";
15
+ import { sleepWithAbort, waitForAbortSignal } from "openclaw/plugin-sdk/runtime-env";
16
16
  import { createHostedOutboundMediaStore } from "openclaw/plugin-sdk/outbound-media";
17
17
  //#region extensions/zalo/src/monitor-durable.ts
18
18
  function prepareZaloDurableReplyPayload(params) {
@@ -150,6 +150,10 @@ async function tryHandleHostedZaloMediaRequest(req, res) {
150
150
  }
151
151
  //#endregion
152
152
  //#region extensions/zalo/src/monitor.ts
153
+ /** Default idle timeout for Zalo inbound photo downloads (30 seconds). */
154
+ const ZALO_MEDIA_READ_IDLE_TIMEOUT_MS = 3e4;
155
+ /** Maximum wait for Zalo inbound photo response headers (120 seconds). */
156
+ const ZALO_MEDIA_RESPONSE_HEADER_TIMEOUT_MS = 12e4;
153
157
  const ZALO_TEXT_LIMIT = 2e3;
154
158
  const DEFAULT_MEDIA_MAX_MB = 5;
155
159
  const WEBHOOK_CLEANUP_TIMEOUT_MS = 5e3;
@@ -270,9 +274,7 @@ function startPollingLoop(params) {
270
274
  } catch (err) {
271
275
  if (err instanceof ZaloApiError && err.isPollingTimeout) {} else if (!isStopped() && !abortSignal.aborted) {
272
276
  runtime.error?.(`[${account.accountId}] Zalo polling error: ${formatZaloError(err)}`);
273
- await new Promise((resolve) => {
274
- setTimeout(resolve, 5e3);
275
- });
277
+ await sleepWithAbort(5e3, abortSignal).catch(() => void 0);
276
278
  }
277
279
  }
278
280
  if (!isStopped() && !abortSignal.aborted) setImmediate(() => {
@@ -347,7 +349,9 @@ async function handleImageMessage(params) {
347
349
  const maxBytes = mediaMaxMb * 1024 * 1024;
348
350
  const saved = await core.channel.media.saveRemoteMedia({
349
351
  url: photo_url,
350
- maxBytes
352
+ maxBytes,
353
+ responseHeaderTimeoutMs: ZALO_MEDIA_RESPONSE_HEADER_TIMEOUT_MS,
354
+ readIdleTimeoutMs: ZALO_MEDIA_READ_IDLE_TIMEOUT_MS
351
355
  });
352
356
  mediaPath = saved.path;
353
357
  mediaType = saved.contentType;
@@ -1,51 +1,10 @@
1
- import { collectConditionalChannelFieldAssignments, getChannelSurface, hasOwnProperty } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
1
+ import { collectConditionalChannelFieldAssignments, createChannelSecretTargetRegistryEntries, getChannelSurface, hasOwnProperty } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
2
2
  //#region extensions/zalo/src/secret-contract.ts
3
- const secretTargetRegistryEntries = [
4
- {
5
- id: "channels.zalo.accounts.*.botToken",
6
- targetType: "channels.zalo.accounts.*.botToken",
7
- configFile: "openclaw.json",
8
- pathPattern: "channels.zalo.accounts.*.botToken",
9
- secretShape: "secret_input",
10
- expectedResolvedValue: "string",
11
- includeInPlan: true,
12
- includeInConfigure: true,
13
- includeInAudit: true
14
- },
15
- {
16
- id: "channels.zalo.accounts.*.webhookSecret",
17
- targetType: "channels.zalo.accounts.*.webhookSecret",
18
- configFile: "openclaw.json",
19
- pathPattern: "channels.zalo.accounts.*.webhookSecret",
20
- secretShape: "secret_input",
21
- expectedResolvedValue: "string",
22
- includeInPlan: true,
23
- includeInConfigure: true,
24
- includeInAudit: true
25
- },
26
- {
27
- id: "channels.zalo.botToken",
28
- targetType: "channels.zalo.botToken",
29
- configFile: "openclaw.json",
30
- pathPattern: "channels.zalo.botToken",
31
- secretShape: "secret_input",
32
- expectedResolvedValue: "string",
33
- includeInPlan: true,
34
- includeInConfigure: true,
35
- includeInAudit: true
36
- },
37
- {
38
- id: "channels.zalo.webhookSecret",
39
- targetType: "channels.zalo.webhookSecret",
40
- configFile: "openclaw.json",
41
- pathPattern: "channels.zalo.webhookSecret",
42
- secretShape: "secret_input",
43
- expectedResolvedValue: "string",
44
- includeInPlan: true,
45
- includeInConfigure: true,
46
- includeInAudit: true
47
- }
48
- ];
3
+ const secretTargetRegistryEntries = createChannelSecretTargetRegistryEntries({
4
+ channelKey: "zalo",
5
+ account: ["botToken", "webhookSecret"],
6
+ channel: ["botToken", "webhookSecret"]
7
+ });
49
8
  function collectRuntimeConfigAssignments(params) {
50
9
  const resolved = getChannelSurface(params.config, "zalo");
51
10
  if (!resolved) return;
@@ -1,2 +1,2 @@
1
- import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-Bno_huZF.js";
1
+ import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-Bxvjh0Hq.js";
2
2
  export { channelSecrets, collectRuntimeConfigAssignments, secretTargetRegistryEntries };
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@openclaw/zalo",
3
- "version": "2026.7.1-beta.6",
3
+ "version": "2026.7.2-beta.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/zalo",
9
- "version": "2026.7.1-beta.6",
9
+ "version": "2026.7.2-beta.1",
10
10
  "dependencies": {
11
11
  "zod": "4.4.3"
12
12
  },
13
13
  "peerDependencies": {
14
- "openclaw": ">=2026.7.1-beta.6"
14
+ "openclaw": ">=2026.7.2-beta.1"
15
15
  },
16
16
  "peerDependenciesMeta": {
17
17
  "openclaw": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/zalo",
3
- "version": "2026.7.1-beta.6",
3
+ "version": "2026.7.2-beta.1",
4
4
  "description": "OpenClaw Zalo channel plugin for bot and webhook chats.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "type": "module",
10
10
  "peerDependencies": {
11
- "openclaw": ">=2026.7.1-beta.6"
11
+ "openclaw": ">=2026.7.2-beta.1"
12
12
  },
13
13
  "peerDependenciesMeta": {
14
14
  "openclaw": {
@@ -39,10 +39,10 @@
39
39
  "minHostVersion": ">=2026.4.10"
40
40
  },
41
41
  "compat": {
42
- "pluginApi": ">=2026.7.1-beta.6"
42
+ "pluginApi": ">=2026.7.2-beta.1"
43
43
  },
44
44
  "build": {
45
- "openclawVersion": "2026.7.1-beta.6"
45
+ "openclawVersion": "2026.7.2-beta.1"
46
46
  },
47
47
  "release": {
48
48
  "publishToClawHub": true,