@openclaw/zalo 2026.7.1-beta.1 → 2026.7.1-beta.4
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/{actions.runtime-BvO8xrg_.js → actions.runtime-OmfJFYZn.js} +1 -1
- package/dist/api.js +1 -1
- package/dist/{channel-Zju2s6y_.js → channel-BOWhJVyl.js} +15 -7
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-T7qX1CZo.js → channel.runtime-CEPgF8Zo.js} +4 -4
- package/dist/{monitor-C1dGXDyQ.js → monitor-fgcJhAZL.js} +31 -19
- package/dist/{monitor.webhook-B23mUx-y.js → monitor.webhook-AYcIUBBP.js} +3 -6
- package/dist/{runtime-api-CDwUY_-_.js → runtime-api-CAA4ZtqF.js} +2 -2
- package/dist/runtime-api.js +1 -1
- package/dist/{send-DzchAfon.js → send-9sVVxyap.js} +18 -3
- package/npm-shrinkwrap.json +3 -3
- package/package.json +4 -4
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-
|
|
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 {
|
|
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-
|
|
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
|
|
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
|
-
|
|
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:
|
|
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-
|
|
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-
|
|
3
|
-
import { a as getMe, n as resolveZaloProxyFetch, r as ZaloApiError, t as sendMessageZalo } from "./send-
|
|
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) {
|
|
@@ -71,7 +71,7 @@ async function startZaloGatewayAccount(ctx) {
|
|
|
71
71
|
const fetcher = resolveZaloProxyFetch(account.config.proxy);
|
|
72
72
|
try {
|
|
73
73
|
const probe = await probeZalo(token, 2500, fetcher);
|
|
74
|
-
const name = probe.ok ? probe.bot?.
|
|
74
|
+
const name = probe.ok ? probe.bot?.account_name?.trim() : null;
|
|
75
75
|
if (name) zaloBotLabel = ` (${name})`;
|
|
76
76
|
if (!probe.ok) ctx.log?.warn?.(`[${account.accountId}] Zalo probe failed before provider start (${String(probe.elapsedMs)}ms): ${probe.error}`);
|
|
77
77
|
ctx.setStatus({
|
|
@@ -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-
|
|
89
|
+
const { monitorZaloProvider } = await import("./monitor-fgcJhAZL.js");
|
|
90
90
|
return monitorZaloProvider({
|
|
91
91
|
token,
|
|
92
92
|
account,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { n as resolveZaloRuntimeGroupPolicy, t as normalizeZaloAllowEntry } from "./group-access-8qHRzDHx.js";
|
|
2
|
-
import { t as getZaloRuntime } from "./runtime-api-
|
|
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-
|
|
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
|
+
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
4
5
|
import { deliverTextOrMediaReply, resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
|
|
5
6
|
import { normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
7
|
import { resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
@@ -9,6 +10,7 @@ import { logTypingFailure } from "openclaw/plugin-sdk/channel-feedback";
|
|
|
9
10
|
import { resolveInboundRouteEnvelopeBuilderWithRuntime } from "openclaw/plugin-sdk/inbound-envelope";
|
|
10
11
|
import { registerPluginHttpRoute, resolveWebhookPath } from "openclaw/plugin-sdk/webhook-ingress";
|
|
11
12
|
import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
13
|
+
import { formatInboundMediaUnavailableText } from "openclaw/plugin-sdk/channel-inbound";
|
|
12
14
|
import { resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
13
15
|
import { waitForAbortSignal } from "openclaw/plugin-sdk/runtime-env";
|
|
14
16
|
import { createHostedOutboundMediaStore } from "openclaw/plugin-sdk/outbound-media";
|
|
@@ -152,12 +154,13 @@ const ZALO_TEXT_LIMIT = 2e3;
|
|
|
152
154
|
const DEFAULT_MEDIA_MAX_MB = 5;
|
|
153
155
|
const WEBHOOK_CLEANUP_TIMEOUT_MS = 5e3;
|
|
154
156
|
const ZALO_TYPING_TIMEOUT_MS = 5e3;
|
|
155
|
-
|
|
157
|
+
const UNIX_MILLISECONDS_THRESHOLD = 0xe8d4a51000;
|
|
156
158
|
const hostedMediaRouteRefs = /* @__PURE__ */ new Map();
|
|
157
|
-
function
|
|
158
|
-
|
|
159
|
-
return
|
|
159
|
+
function resolveZaloTimestampMs(date) {
|
|
160
|
+
if (!date) return;
|
|
161
|
+
return date >= UNIX_MILLISECONDS_THRESHOLD ? date : date * 1e3;
|
|
160
162
|
}
|
|
163
|
+
const loadZaloWebhookModule = createLazyRuntimeModule(() => import("./monitor.webhook-AYcIUBBP.js"));
|
|
161
164
|
function releaseSharedHostedMediaRouteRef(routePath) {
|
|
162
165
|
const current = hostedMediaRouteRefs.get(routePath);
|
|
163
166
|
if (!current) return;
|
|
@@ -334,7 +337,7 @@ async function handleImageMessage(params) {
|
|
|
334
337
|
const authorization = await authorizeZaloMessage({
|
|
335
338
|
...params,
|
|
336
339
|
text: caption,
|
|
337
|
-
mediaPath:
|
|
340
|
+
mediaPath: "__pending_media__",
|
|
338
341
|
mediaType: void 0
|
|
339
342
|
});
|
|
340
343
|
if (!authorization) return;
|
|
@@ -351,9 +354,15 @@ async function handleImageMessage(params) {
|
|
|
351
354
|
} catch (err) {
|
|
352
355
|
runtime.error?.(`[${account.accountId}] Failed to download Zalo image: ${String(err)}`);
|
|
353
356
|
}
|
|
357
|
+
const agentBody = mediaPath ? authorization.rawBody : formatInboundMediaUnavailableText({
|
|
358
|
+
body: caption,
|
|
359
|
+
mediaPlaceholder: "<media:image>",
|
|
360
|
+
notice: "[zalo image attachment unavailable]"
|
|
361
|
+
});
|
|
354
362
|
await processMessageWithPipeline({
|
|
355
363
|
...params,
|
|
356
364
|
authorization,
|
|
365
|
+
agentBody,
|
|
357
366
|
text: caption,
|
|
358
367
|
mediaPath,
|
|
359
368
|
mediaType
|
|
@@ -455,7 +464,7 @@ async function authorizeZaloMessage(params) {
|
|
|
455
464
|
};
|
|
456
465
|
}
|
|
457
466
|
async function processMessageWithPipeline(params) {
|
|
458
|
-
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;
|
|
459
468
|
const { message_id, date } = message;
|
|
460
469
|
const authorization = authorizationOverride ?? await authorizeZaloMessage({
|
|
461
470
|
...params,
|
|
@@ -464,6 +473,7 @@ async function processMessageWithPipeline(params) {
|
|
|
464
473
|
});
|
|
465
474
|
if (!authorization) return;
|
|
466
475
|
const { isGroup, chatId, senderId, senderName, rawBody, commandAuthorized } = authorization;
|
|
476
|
+
const agentBody = agentBodyOverride ?? rawBody;
|
|
467
477
|
const { route, buildEnvelope } = resolveInboundRouteEnvelopeBuilderWithRuntime({
|
|
468
478
|
cfg: config,
|
|
469
479
|
channel: "zalo",
|
|
@@ -480,17 +490,18 @@ async function processMessageWithPipeline(params) {
|
|
|
480
490
|
return;
|
|
481
491
|
}
|
|
482
492
|
const fromLabel = isGroup ? `group:${chatId}` : senderName || `user:${senderId}`;
|
|
493
|
+
const timestamp = resolveZaloTimestampMs(date);
|
|
483
494
|
const { storePath, body } = buildEnvelope({
|
|
484
495
|
channel: "Zalo",
|
|
485
496
|
from: fromLabel,
|
|
486
|
-
timestamp
|
|
487
|
-
body:
|
|
497
|
+
timestamp,
|
|
498
|
+
body: agentBody
|
|
488
499
|
});
|
|
489
500
|
const ctxPayload = core.channel.inbound.buildContext({
|
|
490
501
|
channel: "zalo",
|
|
491
502
|
accountId: route.accountId,
|
|
492
503
|
messageId: message_id,
|
|
493
|
-
timestamp
|
|
504
|
+
timestamp,
|
|
494
505
|
from: isGroup ? `zalo:group:${chatId}` : `zalo:${senderId}`,
|
|
495
506
|
sender: {
|
|
496
507
|
id: senderId,
|
|
@@ -509,7 +520,7 @@ async function processMessageWithPipeline(params) {
|
|
|
509
520
|
reply: { to: `zalo:${chatId}` },
|
|
510
521
|
message: {
|
|
511
522
|
body,
|
|
512
|
-
bodyForAgent:
|
|
523
|
+
bodyForAgent: agentBody,
|
|
513
524
|
rawBody,
|
|
514
525
|
commandBody: rawBody
|
|
515
526
|
},
|
|
@@ -618,15 +629,16 @@ async function deliverZaloReply(params) {
|
|
|
618
629
|
}
|
|
619
630
|
},
|
|
620
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;
|
|
621
639
|
await sendPhoto(token, {
|
|
622
640
|
chat_id: chatId,
|
|
623
|
-
photo:
|
|
624
|
-
mediaUrl,
|
|
625
|
-
webhookUrl,
|
|
626
|
-
webhookPath,
|
|
627
|
-
maxBytes: mediaMaxBytes,
|
|
628
|
-
proxyUrl
|
|
629
|
-
}) : mediaUrl,
|
|
641
|
+
photo: sendableMediaUrl,
|
|
630
642
|
caption
|
|
631
643
|
}, fetcher);
|
|
632
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-
|
|
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) =>
|
|
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,
|
|
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
|
|
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
|
|
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 };
|
package/dist/runtime-api.js
CHANGED
|
@@ -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-
|
|
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";
|
|
@@ -11,6 +12,7 @@ import { makeProxyFetch } from "openclaw/plugin-sdk/fetch-runtime";
|
|
|
11
12
|
* @see https://bot.zaloplatforms.com/docs
|
|
12
13
|
*/
|
|
13
14
|
const ZALO_API_BASE = "https://bot-api.zaloplatforms.com";
|
|
15
|
+
const ZALO_API_URL_ENV = "ZALO_API_URL";
|
|
14
16
|
const ZALO_MEDIA_SSRF_POLICY = {};
|
|
15
17
|
var ZaloApiError = class extends Error {
|
|
16
18
|
constructor(message, errorCode, description) {
|
|
@@ -24,11 +26,24 @@ var ZaloApiError = class extends Error {
|
|
|
24
26
|
return this.errorCode === 408;
|
|
25
27
|
}
|
|
26
28
|
};
|
|
29
|
+
function resolveZaloApiUrl(apiUrl) {
|
|
30
|
+
const value = apiUrl === void 0 ? process.env[ZALO_API_URL_ENV]?.trim() ?? ZALO_API_BASE : apiUrl.trim();
|
|
31
|
+
if (!value) throw new Error(`${ZALO_API_URL_ENV} must not be empty.`);
|
|
32
|
+
let parsed;
|
|
33
|
+
try {
|
|
34
|
+
parsed = new URL(value);
|
|
35
|
+
} catch {
|
|
36
|
+
throw new Error(`${ZALO_API_URL_ENV} must be a valid URL.`);
|
|
37
|
+
}
|
|
38
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new Error(`${ZALO_API_URL_ENV} must use http:// or https://.`);
|
|
39
|
+
if (parsed.search || parsed.hash) throw new Error(`${ZALO_API_URL_ENV} must not include a query string or fragment.`);
|
|
40
|
+
return parsed.href.replace(/\/+$/u, "");
|
|
41
|
+
}
|
|
27
42
|
/**
|
|
28
43
|
* Call the Zalo Bot API
|
|
29
44
|
*/
|
|
30
45
|
async function callZaloApi(method, token, body, options) {
|
|
31
|
-
const url = `${
|
|
46
|
+
const url = `${resolveZaloApiUrl(options?.apiUrl)}/bot${token}/${method}`;
|
|
32
47
|
const controller = new AbortController();
|
|
33
48
|
const requestTimeoutMs = options?.timeoutMs === void 0 ? void 0 : resolveTimerTimeoutMs(options.timeoutMs, 1);
|
|
34
49
|
const timeoutId = requestTimeoutMs === void 0 ? void 0 : setTimeout(() => controller.abort(), requestTimeoutMs);
|
|
@@ -245,7 +260,7 @@ async function sendMessageZalo(chatId, text, options = {}) {
|
|
|
245
260
|
kind: "text"
|
|
246
261
|
}, () => sendMessage(context.token, {
|
|
247
262
|
chat_id: context.chatId,
|
|
248
|
-
text: text
|
|
263
|
+
text: truncateUtf16Safe(text, 2e3)
|
|
249
264
|
}, context.fetcher));
|
|
250
265
|
}
|
|
251
266
|
async function sendPhotoZalo(chatId, photoUrl, options = {}) {
|
|
@@ -266,7 +281,7 @@ async function sendPhotoZalo(chatId, photoUrl, options = {}) {
|
|
|
266
281
|
}, () => (async () => sendPhoto(context.token, {
|
|
267
282
|
chat_id: context.chatId,
|
|
268
283
|
photo: photoUrl.trim(),
|
|
269
|
-
caption: options.caption
|
|
284
|
+
caption: options.caption !== void 0 ? truncateUtf16Safe(options.caption, 2e3) : void 0
|
|
270
285
|
}, context.fetcher))());
|
|
271
286
|
}
|
|
272
287
|
//#endregion
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/zalo",
|
|
3
|
-
"version": "2026.7.1-beta.
|
|
3
|
+
"version": "2026.7.1-beta.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/zalo",
|
|
9
|
-
"version": "2026.7.1-beta.
|
|
9
|
+
"version": "2026.7.1-beta.4",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"zod": "4.4.3"
|
|
12
12
|
},
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"openclaw": ">=2026.7.1-beta.
|
|
14
|
+
"openclaw": ">=2026.7.1-beta.4"
|
|
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.
|
|
3
|
+
"version": "2026.7.1-beta.4",
|
|
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.
|
|
11
|
+
"openclaw": ">=2026.7.1-beta.4"
|
|
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.
|
|
42
|
+
"pluginApi": ">=2026.7.1-beta.4"
|
|
43
43
|
},
|
|
44
44
|
"build": {
|
|
45
|
-
"openclawVersion": "2026.7.1-beta.
|
|
45
|
+
"openclawVersion": "2026.7.1-beta.4"
|
|
46
46
|
},
|
|
47
47
|
"release": {
|
|
48
48
|
"publishToClawHub": true,
|