@openclaw/zalo 2026.7.1-beta.2 → 2026.7.1-beta.5

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.
@@ -1,4 +1,4 @@
1
- import { t as sendMessageZalo } from "./send-Bv6fMYcy.js";
1
+ import { t as sendMessageZalo } from "./send-9sVVxyap.js";
2
2
  //#region extensions/zalo/src/actions.runtime.ts
3
3
  const zaloActionsRuntime = { sendMessageZalo };
4
4
  //#endregion
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-DAsgqZBL.js";
2
+ import { t as zaloPlugin } from "./channel-BOWhJVyl.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 };
@@ -12,7 +12,7 @@ import { buildTokenChannelStatusSummary } from "openclaw/plugin-sdk/channel-stat
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
- import { isNumericTargetId, sendPayloadWithChunkedTextAndMedia } from "openclaw/plugin-sdk/reply-payload";
15
+ import { sendPayloadWithChunkedTextAndMedia } from "openclaw/plugin-sdk/reply-payload";
16
16
  import { createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } 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";
@@ -24,7 +24,7 @@ import { AllowFromListSchema, DmPolicySchema, GroupPolicySchema, MarkdownConfigS
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
- const loadZaloActionsRuntime = createLazyRuntimeNamedExport(() => import("./actions.runtime-Dn2ZiJpf.js"), "zaloActionsRuntime");
27
+ const loadZaloActionsRuntime = createLazyRuntimeNamedExport(() => import("./actions.runtime-OmfJFYZn.js"), "zaloActionsRuntime");
28
28
  const providerId = "zalo";
29
29
  function listEnabledAccounts(cfg, accountId) {
30
30
  return (accountId ? [resolveZaloAccount({
@@ -35,7 +35,7 @@ function listEnabledAccounts(cfg, accountId) {
35
35
  const zaloMessageActions = {
36
36
  describeMessageTool: ({ cfg, accountId }) => {
37
37
  if (listEnabledAccounts(cfg, accountId).length === 0) return null;
38
- const actions = new Set(["send"]);
38
+ const actions = /* @__PURE__ */ new Set(["send"]);
39
39
  return {
40
40
  actions: Array.from(actions),
41
41
  capabilities: []
@@ -111,7 +111,9 @@ const ZaloConfigSchema = buildCatchallMultiAccountChannelSchema(z.object({
111
111
  function resolveZaloOutboundSessionRoute(params) {
112
112
  const trimmed = stripChannelTargetPrefix(params.target, "zalo", "zl");
113
113
  if (!trimmed) return null;
114
- const isGroup = normalizeLowercaseStringOrEmpty(trimmed).startsWith("group:");
114
+ const normalizedTarget = normalizeLowercaseStringOrEmpty(trimmed);
115
+ const isGroup = normalizedTarget.startsWith("group:");
116
+ const recipientSessionExact = /^(?:group|user|dm):/.test(normalizedTarget);
115
117
  const peerId = stripTargetKindPrefix(trimmed);
116
118
  if (!peerId) return null;
117
119
  return buildChannelOutboundSessionRoute({
@@ -119,6 +121,7 @@ function resolveZaloOutboundSessionRoute(params) {
119
121
  agentId: params.agentId,
120
122
  channel: "zalo",
121
123
  accountId: params.accountId,
124
+ recipientSessionExact,
122
125
  peer: {
123
126
  kind: isGroup ? "group" : "direct",
124
127
  id: peerId
@@ -173,7 +176,11 @@ function normalizeZaloMessagingTarget(raw) {
173
176
  if (!trimmed) return;
174
177
  return trimmed.replace(/^(zalo|zl):/i, "").trim();
175
178
  }
176
- const loadZaloChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-B3bsfcE4.js"));
179
+ function looksLikeZaloChatId(raw, normalized) {
180
+ const target = normalizeZaloMessagingTarget(normalized ?? raw);
181
+ return Boolean(target);
182
+ }
183
+ const loadZaloChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-CEPgF8Zo.js"));
177
184
  const zaloSetupWizard = createZaloSetupWizardProxy(async () => (await import("./setup-surface-8eRimod9.js")).zaloSetupWizard);
178
185
  const zaloTextChunkLimit = 2e3;
179
186
  const zaloRawSendResultAdapter = createRawChannelSendResultAdapter({
@@ -297,7 +304,7 @@ const zaloPlugin = createChatChannelPlugin({
297
304
  normalizeTarget: normalizeZaloMessagingTarget,
298
305
  resolveOutboundSessionRoute: (params) => resolveZaloOutboundSessionRoute(params),
299
306
  targetResolver: {
300
- looksLikeId: isNumericTargetId,
307
+ looksLikeId: looksLikeZaloChatId,
301
308
  hint: "<chatId>"
302
309
  }
303
310
  },
@@ -358,7 +365,8 @@ const zaloPlugin = createChatChannelPlugin({
358
365
  chunker: chunkTextForOutbound,
359
366
  sendText: (nextCtx) => zaloRawSendResultAdapter.sendText(nextCtx),
360
367
  sendMedia: (nextCtx) => zaloRawSendResultAdapter.sendMedia(nextCtx),
361
- emptyResult: createEmptyChannelResult("zalo")
368
+ emptyResult: createEmptyChannelResult("zalo"),
369
+ onResult: ctx.onDeliveryResult
362
370
  }),
363
371
  ...zaloRawSendResultAdapter
364
372
  }
@@ -1,2 +1,2 @@
1
- import { t as zaloPlugin } from "./channel-DAsgqZBL.js";
1
+ import { t as zaloPlugin } from "./channel-BOWhJVyl.js";
2
2
  export { zaloPlugin };
@@ -1,6 +1,6 @@
1
1
  import { p as normalizeSecretInputString } from "./setup-core-fwCh0QUi.js";
2
- import { i as PAIRING_APPROVED_MESSAGE } from "./runtime-api-CDwUY_-_.js";
3
- import { a as getMe, n as resolveZaloProxyFetch, r as ZaloApiError, t as sendMessageZalo } from "./send-Bv6fMYcy.js";
2
+ import { i as PAIRING_APPROVED_MESSAGE } from "./runtime-api-CAA4ZtqF.js";
3
+ import { a as getMe, n as resolveZaloProxyFetch, r as ZaloApiError, t as sendMessageZalo } from "./send-9sVVxyap.js";
4
4
  import { createAccountStatusSink } from "openclaw/plugin-sdk/channel-outbound";
5
5
  //#region extensions/zalo/src/probe.ts
6
6
  async function probeZalo(token, timeoutMs = 5e3, fetcher) {
@@ -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-CH3X2uV7.js");
89
+ const { monitorZaloProvider } = await import("./monitor-fgcJhAZL.js");
90
90
  return monitorZaloProvider({
91
91
  token,
92
92
  account,
@@ -1,6 +1,6 @@
1
1
  import { n as resolveZaloRuntimeGroupPolicy, t as normalizeZaloAllowEntry } from "./group-access-8qHRzDHx.js";
2
- import { t as getZaloRuntime } from "./runtime-api-CDwUY_-_.js";
3
- import { c as sendChatAction, d as setWebhook, i as deleteWebhook, l as sendMessage, n as resolveZaloProxyFetch, o as getUpdates, r as ZaloApiError, s as getWebhookInfo, u as sendPhoto } from "./send-Bv6fMYcy.js";
2
+ import { t as getZaloRuntime } from "./runtime-api-CAA4ZtqF.js";
3
+ import { c as sendChatAction, d as setWebhook, i as deleteWebhook, l as sendMessage, n as resolveZaloProxyFetch, o as getUpdates, r as ZaloApiError, s as getWebhookInfo, u as sendPhoto } from "./send-9sVVxyap.js";
4
4
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
5
5
  import { deliverTextOrMediaReply, resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
6
6
  import { normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -10,6 +10,7 @@ import { logTypingFailure } from "openclaw/plugin-sdk/channel-feedback";
10
10
  import { resolveInboundRouteEnvelopeBuilderWithRuntime } from "openclaw/plugin-sdk/inbound-envelope";
11
11
  import { registerPluginHttpRoute, resolveWebhookPath } from "openclaw/plugin-sdk/webhook-ingress";
12
12
  import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
13
+ import { formatInboundMediaUnavailableText } from "openclaw/plugin-sdk/channel-inbound";
13
14
  import { resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
14
15
  import { waitForAbortSignal } from "openclaw/plugin-sdk/runtime-env";
15
16
  import { createHostedOutboundMediaStore } from "openclaw/plugin-sdk/outbound-media";
@@ -159,7 +160,7 @@ function resolveZaloTimestampMs(date) {
159
160
  if (!date) return;
160
161
  return date >= UNIX_MILLISECONDS_THRESHOLD ? date : date * 1e3;
161
162
  }
162
- const loadZaloWebhookModule = createLazyRuntimeModule(() => import("./monitor.webhook-B23mUx-y.js"));
163
+ const loadZaloWebhookModule = createLazyRuntimeModule(() => import("./monitor.webhook-AYcIUBBP.js"));
163
164
  function releaseSharedHostedMediaRouteRef(routePath) {
164
165
  const current = hostedMediaRouteRefs.get(routePath);
165
166
  if (!current) return;
@@ -336,7 +337,7 @@ async function handleImageMessage(params) {
336
337
  const authorization = await authorizeZaloMessage({
337
338
  ...params,
338
339
  text: caption,
339
- mediaPath: photo_url ? "__pending_media__" : void 0,
340
+ mediaPath: "__pending_media__",
340
341
  mediaType: void 0
341
342
  });
342
343
  if (!authorization) return;
@@ -353,9 +354,15 @@ async function handleImageMessage(params) {
353
354
  } catch (err) {
354
355
  runtime.error?.(`[${account.accountId}] Failed to download Zalo image: ${String(err)}`);
355
356
  }
357
+ const agentBody = mediaPath ? authorization.rawBody : formatInboundMediaUnavailableText({
358
+ body: caption,
359
+ mediaPlaceholder: "<media:image>",
360
+ notice: "[zalo image attachment unavailable]"
361
+ });
356
362
  await processMessageWithPipeline({
357
363
  ...params,
358
364
  authorization,
365
+ agentBody,
359
366
  text: caption,
360
367
  mediaPath,
361
368
  mediaType
@@ -457,7 +464,7 @@ async function authorizeZaloMessage(params) {
457
464
  };
458
465
  }
459
466
  async function processMessageWithPipeline(params) {
460
- const { message, token, account, config, runtime, core, mediaPath, mediaType, statusSink, fetcher, authorization: authorizationOverride } = params;
467
+ const { message, token, account, config, runtime, core, mediaPath, mediaType, statusSink, fetcher, agentBody: agentBodyOverride, authorization: authorizationOverride } = params;
461
468
  const { message_id, date } = message;
462
469
  const authorization = authorizationOverride ?? await authorizeZaloMessage({
463
470
  ...params,
@@ -466,6 +473,7 @@ async function processMessageWithPipeline(params) {
466
473
  });
467
474
  if (!authorization) return;
468
475
  const { isGroup, chatId, senderId, senderName, rawBody, commandAuthorized } = authorization;
476
+ const agentBody = agentBodyOverride ?? rawBody;
469
477
  const { route, buildEnvelope } = resolveInboundRouteEnvelopeBuilderWithRuntime({
470
478
  cfg: config,
471
479
  channel: "zalo",
@@ -487,7 +495,7 @@ async function processMessageWithPipeline(params) {
487
495
  channel: "Zalo",
488
496
  from: fromLabel,
489
497
  timestamp,
490
- body: rawBody
498
+ body: agentBody
491
499
  });
492
500
  const ctxPayload = core.channel.inbound.buildContext({
493
501
  channel: "zalo",
@@ -512,7 +520,7 @@ async function processMessageWithPipeline(params) {
512
520
  reply: { to: `zalo:${chatId}` },
513
521
  message: {
514
522
  body,
515
- bodyForAgent: rawBody,
523
+ bodyForAgent: agentBody,
516
524
  rawBody,
517
525
  commandBody: rawBody
518
526
  },
@@ -621,15 +629,16 @@ async function deliverZaloReply(params) {
621
629
  }
622
630
  },
623
631
  sendMedia: async ({ mediaUrl, caption }) => {
632
+ const sendableMediaUrl = canHostMedia && webhookUrl && webhookPath ? await prepareHostedZaloMediaUrl({
633
+ mediaUrl,
634
+ webhookUrl,
635
+ webhookPath,
636
+ maxBytes: mediaMaxBytes,
637
+ proxyUrl
638
+ }) : mediaUrl;
624
639
  await sendPhoto(token, {
625
640
  chat_id: chatId,
626
- photo: canHostMedia && webhookUrl && webhookPath ? await prepareHostedZaloMediaUrl({
627
- mediaUrl,
628
- webhookUrl,
629
- webhookPath,
630
- maxBytes: mediaMaxBytes,
631
- proxyUrl
632
- }) : mediaUrl,
641
+ photo: sendableMediaUrl,
633
642
  caption
634
643
  }, fetcher);
635
644
  statusSink?.({ lastOutboundAt: Date.now() });
@@ -1,4 +1,4 @@
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-CDwUY_-_.js";
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
2
  import { createClaimableDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
3
3
  import { safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
4
4
  //#region extensions/zalo/src/monitor.webhook.ts
@@ -29,9 +29,6 @@ function getZaloWebhookRateLimitStateSizeForTest() {
29
29
  function getZaloWebhookStatusCounterSizeForTest() {
30
30
  return webhookAnomalyTracker.size();
31
31
  }
32
- function timingSafeEquals(left, right) {
33
- return safeEqualSecret(left, right);
34
- }
35
32
  function buildReplayEventCacheKey(target, update) {
36
33
  const messageId = update.message?.message_id;
37
34
  if (!messageId) return null;
@@ -122,7 +119,7 @@ async function handleZaloWebhookRequest(req, res, processUpdate) {
122
119
  const target = resolveWebhookTargetWithAuthOrRejectSync({
123
120
  targets,
124
121
  res,
125
- isMatch: (entry) => timingSafeEquals(entry.secret, headerToken)
122
+ isMatch: (entry) => safeEqualSecret(entry.secret, headerToken)
126
123
  });
127
124
  if (!target) {
128
125
  recordWebhookStatus(targets[0]?.runtime, path, res.statusCode);
@@ -172,4 +169,4 @@ async function handleZaloWebhookRequest(req, res, processUpdate) {
172
169
  });
173
170
  }
174
171
  //#endregion
175
- export { ZaloRetryableWebhookError, clearZaloWebhookSecurityStateForTest, getZaloWebhookRateLimitStateSizeForTest, getZaloWebhookStatusCounterSizeForTest, handleZaloWebhookRequest, processZaloReplayGuardedUpdate, registerZaloWebhookTarget };
172
+ export { ZaloRetryableWebhookError, clearZaloWebhookSecurityStateForTest, getZaloWebhookRateLimitStateSizeForTest, getZaloWebhookStatusCounterSizeForTest, handleZaloWebhookRequest, registerZaloWebhookTarget };
@@ -1,7 +1,7 @@
1
1
  import { formatAllowFromLowercase as formatAllowFromLowercase$1, isNormalizedSenderAllowed } from "openclaw/plugin-sdk/allow-from";
2
2
  import { createChannelMessageReplyPipeline } from "openclaw/plugin-sdk/channel-outbound";
3
3
  import { PAIRING_APPROVED_MESSAGE, buildTokenChannelStatusSummary as buildTokenChannelStatusSummary$1 } from "openclaw/plugin-sdk/channel-status";
4
- import { deliverTextOrMediaReply as deliverTextOrMediaReply$1, isNumericTargetId as isNumericTargetId$1, sendPayloadWithChunkedTextAndMedia as sendPayloadWithChunkedTextAndMedia$1 } from "openclaw/plugin-sdk/reply-payload";
4
+ import { deliverTextOrMediaReply as deliverTextOrMediaReply$1, isNumericTargetId, sendPayloadWithChunkedTextAndMedia as sendPayloadWithChunkedTextAndMedia$1 } from "openclaw/plugin-sdk/reply-payload";
5
5
  import { buildBaseAccountStatusSnapshot } from "openclaw/plugin-sdk/status-helpers";
6
6
  import { chunkTextForOutbound as chunkTextForOutbound$1 } from "openclaw/plugin-sdk/text-chunking";
7
7
  import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, buildChannelConfigSchema, createDedupeCache, formatPairingApproveHint, jsonResult, normalizeAccountId as normalizeAccountId$1, readStringParam, resolveClientIp } from "openclaw/plugin-sdk/core";
@@ -20,4 +20,4 @@ const { setRuntime: setZaloRuntime, getRuntime: getZaloRuntime } = createPluginR
20
20
  errorMessage: "Zalo runtime not initialized"
21
21
  });
22
22
  //#endregion
23
- export { mergeAllowFromEntries$1 as A, registerWebhookTargetWithPluginRoute as B, formatAllowFromLowercase$1 as C, isNumericTargetId$1 as D, isNormalizedSenderAllowed as E, promptSingleChannelSecretInput$1 as F, resolveWebhookPath$1 as G, resolveDefaultGroupPolicy$1 as H, readJsonWebhookBodyOrReject as I, sendPayloadWithChunkedTextAndMedia$1 as J, resolveWebhookTargetWithAuthOrRejectSync as K, readStringParam as L, normalizeAccountId$1 as M, normalizeResolvedSecretInputString as N, jsonResult as O, normalizeSecretInputString as P, withResolvedWebhookRequestPipeline as Q, registerPluginHttpRoute$1 as R, deliverTextOrMediaReply$1 as S, hasConfiguredSecretInput$1 as T, resolveInboundRouteEnvelopeBuilderWithRuntime$1 as U, resolveClientIp as V, resolveOpenProviderRuntimeGroupPolicy$1 as W, waitForAbortSignal as X, setTopLevelChannelDmPolicyWithAllowFrom as Y, warnMissingProviderGroupPolicyFallbackOnce$1 as Z, createChannelMessageReplyPipeline as _, WEBHOOK_ANOMALY_COUNTER_DEFAULTS as a, createFixedWindowRateLimiter as b, applyAccountNameToChannelSection as c, buildBaseAccountStatusSnapshot as d, buildChannelConfigSchema as f, chunkTextForOutbound$1 as g, buildTokenChannelStatusSummary$1 as h, PAIRING_APPROVED_MESSAGE as i, migrateBaseNameToDefaultAccount as j, logTypingFailure$1 as k, applyBasicWebhookRequestGuards as l, buildSingleChannelSecretPromptState$1 as m, setZaloRuntime as n, WEBHOOK_RATE_LIMIT_DEFAULTS as o, buildSecretInputSchema as p, runSingleChannelSecretStep$1 as q, DEFAULT_ACCOUNT_ID$1 as r, addWildcardAllowFrom$1 as s, getZaloRuntime as t, applySetupAccountConfigPatch as u, createChannelPairingController$1 as v, formatPairingApproveHint as w, createWebhookAnomalyTracker as x, createDedupeCache as y, registerWebhookTarget as z };
23
+ export { mergeAllowFromEntries$1 as A, registerWebhookTargetWithPluginRoute as B, formatAllowFromLowercase$1 as C, isNumericTargetId as D, isNormalizedSenderAllowed as E, promptSingleChannelSecretInput$1 as F, resolveWebhookPath$1 as G, resolveDefaultGroupPolicy$1 as H, readJsonWebhookBodyOrReject as I, sendPayloadWithChunkedTextAndMedia$1 as J, resolveWebhookTargetWithAuthOrRejectSync as K, readStringParam as L, normalizeAccountId$1 as M, normalizeResolvedSecretInputString as N, jsonResult as O, normalizeSecretInputString as P, withResolvedWebhookRequestPipeline as Q, registerPluginHttpRoute$1 as R, deliverTextOrMediaReply$1 as S, hasConfiguredSecretInput$1 as T, resolveInboundRouteEnvelopeBuilderWithRuntime$1 as U, resolveClientIp as V, resolveOpenProviderRuntimeGroupPolicy$1 as W, waitForAbortSignal as X, setTopLevelChannelDmPolicyWithAllowFrom as Y, warnMissingProviderGroupPolicyFallbackOnce$1 as Z, createChannelMessageReplyPipeline as _, WEBHOOK_ANOMALY_COUNTER_DEFAULTS as a, createFixedWindowRateLimiter as b, applyAccountNameToChannelSection as c, buildBaseAccountStatusSnapshot as d, buildChannelConfigSchema as f, chunkTextForOutbound$1 as g, buildTokenChannelStatusSummary$1 as h, PAIRING_APPROVED_MESSAGE as i, migrateBaseNameToDefaultAccount as j, logTypingFailure$1 as k, applyBasicWebhookRequestGuards as l, buildSingleChannelSecretPromptState$1 as m, setZaloRuntime as n, WEBHOOK_RATE_LIMIT_DEFAULTS as o, buildSecretInputSchema as p, runSingleChannelSecretStep$1 as q, DEFAULT_ACCOUNT_ID$1 as r, addWildcardAllowFrom$1 as s, getZaloRuntime as t, applySetupAccountConfigPatch as u, createChannelPairingController$1 as v, formatPairingApproveHint as w, createWebhookAnomalyTracker as x, createDedupeCache as y, registerWebhookTarget as z };
@@ -1,2 +1,2 @@
1
- import { A as mergeAllowFromEntries, B as registerWebhookTargetWithPluginRoute, C as formatAllowFromLowercase, D as isNumericTargetId, E as isNormalizedSenderAllowed, F as promptSingleChannelSecretInput, G as resolveWebhookPath, H as resolveDefaultGroupPolicy, I as readJsonWebhookBodyOrReject, J as sendPayloadWithChunkedTextAndMedia, K as resolveWebhookTargetWithAuthOrRejectSync, L as readStringParam, M as normalizeAccountId, N as normalizeResolvedSecretInputString, O as jsonResult, P as normalizeSecretInputString, Q as withResolvedWebhookRequestPipeline, R as registerPluginHttpRoute, S as deliverTextOrMediaReply, T as hasConfiguredSecretInput, U as resolveInboundRouteEnvelopeBuilderWithRuntime, V as resolveClientIp, W as resolveOpenProviderRuntimeGroupPolicy, X as waitForAbortSignal, Y as setTopLevelChannelDmPolicyWithAllowFrom, Z as warnMissingProviderGroupPolicyFallbackOnce, _ as createChannelMessageReplyPipeline, a as WEBHOOK_ANOMALY_COUNTER_DEFAULTS, b as createFixedWindowRateLimiter, c as applyAccountNameToChannelSection, d as buildBaseAccountStatusSnapshot, f as buildChannelConfigSchema, g as chunkTextForOutbound, h as buildTokenChannelStatusSummary, i as PAIRING_APPROVED_MESSAGE, j as migrateBaseNameToDefaultAccount, k as logTypingFailure, l as applyBasicWebhookRequestGuards, m as buildSingleChannelSecretPromptState, n as setZaloRuntime, o as WEBHOOK_RATE_LIMIT_DEFAULTS, p as buildSecretInputSchema, q as runSingleChannelSecretStep, r as DEFAULT_ACCOUNT_ID, s as addWildcardAllowFrom, u as applySetupAccountConfigPatch, v as createChannelPairingController, w as formatPairingApproveHint, x as createWebhookAnomalyTracker, y as createDedupeCache, z as registerWebhookTarget } from "./runtime-api-CDwUY_-_.js";
1
+ import { A as mergeAllowFromEntries, B as registerWebhookTargetWithPluginRoute, C as formatAllowFromLowercase, D as isNumericTargetId, E as isNormalizedSenderAllowed, F as promptSingleChannelSecretInput, G as resolveWebhookPath, H as resolveDefaultGroupPolicy, I as readJsonWebhookBodyOrReject, J as sendPayloadWithChunkedTextAndMedia, K as resolveWebhookTargetWithAuthOrRejectSync, L as readStringParam, M as normalizeAccountId, N as normalizeResolvedSecretInputString, O as jsonResult, P as normalizeSecretInputString, Q as withResolvedWebhookRequestPipeline, R as registerPluginHttpRoute, S as deliverTextOrMediaReply, T as hasConfiguredSecretInput, U as resolveInboundRouteEnvelopeBuilderWithRuntime, V as resolveClientIp, W as resolveOpenProviderRuntimeGroupPolicy, X as waitForAbortSignal, Y as setTopLevelChannelDmPolicyWithAllowFrom, Z as warnMissingProviderGroupPolicyFallbackOnce, _ as createChannelMessageReplyPipeline, a as WEBHOOK_ANOMALY_COUNTER_DEFAULTS, b as createFixedWindowRateLimiter, c as applyAccountNameToChannelSection, d as buildBaseAccountStatusSnapshot, f as buildChannelConfigSchema, g as chunkTextForOutbound, h as buildTokenChannelStatusSummary, i as PAIRING_APPROVED_MESSAGE, j as migrateBaseNameToDefaultAccount, k as logTypingFailure, l as applyBasicWebhookRequestGuards, m as buildSingleChannelSecretPromptState, n as setZaloRuntime, o as WEBHOOK_RATE_LIMIT_DEFAULTS, p as buildSecretInputSchema, q as runSingleChannelSecretStep, r as DEFAULT_ACCOUNT_ID, s as addWildcardAllowFrom, u as applySetupAccountConfigPatch, v as createChannelPairingController, w as formatPairingApproveHint, x as createWebhookAnomalyTracker, y as createDedupeCache, z as registerWebhookTarget } from "./runtime-api-CAA4ZtqF.js";
2
2
  export { DEFAULT_ACCOUNT_ID, PAIRING_APPROVED_MESSAGE, WEBHOOK_ANOMALY_COUNTER_DEFAULTS, WEBHOOK_RATE_LIMIT_DEFAULTS, addWildcardAllowFrom, applyAccountNameToChannelSection, applyBasicWebhookRequestGuards, applySetupAccountConfigPatch, buildBaseAccountStatusSnapshot, buildChannelConfigSchema, buildSecretInputSchema, buildSingleChannelSecretPromptState, buildTokenChannelStatusSummary, chunkTextForOutbound, createChannelMessageReplyPipeline, createChannelPairingController, createDedupeCache, createFixedWindowRateLimiter, createWebhookAnomalyTracker, deliverTextOrMediaReply, formatAllowFromLowercase, formatPairingApproveHint, hasConfiguredSecretInput, isNormalizedSenderAllowed, isNumericTargetId, jsonResult, logTypingFailure, mergeAllowFromEntries, migrateBaseNameToDefaultAccount, normalizeAccountId, normalizeResolvedSecretInputString, normalizeSecretInputString, promptSingleChannelSecretInput, readJsonWebhookBodyOrReject, readStringParam, registerPluginHttpRoute, registerWebhookTarget, registerWebhookTargetWithPluginRoute, resolveClientIp, resolveDefaultGroupPolicy, resolveInboundRouteEnvelopeBuilderWithRuntime, resolveOpenProviderRuntimeGroupPolicy, resolveWebhookPath, resolveWebhookTargetWithAuthOrRejectSync, runSingleChannelSecretStep, sendPayloadWithChunkedTextAndMedia, setTopLevelChannelDmPolicyWithAllowFrom, setZaloRuntime, waitForAbortSignal, warnMissingProviderGroupPolicyFallbackOnce, withResolvedWebhookRequestPipeline };
@@ -1,6 +1,7 @@
1
1
  import { d as resolveZaloToken, u as resolveZaloAccount } from "./setup-core-fwCh0QUi.js";
2
2
  import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
3
3
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
4
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
4
5
  import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
5
6
  import { readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http";
6
7
  import { resolvePinnedHostnameWithPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
@@ -259,7 +260,7 @@ async function sendMessageZalo(chatId, text, options = {}) {
259
260
  kind: "text"
260
261
  }, () => sendMessage(context.token, {
261
262
  chat_id: context.chatId,
262
- text: text.slice(0, 2e3)
263
+ text: truncateUtf16Safe(text, 2e3)
263
264
  }, context.fetcher));
264
265
  }
265
266
  async function sendPhotoZalo(chatId, photoUrl, options = {}) {
@@ -280,7 +281,7 @@ async function sendPhotoZalo(chatId, photoUrl, options = {}) {
280
281
  }, () => (async () => sendPhoto(context.token, {
281
282
  chat_id: context.chatId,
282
283
  photo: photoUrl.trim(),
283
- caption: options.caption?.slice(0, 2e3)
284
+ caption: options.caption !== void 0 ? truncateUtf16Safe(options.caption, 2e3) : void 0
284
285
  }, context.fetcher))());
285
286
  }
286
287
  //#endregion
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@openclaw/zalo",
3
- "version": "2026.7.1-beta.2",
3
+ "version": "2026.7.1-beta.5",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/zalo",
9
- "version": "2026.7.1-beta.2",
9
+ "version": "2026.7.1-beta.5",
10
10
  "dependencies": {
11
11
  "zod": "4.4.3"
12
12
  },
13
13
  "peerDependencies": {
14
- "openclaw": ">=2026.7.1-beta.2"
14
+ "openclaw": ">=2026.7.1-beta.5"
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.2",
3
+ "version": "2026.7.1-beta.5",
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.2"
11
+ "openclaw": ">=2026.7.1-beta.5"
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.2"
42
+ "pluginApi": ">=2026.7.1-beta.5"
43
43
  },
44
44
  "build": {
45
- "openclawVersion": "2026.7.1-beta.2"
45
+ "openclawVersion": "2026.7.1-beta.5"
46
46
  },
47
47
  "release": {
48
48
  "publishToClawHub": true,