@openclaw/zalo 2026.7.1 → 2026.7.2-beta.2

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-CBPOM3Pc.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,25 +7,26 @@ 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";
14
14
  import { createLazyRuntimeModule, createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
15
15
  import { sendPayloadWithChunkedTextAndMedia } from "openclaw/plugin-sdk/reply-payload";
16
- import { createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
16
+ import { createComputedAccountStatusAdapter, createDefaultChannelRuntimeState, standardDmPolicyOpenIssue } from "openclaw/plugin-sdk/status-helpers";
17
17
  import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
18
18
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
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";
23
- import { AllowFromListSchema, DmPolicySchema, GroupPolicySchema, MarkdownConfigSchema, buildCatchallMultiAccountChannelSchema } from "openclaw/plugin-sdk/channel-config-schema";
22
+ import { createChannelApprovalAuth } from "openclaw/plugin-sdk/approval-auth-runtime";
23
+ import { AllowFromListSchema, DmPolicySchema, GroupPolicySchema, MarkdownConfigSchema, buildMultiAccountChannelSchema } from "openclaw/plugin-sdk/channel-config-schema";
24
24
  import { z } from "zod";
25
25
  import { coerceStatusIssueAccountId, readStatusIssueFields } from "openclaw/plugin-sdk/extension-shared";
26
26
  //#region extensions/zalo/src/actions.ts
27
27
  const loadZaloActionsRuntime = createLazyRuntimeNamedExport(() => import("./actions.runtime-OmfJFYZn.js"), "zaloActionsRuntime");
28
28
  const providerId = "zalo";
29
+ const ZALO_ACTIONS = /* @__PURE__ */ new Set(["send"]);
29
30
  function listEnabledAccounts(cfg, accountId) {
30
31
  return (accountId ? [resolveZaloAccount({
31
32
  cfg,
@@ -35,12 +36,12 @@ function listEnabledAccounts(cfg, accountId) {
35
36
  const zaloMessageActions = {
36
37
  describeMessageTool: ({ cfg, accountId }) => {
37
38
  if (listEnabledAccounts(cfg, accountId).length === 0) return null;
38
- const actions = /* @__PURE__ */ new Set(["send"]);
39
39
  return {
40
- actions: Array.from(actions),
40
+ actions: Array.from(ZALO_ACTIONS),
41
41
  capabilities: []
42
42
  };
43
43
  },
44
+ supportsAction: ({ action }) => ZALO_ACTIONS.has(action),
44
45
  extractToolSend: ({ args }) => extractToolSend(args, "sendMessage"),
45
46
  handleAction: async ({ action, params, cfg, accountId }) => {
46
47
  if (action === "send") {
@@ -75,21 +76,17 @@ function normalizeZaloApproverId(value) {
75
76
  const normalized = String(value).trim().replace(/^(zalo|zl):/i, "").trim();
76
77
  return /^\d+$/.test(normalized) ? normalized : void 0;
77
78
  }
78
- const zaloApprovalAuth = createResolvedApproverActionAuthAdapter({
79
+ const zaloApprovalAuth = createChannelApprovalAuth({
79
80
  channelLabel: "Zalo",
80
- resolveApprovers: ({ cfg, accountId }) => {
81
- const account = resolveZaloAccount({
81
+ resolveInputs: ({ cfg, accountId }) => {
82
+ return { allowFrom: resolveZaloAccount({
82
83
  cfg,
83
84
  accountId
84
- }).config;
85
- return resolveApprovalApprovers({
86
- allowFrom: account.allowFrom,
87
- normalizeApprover: normalizeZaloApproverId
88
- });
85
+ }).config.allowFrom };
89
86
  },
90
- normalizeSenderId: (value) => normalizeZaloApproverId(value)
91
- });
92
- const ZaloConfigSchema = buildCatchallMultiAccountChannelSchema(z.object({
87
+ normalizeApprover: normalizeZaloApproverId
88
+ }).approvalAuth;
89
+ const ZaloConfigSchema = buildMultiAccountChannelSchema(z.object({
93
90
  name: z.string().optional(),
94
91
  enabled: z.boolean().optional(),
95
92
  markdown: MarkdownConfigSchema,
@@ -105,7 +102,7 @@ const ZaloConfigSchema = buildCatchallMultiAccountChannelSchema(z.object({
105
102
  mediaMaxMb: z.number().optional(),
106
103
  proxy: z.string().optional(),
107
104
  responsePrefix: z.string().optional()
108
- }));
105
+ }), { accountsMode: "catchall" });
109
106
  //#endregion
110
107
  //#region extensions/zalo/src/session-route.ts
111
108
  function resolveZaloOutboundSessionRoute(params) {
@@ -148,13 +145,12 @@ function collectZaloStatusIssues(accounts) {
148
145
  const enabled = account.enabled !== false;
149
146
  const configured = account.configured === true;
150
147
  if (!enabled || !configured) continue;
151
- if (account.dmPolicy === "open") issues.push({
148
+ if (account.dmPolicy === "open") issues.push(standardDmPolicyOpenIssue({
152
149
  channel: "zalo",
153
150
  accountId,
154
- kind: "config",
155
- message: "Zalo dmPolicy is \"open\", allowing any user to message the bot without pairing.",
156
- fix: "Set channels.zalo.dmPolicy to \"pairing\" or \"allowlist\" to restrict access."
157
- });
151
+ channelLabel: "Zalo",
152
+ configPath: "channels.zalo"
153
+ }));
158
154
  }
159
155
  return issues;
160
156
  }
@@ -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-BsZBukDW.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-CBPOM3Pc.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-DTi243P3.js");
90
90
  return monitorZaloProvider({
91
91
  token,
92
92
  account,
@@ -12,8 +12,9 @@ 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
+ import { safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
17
18
  //#region extensions/zalo/src/monitor-durable.ts
18
19
  function prepareZaloDurableReplyPayload(params) {
19
20
  if (!params.payload.text) return params.payload;
@@ -129,7 +130,7 @@ async function tryHandleHostedZaloMediaRequest(req, res) {
129
130
  res.end("Expired");
130
131
  return true;
131
132
  }
132
- if (url.searchParams.get("token") !== entry.metadata.token) {
133
+ if (!safeEqualSecret(url.searchParams.get("token"), entry.metadata.token)) {
133
134
  res.statusCode = 401;
134
135
  res.end("Unauthorized");
135
136
  return true;
@@ -150,6 +151,10 @@ async function tryHandleHostedZaloMediaRequest(req, res) {
150
151
  }
151
152
  //#endregion
152
153
  //#region extensions/zalo/src/monitor.ts
154
+ /** Default idle timeout for Zalo inbound photo downloads (30 seconds). */
155
+ const ZALO_MEDIA_READ_IDLE_TIMEOUT_MS = 3e4;
156
+ /** Maximum wait for Zalo inbound photo response headers (120 seconds). */
157
+ const ZALO_MEDIA_RESPONSE_HEADER_TIMEOUT_MS = 12e4;
153
158
  const ZALO_TEXT_LIMIT = 2e3;
154
159
  const DEFAULT_MEDIA_MAX_MB = 5;
155
160
  const WEBHOOK_CLEANUP_TIMEOUT_MS = 5e3;
@@ -160,7 +165,7 @@ function resolveZaloTimestampMs(date) {
160
165
  if (!date) return;
161
166
  return date >= UNIX_MILLISECONDS_THRESHOLD ? date : date * 1e3;
162
167
  }
163
- const loadZaloWebhookModule = createLazyRuntimeModule(() => import("./monitor.webhook-AYcIUBBP.js"));
168
+ const loadZaloWebhookModule = createLazyRuntimeModule(() => import("./monitor.webhook-BFkM-Syx.js"));
164
169
  function releaseSharedHostedMediaRouteRef(routePath) {
165
170
  const current = hostedMediaRouteRefs.get(routePath);
166
171
  if (!current) return;
@@ -270,9 +275,7 @@ function startPollingLoop(params) {
270
275
  } catch (err) {
271
276
  if (err instanceof ZaloApiError && err.isPollingTimeout) {} else if (!isStopped() && !abortSignal.aborted) {
272
277
  runtime.error?.(`[${account.accountId}] Zalo polling error: ${formatZaloError(err)}`);
273
- await new Promise((resolve) => {
274
- setTimeout(resolve, 5e3);
275
- });
278
+ await sleepWithAbort(5e3, abortSignal).catch(() => void 0);
276
279
  }
277
280
  }
278
281
  if (!isStopped() && !abortSignal.aborted) setImmediate(() => {
@@ -347,7 +350,9 @@ async function handleImageMessage(params) {
347
350
  const maxBytes = mediaMaxMb * 1024 * 1024;
348
351
  const saved = await core.channel.media.saveRemoteMedia({
349
352
  url: photo_url,
350
- maxBytes
353
+ maxBytes,
354
+ responseHeaderTimeoutMs: ZALO_MEDIA_RESPONSE_HEADER_TIMEOUT_MS,
355
+ readIdleTimeoutMs: ZALO_MEDIA_READ_IDLE_TIMEOUT_MS
351
356
  });
352
357
  mediaPath = saved.path;
353
358
  mediaType = saved.contentType;
@@ -1,6 +1,7 @@
1
1
  import { B as registerWebhookTargetWithPluginRoute, I as readJsonWebhookBodyOrReject, K as resolveWebhookTargetWithAuthOrRejectSync, Q as withResolvedWebhookRequestPipeline, V as resolveClientIp, a as WEBHOOK_ANOMALY_COUNTER_DEFAULTS, b as createFixedWindowRateLimiter, l as applyBasicWebhookRequestGuards, o as WEBHOOK_RATE_LIMIT_DEFAULTS, x as createWebhookAnomalyTracker, z as registerWebhookTarget } from "./runtime-api-CAA4ZtqF.js";
2
- import { createClaimableDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
3
2
  import { safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
3
+ import { createChannelReplayGuard } from "openclaw/plugin-sdk/persistent-dedupe";
4
+ import { runDetachedWebhookWork } from "openclaw/plugin-sdk/webhook-request-guards";
4
5
  //#region extensions/zalo/src/monitor.webhook.ts
5
6
  const ZALO_WEBHOOK_REPLAY_WINDOW_MS = 5 * 6e4;
6
7
  const webhookTargets = /* @__PURE__ */ new Map();
@@ -9,10 +10,6 @@ const webhookRateLimiter = createFixedWindowRateLimiter({
9
10
  maxRequests: WEBHOOK_RATE_LIMIT_DEFAULTS.maxRequests,
10
11
  maxTrackedKeys: WEBHOOK_RATE_LIMIT_DEFAULTS.maxTrackedKeys
11
12
  });
12
- const recentWebhookEvents = createClaimableDedupe({
13
- ttlMs: ZALO_WEBHOOK_REPLAY_WINDOW_MS,
14
- memoryMaxSize: 5e3
15
- });
16
13
  const webhookAnomalyTracker = createWebhookAnomalyTracker({
17
14
  maxTrackedKeys: WEBHOOK_ANOMALY_COUNTER_DEFAULTS.maxTrackedKeys,
18
15
  ttlMs: WEBHOOK_ANOMALY_COUNTER_DEFAULTS.ttlMs,
@@ -43,6 +40,13 @@ function buildReplayEventCacheKey(target, update) {
43
40
  messageId
44
41
  ]);
45
42
  }
43
+ const recentWebhookEvents = createChannelReplayGuard({
44
+ dedupe: {
45
+ ttlMs: ZALO_WEBHOOK_REPLAY_WINDOW_MS,
46
+ memoryMaxSize: 5e3
47
+ },
48
+ buildReplayKey: ({ target, update }) => buildReplayEventCacheKey(target, update)
49
+ });
46
50
  var ZaloRetryableWebhookError = class extends Error {
47
51
  constructor(message, options) {
48
52
  super(message, options);
@@ -50,23 +54,17 @@ var ZaloRetryableWebhookError = class extends Error {
50
54
  }
51
55
  };
52
56
  async function processZaloReplayGuardedUpdate(params) {
53
- const replayEventKey = buildReplayEventCacheKey(params.target, params.update);
54
- if (replayEventKey) {
55
- if ((await recentWebhookEvents.claim(replayEventKey, { now: params.nowMs })).kind !== "claimed") return "duplicate";
56
- }
57
- params.target.statusSink?.({ lastInboundAt: Date.now() });
58
- try {
59
- await params.processUpdate({
60
- update: params.update,
61
- target: params.target
62
- });
63
- if (replayEventKey) await recentWebhookEvents.commit(replayEventKey);
64
- return "processed";
65
- } catch (error) {
66
- if (replayEventKey) if (error instanceof ZaloRetryableWebhookError) recentWebhookEvents.release(replayEventKey, { error });
67
- else await recentWebhookEvents.commit(replayEventKey);
68
- throw error;
69
- }
57
+ const event = {
58
+ target: params.target,
59
+ update: params.update
60
+ };
61
+ return (await recentWebhookEvents.processGuarded(event, async () => {
62
+ params.target.statusSink?.({ lastInboundAt: Date.now() });
63
+ await params.processUpdate(event);
64
+ }, {
65
+ dedupe: { now: params.nowMs },
66
+ onError: (error) => error instanceof ZaloRetryableWebhookError ? "release" : "commit"
67
+ })).kind === "processed" ? "processed" : "duplicate";
70
68
  }
71
69
  function recordWebhookStatus(runtime, path, statusCode) {
72
70
  webhookAnomalyTracker.record({
@@ -154,12 +152,12 @@ async function handleZaloWebhookRequest(req, res, processUpdate) {
154
152
  recordWebhookStatus(target.runtime, path, res.statusCode);
155
153
  return true;
156
154
  }
157
- processZaloReplayGuardedUpdate({
155
+ runDetachedWebhookWork(() => processZaloReplayGuardedUpdate({
158
156
  target,
159
157
  update,
160
158
  processUpdate,
161
159
  nowMs
162
- }).catch((err) => {
160
+ })).catch((err) => {
163
161
  target.runtime.error?.(`[${target.account.accountId}] Zalo webhook failed: ${String(err)}`);
164
162
  });
165
163
  res.statusCode = 200;
@@ -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",
3
+ "version": "2026.7.2-beta.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/zalo",
9
- "version": "2026.7.1",
9
+ "version": "2026.7.2-beta.2",
10
10
  "dependencies": {
11
11
  "zod": "4.4.3"
12
12
  },
13
13
  "peerDependencies": {
14
- "openclaw": ">=2026.7.1"
14
+ "openclaw": ">=2026.7.2-beta.2"
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",
3
+ "version": "2026.7.2-beta.2",
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"
11
+ "openclaw": ">=2026.7.2-beta.2"
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"
42
+ "pluginApi": ">=2026.7.2-beta.2"
43
43
  },
44
44
  "build": {
45
- "openclawVersion": "2026.7.1"
45
+ "openclawVersion": "2026.7.2-beta.2"
46
46
  },
47
47
  "release": {
48
48
  "publishToClawHub": true,