@openclaw/zalouser 2026.5.7 → 2026.5.9-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.
@@ -3,7 +3,7 @@ import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
3
3
  //#region extensions/zalouser/src/accounts.ts
4
4
  let zalouserAccountsRuntimePromise;
5
5
  async function loadZalouserAccountsRuntime() {
6
- zalouserAccountsRuntimePromise ??= import("./accounts.runtime-uG7S8cXT.js");
6
+ zalouserAccountsRuntimePromise ??= import("./accounts.runtime-Bls9vlnf.js");
7
7
  return await zalouserAccountsRuntimePromise;
8
8
  }
9
9
  const { listAccountIds: listZalouserAccountIds, resolveDefaultAccountId: resolveDefaultZalouserAccountId } = createAccountListHelpers("zalouser");
@@ -1,2 +1,2 @@
1
- import { n as getZaloUserInfo, t as checkZaloAuthenticated } from "./zalo-js-CHCUlY3c.js";
1
+ import { n as getZaloUserInfo, t as checkZaloAuthenticated } from "./zalo-js-QGi0H5K7.js";
2
2
  export { checkZaloAuthenticated, getZaloUserInfo };
@@ -1,11 +1,12 @@
1
- import "./setup-surface-NCOuKu-l.js";
1
+ import "./setup-surface-6MmoBuUf.js";
2
2
  import "./setup-core-CqipqY98.js";
3
3
  import { r as parseZalouserOutboundTarget } from "./session-route-C0-Xr8bt.js";
4
- import "./channel-DLNmGWb8.js";
4
+ import "./channel-_NSq5FwQ.js";
5
5
  import "./security-audit-BZLhil-V.js";
6
- import { i as listZaloFriendsMatching, n as getZaloUserInfo, s as listZaloGroupsMatching, t as checkZaloAuthenticated } from "./zalo-js-CHCUlY3c.js";
7
- import "./channel.setup-CiDeBFrn.js";
8
- import { i as sendMessageZalouser, n as sendImageZalouser, r as sendLinkZalouser } from "./send-BsmySxe3.js";
6
+ import { i as listZaloFriendsMatching, n as getZaloUserInfo, s as listZaloGroupsMatching, t as checkZaloAuthenticated } from "./zalo-js-QGi0H5K7.js";
7
+ import "./channel.setup-Tevqgs6C.js";
8
+ import { i as sendMessageZalouser, n as sendImageZalouser, r as sendLinkZalouser } from "./send-CeCQ8UZF.js";
9
+ import { stringEnum } from "openclaw/plugin-sdk/channel-actions";
9
10
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
10
11
  import { Type } from "typebox";
11
12
  //#region extensions/zalouser/src/tool.ts
@@ -18,13 +19,6 @@ const ACTIONS = [
18
19
  "me",
19
20
  "status"
20
21
  ];
21
- function stringEnum(values, options = {}) {
22
- return Type.Unsafe({
23
- type: "string",
24
- enum: [...values],
25
- ...options
26
- });
27
- }
28
22
  const ZalouserToolSchema = Type.Object({
29
23
  action: stringEnum(ACTIONS, { description: `Action to perform: ${ACTIONS.join(", ")}` }),
30
24
  threadId: Type.Optional(Type.String({ description: "Thread ID for messaging" })),
package/dist/api.js CHANGED
@@ -1,7 +1,7 @@
1
- import { n as zalouserSetupWizard } from "./setup-surface-NCOuKu-l.js";
1
+ import { n as zalouserSetupWizard } from "./setup-surface-6MmoBuUf.js";
2
2
  import { n as zalouserSetupAdapter, t as createZalouserSetupWizardProxy } from "./setup-core-CqipqY98.js";
3
- import { t as zalouserPlugin } from "./channel-DLNmGWb8.js";
3
+ import { t as zalouserPlugin } from "./channel-_NSq5FwQ.js";
4
4
  import { n as isZalouserMutableGroupEntry, t as collectZalouserSecurityAuditFindings } from "./security-audit-BZLhil-V.js";
5
- import { t as zalouserSetupPlugin } from "./channel.setup-CiDeBFrn.js";
6
- import { t as createZalouserTool } from "./api-C3SYq_R3.js";
5
+ import { t as zalouserSetupPlugin } from "./channel.setup-Tevqgs6C.js";
6
+ import { t as createZalouserTool } from "./api-BR8DCvu2.js";
7
7
  export { collectZalouserSecurityAuditFindings, createZalouserSetupWizardProxy, createZalouserTool, isZalouserMutableGroupEntry, zalouserPlugin, zalouserSetupAdapter, zalouserSetupPlugin, zalouserSetupWizard };
@@ -1,5 +1,5 @@
1
- import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-C00IMUgd.js";
2
- import { a as isNumericTargetId, i as isDangerousNameMatchingEnabled, n as DEFAULT_ACCOUNT_ID, o as normalizeAccountId, r as chunkTextForOutbound, s as sendPayloadWithChunkedTextAndMedia, t as createZalouserPluginBase } from "./shared-DSy8aIUx.js";
1
+ import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-ClSPNIvj.js";
2
+ import { a as isNumericTargetId, i as isDangerousNameMatchingEnabled, n as DEFAULT_ACCOUNT_ID, o as normalizeAccountId, r as chunkTextForOutbound, s as sendPayloadWithChunkedTextAndMedia, t as createZalouserPluginBase } from "./shared-C4hIhcfY.js";
3
3
  import { a as resolveZalouserReactionMessageIds, o as buildZalouserGroupCandidates, s as findZalouserGroupEntry, t as getZalouserRuntime } from "./runtime-QNU7vLgI.js";
4
4
  import { n as zalouserSetupAdapter, r as writeQrDataUrlToTempFile, t as createZalouserSetupWizardProxy } from "./setup-core-CqipqY98.js";
5
5
  import { i as resolveZalouserOutboundSessionRoute, n as parseZalouserDirectoryGroupId, r as parseZalouserOutboundTarget, t as normalizeZalouserTarget } from "./session-route-C0-Xr8bt.js";
@@ -10,11 +10,12 @@ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
10
10
  import { createAsyncComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
11
11
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
12
12
  import { createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
13
+ import { defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-message";
13
14
  import { createPairingPrefixStripper } from "openclaw/plugin-sdk/channel-pairing";
14
15
  import { createEmptyChannelResult, createRawChannelSendResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
15
16
  import { createStaticReplyToModeResolver } from "openclaw/plugin-sdk/conversation-runtime";
16
17
  //#region extensions/zalouser/src/channel.adapters.ts
17
- const loadZalouserChannelRuntime$1 = createLazyRuntimeModule(() => import("./channel.runtime-C9WxiAiR.js"));
18
+ const loadZalouserChannelRuntime$1 = createLazyRuntimeModule(() => import("./channel.runtime-85pFFq1m.js"));
18
19
  const ZALOUSER_TEXT_CHUNK_LIMIT = 2e3;
19
20
  function resolveZalouserQrProfile(accountId) {
20
21
  const normalized = normalizeAccountId(accountId);
@@ -47,40 +48,54 @@ function resolveZalouserRequireMention(params) {
47
48
  if (typeof entry?.requireMention === "boolean") return entry.requireMention;
48
49
  return true;
49
50
  }
51
+ async function sendZalouserTextFromContext({ to, text, accountId, cfg }) {
52
+ const { sendMessageZalouser } = await loadZalouserChannelRuntime$1();
53
+ const account = resolveZalouserAccountSync({
54
+ cfg,
55
+ accountId
56
+ });
57
+ const target = parseZalouserOutboundTarget(to);
58
+ return await sendMessageZalouser(target.threadId, text, {
59
+ profile: account.profile,
60
+ isGroup: target.isGroup,
61
+ textMode: "markdown",
62
+ textChunkMode: resolveZalouserOutboundChunkMode(cfg, account.accountId),
63
+ textChunkLimit: resolveZalouserOutboundTextChunkLimit(cfg, account.accountId)
64
+ });
65
+ }
66
+ async function sendZalouserMediaFromContext({ to, text, mediaUrl, accountId, cfg, mediaLocalRoots, mediaReadFile }) {
67
+ const { sendMessageZalouser } = await loadZalouserChannelRuntime$1();
68
+ const account = resolveZalouserAccountSync({
69
+ cfg,
70
+ accountId
71
+ });
72
+ const target = parseZalouserOutboundTarget(to);
73
+ return await sendMessageZalouser(target.threadId, text, {
74
+ profile: account.profile,
75
+ isGroup: target.isGroup,
76
+ mediaUrl,
77
+ mediaLocalRoots,
78
+ mediaReadFile,
79
+ textMode: "markdown",
80
+ textChunkMode: resolveZalouserOutboundChunkMode(cfg, account.accountId),
81
+ textChunkLimit: resolveZalouserOutboundTextChunkLimit(cfg, account.accountId)
82
+ });
83
+ }
50
84
  const zalouserRawSendResultAdapter = createRawChannelSendResultAdapter({
51
85
  channel: "zalouser",
52
- sendText: async ({ to, text, accountId, cfg }) => {
53
- const { sendMessageZalouser } = await loadZalouserChannelRuntime$1();
54
- const account = resolveZalouserAccountSync({
55
- cfg,
56
- accountId
57
- });
58
- const target = parseZalouserOutboundTarget(to);
59
- return await sendMessageZalouser(target.threadId, text, {
60
- profile: account.profile,
61
- isGroup: target.isGroup,
62
- textMode: "markdown",
63
- textChunkMode: resolveZalouserOutboundChunkMode(cfg, account.accountId),
64
- textChunkLimit: resolveZalouserOutboundTextChunkLimit(cfg, account.accountId)
65
- });
66
- },
67
- sendMedia: async ({ to, text, mediaUrl, accountId, cfg, mediaLocalRoots, mediaReadFile }) => {
68
- const { sendMessageZalouser } = await loadZalouserChannelRuntime$1();
69
- const account = resolveZalouserAccountSync({
70
- cfg,
71
- accountId
72
- });
73
- const target = parseZalouserOutboundTarget(to);
74
- return await sendMessageZalouser(target.threadId, text, {
75
- profile: account.profile,
76
- isGroup: target.isGroup,
77
- mediaUrl,
78
- mediaLocalRoots,
79
- mediaReadFile,
80
- textMode: "markdown",
81
- textChunkMode: resolveZalouserOutboundChunkMode(cfg, account.accountId),
82
- textChunkLimit: resolveZalouserOutboundTextChunkLimit(cfg, account.accountId)
83
- });
86
+ sendText: sendZalouserTextFromContext,
87
+ sendMedia: sendZalouserMediaFromContext
88
+ });
89
+ const zalouserMessageAdapter = defineChannelMessageAdapter({
90
+ id: "zalouser",
91
+ durableFinal: { capabilities: {
92
+ text: true,
93
+ media: true,
94
+ messageSendingHooks: true
95
+ } },
96
+ send: {
97
+ text: sendZalouserTextFromContext,
98
+ media: sendZalouserMediaFromContext
84
99
  }
85
100
  });
86
101
  const resolveZalouserDmPolicy = createScopedDmSecurityResolver({
@@ -331,8 +346,8 @@ function collectZalouserStatusIssues(accounts) {
331
346
  }
332
347
  //#endregion
333
348
  //#region extensions/zalouser/src/channel.ts
334
- const loadZalouserChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-C9WxiAiR.js"));
335
- const zalouserSetupWizardProxy = createZalouserSetupWizardProxy(async () => (await import("./setup-surface-NCOuKu-l.js").then((n) => n.t)).zalouserSetupWizard);
349
+ const loadZalouserChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-85pFFq1m.js"));
350
+ const zalouserSetupWizardProxy = createZalouserSetupWizardProxy(async () => (await import("./setup-surface-6MmoBuUf.js").then((n) => n.t)).zalouserSetupWizard);
336
351
  function mapUser(params) {
337
352
  return {
338
353
  kind: "user",
@@ -411,6 +426,7 @@ const zalouserPlugin = createChatChannelPlugin({
411
426
  },
412
427
  resolver: zalouserResolverAdapter,
413
428
  auth: zalouserAuthAdapter,
429
+ message: zalouserMessageAdapter,
414
430
  status: createAsyncComputedAccountStatusAdapter({
415
431
  defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID),
416
432
  collectStatusIssues: collectZalouserStatusIssues,
@@ -448,7 +464,7 @@ const zalouserPlugin = createChatChannelPlugin({
448
464
  setStatus: ctx.setStatus
449
465
  });
450
466
  ctx.log?.info(`[${account.accountId}] starting zalouser provider${userLabel}`);
451
- const { monitorZalouserProvider } = await import("./monitor-dpWp8FkN.js");
467
+ const { monitorZalouserProvider } = await import("./monitor-DvZ0E6nW.js");
452
468
  return monitorZalouserProvider({
453
469
  account,
454
470
  config: ctx.cfg,
@@ -1,2 +1,2 @@
1
- import { t as zalouserPlugin } from "./channel-DLNmGWb8.js";
1
+ import { t as zalouserPlugin } from "./channel-_NSq5FwQ.js";
2
2
  export { zalouserPlugin };
@@ -1,6 +1,6 @@
1
1
  import { t as collectZalouserSecurityAuditFindings } from "./security-audit-BZLhil-V.js";
2
- import { a as listZaloGroupMembers, b as waitForZaloQrLogin, c as logoutZaloProfile, i as listZaloFriendsMatching, n as getZaloUserInfo, s as listZaloGroupsMatching, y as startZaloQrLogin } from "./zalo-js-CHCUlY3c.js";
3
- import { a as sendReactionZalouser, i as sendMessageZalouser } from "./send-BsmySxe3.js";
2
+ import { a as listZaloGroupMembers, b as waitForZaloQrLogin, c as logoutZaloProfile, i as listZaloFriendsMatching, n as getZaloUserInfo, s as listZaloGroupsMatching, y as startZaloQrLogin } from "./zalo-js-QGi0H5K7.js";
3
+ import { a as sendReactionZalouser, i as sendMessageZalouser } from "./send-CeCQ8UZF.js";
4
4
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
5
5
  //#region extensions/zalouser/src/probe.ts
6
6
  async function probeZalouser(profile, timeoutMs) {
@@ -1,5 +1,5 @@
1
- import { n as zalouserSetupWizard } from "./setup-surface-NCOuKu-l.js";
2
- import { t as createZalouserPluginBase } from "./shared-DSy8aIUx.js";
1
+ import { n as zalouserSetupWizard } from "./setup-surface-6MmoBuUf.js";
2
+ import { t as createZalouserPluginBase } from "./shared-C4hIhcfY.js";
3
3
  import { n as zalouserSetupAdapter } from "./setup-core-CqipqY98.js";
4
4
  //#region extensions/zalouser/src/channel.setup.ts
5
5
  const zalouserSetupPlugin = { ...createZalouserPluginBase({
@@ -1,6 +1,6 @@
1
1
  import { c as isZalouserGroupEntryAllowed, i as resolveZalouserMessageSid, o as buildZalouserGroupCandidates, r as formatZalouserMessageSidFull, s as findZalouserGroupEntry, t as getZalouserRuntime } from "./runtime-QNU7vLgI.js";
2
- import { o as listZaloGroups, r as listZaloFriends, u as resolveZaloGroupContext, v as startZaloListener } from "./zalo-js-CHCUlY3c.js";
3
- import { i as sendMessageZalouser, o as sendSeenZalouser, s as sendTypingZalouser, t as sendDeliveredZalouser } from "./send-BsmySxe3.js";
2
+ import { o as listZaloGroups, r as listZaloFriends, u as resolveZaloGroupContext, v as startZaloListener } from "./zalo-js-QGi0H5K7.js";
3
+ import { i as sendMessageZalouser, o as sendSeenZalouser, s as sendTypingZalouser, t as sendDeliveredZalouser } from "./send-CeCQ8UZF.js";
4
4
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
5
5
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime";
6
6
  import { mergeAllowlist, summarizeMapping } from "openclaw/plugin-sdk/allow-from";
@@ -11,7 +11,6 @@ import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pair
11
11
  import { DM_GROUP_ACCESS_REASON, resolveDmGroupAccessWithLists } from "openclaw/plugin-sdk/channel-policy";
12
12
  import { resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
13
13
  import { implicitMentionKindWhen, resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-inbound";
14
- import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
15
14
  import { resolveSenderCommandAuthorization } from "openclaw/plugin-sdk/command-auth";
16
15
  import { evaluateGroupRouteAccessForPolicy, resolveSenderScopedGroupPolicy } from "openclaw/plugin-sdk/group-access";
17
16
  import { DEFAULT_GROUP_HISTORY_LIMIT, buildPendingHistoryContextFromMap, clearHistoryEntriesIfEnabled, recordPendingHistoryEntryIfEnabled } from "openclaw/plugin-sdk/reply-history";
@@ -437,24 +436,18 @@ async function processMessage(message, account, config, core, runtime, historySt
437
436
  CommandAuthorized: commandAuthorized
438
437
  }
439
438
  });
440
- const { onModelSelected, ...replyPipeline } = createChannelReplyPipeline({
441
- cfg: config,
442
- agentId: route.agentId,
443
- channel: "zalouser",
444
- accountId: account.accountId,
445
- typing: {
446
- start: async () => {
447
- await sendTypingZalouser(chatId, {
448
- profile: account.profile,
449
- isGroup
450
- });
451
- },
452
- onStartError: (err) => {
453
- runtime.error?.(`[${account.accountId}] zalouser typing start failed for ${chatId}: ${String(err)}`);
454
- logVerbose(core, runtime, `zalouser typing failed for ${chatId}: ${String(err)}`);
455
- }
439
+ const replyPipeline = { typing: {
440
+ start: async () => {
441
+ await sendTypingZalouser(chatId, {
442
+ profile: account.profile,
443
+ isGroup
444
+ });
445
+ },
446
+ onStartError: (err) => {
447
+ runtime.error?.(`[${account.accountId}] zalouser typing start failed for ${chatId}: ${String(err)}`);
448
+ logVerbose(core, runtime, `zalouser typing failed for ${chatId}: ${String(err)}`);
456
449
  }
457
- });
450
+ } };
458
451
  await core.channel.turn.run({
459
452
  channel: "zalouser",
460
453
  accountId: account.accountId,
@@ -479,8 +472,20 @@ async function processMessage(message, account, config, core, runtime, historySt
479
472
  recordInboundSession: core.channel.session.recordInboundSession,
480
473
  dispatchReplyWithBufferedBlockDispatcher: core.channel.reply.dispatchReplyWithBufferedBlockDispatcher,
481
474
  delivery: {
475
+ preparePayload: (payload) => {
476
+ if (payload.text === void 0) return payload;
477
+ return {
478
+ ...payload,
479
+ text: core.channel.text.convertMarkdownTables(payload.text, core.channel.text.resolveMarkdownTableMode({
480
+ cfg: config,
481
+ channel: "zalouser",
482
+ accountId: account.accountId
483
+ }))
484
+ };
485
+ },
486
+ durable: () => ({ to: normalizedTo }),
482
487
  deliver: async (payload) => {
483
- await deliverZalouserReply({
488
+ return await deliverZalouserReply({
484
489
  payload,
485
490
  profile: account.profile,
486
491
  chatId,
@@ -489,20 +494,17 @@ async function processMessage(message, account, config, core, runtime, historySt
489
494
  core,
490
495
  config,
491
496
  accountId: account.accountId,
492
- statusSink,
493
- tableMode: core.channel.text.resolveMarkdownTableMode({
494
- cfg: config,
495
- channel: "zalouser",
496
- accountId: account.accountId
497
- })
497
+ tableMode: "off"
498
498
  });
499
499
  },
500
+ onDelivered: (_payload, _info, result) => {
501
+ if (result?.visibleReplySent !== false) statusSink?.({ lastOutboundAt: Date.now() });
502
+ },
500
503
  onError: (err, info) => {
501
504
  runtime.error(`[${account.accountId}] Zalouser ${info.kind} reply failed: ${String(err)}`);
502
505
  }
503
506
  },
504
- dispatcherOptions: replyPipeline,
505
- replyOptions: { onModelSelected },
507
+ replyPipeline,
506
508
  record: { onRecordError: (err) => {
507
509
  runtime.error?.(`zalouser: failed updating session meta: ${String(err)}`);
508
510
  } }
@@ -516,8 +518,9 @@ async function processMessage(message, account, config, core, runtime, historySt
516
518
  });
517
519
  }
518
520
  async function deliverZalouserReply(params) {
519
- const { payload, profile, chatId, isGroup, runtime, core, config, accountId, statusSink } = params;
521
+ const { payload, profile, chatId, isGroup, runtime, core, config, accountId } = params;
520
522
  const tableMode = params.tableMode ?? "code";
523
+ let visibleReplySent = false;
521
524
  const reply = resolveSendableOutboundReplyParts(payload, { text: core.channel.text.convertMarkdownTables(payload.text ?? "", tableMode) });
522
525
  const chunkMode = core.channel.text.resolveChunkMode(config, "zalouser", accountId);
523
526
  const textChunkLimit = core.channel.text.resolveTextChunkLimit(config, "zalouser", accountId, { fallbackLimit: ZALOUSER_TEXT_LIMIT });
@@ -533,7 +536,7 @@ async function deliverZalouserReply(params) {
533
536
  textChunkMode: chunkMode,
534
537
  textChunkLimit
535
538
  });
536
- statusSink?.({ lastOutboundAt: Date.now() });
539
+ visibleReplySent = true;
537
540
  } catch (err) {
538
541
  runtime.error(`Zalouser message send failed: ${String(err)}`);
539
542
  }
@@ -548,12 +551,13 @@ async function deliverZalouserReply(params) {
548
551
  textChunkMode: chunkMode,
549
552
  textChunkLimit
550
553
  });
551
- statusSink?.({ lastOutboundAt: Date.now() });
554
+ visibleReplySent = true;
552
555
  },
553
556
  onMediaError: (error) => {
554
557
  runtime.error(`Zalouser media send failed: ${error instanceof Error ? error.message : JSON.stringify(error)}`);
555
558
  }
556
559
  });
560
+ return { visibleReplySent };
557
561
  }
558
562
  async function monitorZalouserProvider(options) {
559
563
  let { account, config } = options;
@@ -1,22 +1,22 @@
1
- import { n as zalouserSetupWizard } from "./setup-surface-NCOuKu-l.js";
1
+ import { n as zalouserSetupWizard } from "./setup-surface-6MmoBuUf.js";
2
2
  import { n as setZalouserRuntime } from "./runtime-QNU7vLgI.js";
3
3
  import { n as zalouserSetupAdapter, t as createZalouserSetupWizardProxy } from "./setup-core-CqipqY98.js";
4
- import { t as zalouserPlugin } from "./channel-DLNmGWb8.js";
4
+ import { t as zalouserPlugin } from "./channel-_NSq5FwQ.js";
5
5
  import { n as isZalouserMutableGroupEntry, t as collectZalouserSecurityAuditFindings } from "./security-audit-BZLhil-V.js";
6
- import { t as zalouserSetupPlugin } from "./channel.setup-CiDeBFrn.js";
7
- import { t as createZalouserTool } from "./api-C3SYq_R3.js";
6
+ import { t as zalouserSetupPlugin } from "./channel.setup-Tevqgs6C.js";
7
+ import { t as createZalouserTool } from "./api-BR8DCvu2.js";
8
8
  import { buildBaseAccountStatusSnapshot } from "openclaw/plugin-sdk/status-helpers";
9
9
  import { formatAllowFromLowercase, mergeAllowlist, summarizeMapping } from "openclaw/plugin-sdk/allow-from";
10
10
  import { DEFAULT_ACCOUNT_ID, buildChannelConfigSchema, normalizeAccountId } from "openclaw/plugin-sdk/core";
11
11
  import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
12
12
  import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
13
13
  import { deliverTextOrMediaReply, isNumericTargetId, resolveSendableOutboundReplyParts, sendPayloadWithChunkedTextAndMedia } from "openclaw/plugin-sdk/reply-payload";
14
+ import { createChannelMessageReplyPipeline } from "openclaw/plugin-sdk/channel-message";
14
15
  import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pairing";
15
16
  import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
16
17
  import { loadOutboundMediaFromUrl } from "openclaw/plugin-sdk/outbound-media";
17
18
  import { resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
18
19
  import { resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-inbound";
19
- import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
20
20
  import { resolveSenderCommandAuthorization } from "openclaw/plugin-sdk/command-auth";
21
21
  import { evaluateGroupRouteAccessForPolicy, resolveSenderScopedGroupPolicy } from "openclaw/plugin-sdk/group-access";
22
- export { DEFAULT_ACCOUNT_ID, buildBaseAccountStatusSnapshot, buildChannelConfigSchema, chunkTextForOutbound, collectZalouserSecurityAuditFindings, createChannelPairingController, createChannelReplyPipeline, createZalouserSetupWizardProxy, createZalouserTool, deliverTextOrMediaReply, evaluateGroupRouteAccessForPolicy, formatAllowFromLowercase, isDangerousNameMatchingEnabled, isNumericTargetId, isZalouserMutableGroupEntry, loadOutboundMediaFromUrl, mergeAllowlist, normalizeAccountId, resolveDefaultGroupPolicy, resolveInboundMentionDecision, resolveOpenProviderRuntimeGroupPolicy, resolvePreferredOpenClawTmpDir, resolveSendableOutboundReplyParts, resolveSenderCommandAuthorization, resolveSenderScopedGroupPolicy, sendPayloadWithChunkedTextAndMedia, setZalouserRuntime, summarizeMapping, warnMissingProviderGroupPolicyFallbackOnce, zalouserPlugin, zalouserSetupAdapter, zalouserSetupPlugin, zalouserSetupWizard };
22
+ export { DEFAULT_ACCOUNT_ID, buildBaseAccountStatusSnapshot, buildChannelConfigSchema, chunkTextForOutbound, collectZalouserSecurityAuditFindings, createChannelMessageReplyPipeline, createChannelPairingController, createZalouserSetupWizardProxy, createZalouserTool, deliverTextOrMediaReply, evaluateGroupRouteAccessForPolicy, formatAllowFromLowercase, isDangerousNameMatchingEnabled, isNumericTargetId, isZalouserMutableGroupEntry, loadOutboundMediaFromUrl, mergeAllowlist, normalizeAccountId, resolveDefaultGroupPolicy, resolveInboundMentionDecision, resolveOpenProviderRuntimeGroupPolicy, resolvePreferredOpenClawTmpDir, resolveSendableOutboundReplyParts, resolveSenderCommandAuthorization, resolveSenderScopedGroupPolicy, sendPayloadWithChunkedTextAndMedia, setZalouserRuntime, summarizeMapping, warnMissingProviderGroupPolicyFallbackOnce, zalouserPlugin, zalouserSetupAdapter, zalouserSetupPlugin, zalouserSetupWizard };
@@ -1,4 +1,4 @@
1
- import { _ as sendZaloTypingEvent, f as sendZaloDeliveredEvent, g as sendZaloTextMessage, h as sendZaloSeenEvent, m as sendZaloReaction, p as sendZaloLink, x as TextStyle } from "./zalo-js-CHCUlY3c.js";
1
+ import { S as TextStyle, _ as sendZaloTypingEvent, f as sendZaloDeliveredEvent, g as sendZaloTextMessage, h as sendZaloSeenEvent, m as sendZaloReaction, p as sendZaloLink, x as createZalouserSendReceipt } from "./zalo-js-QGi0H5K7.js";
2
2
  //#region extensions/zalouser/src/text-styles.ts
3
3
  const ESCAPE_SENTINEL_START = "";
4
4
  const ESCAPE_SENTINEL_END = "";
@@ -418,7 +418,11 @@ async function sendMessageZalouser(threadId, text, options = {}) {
418
418
  }
419
419
  return lastResult ?? {
420
420
  ok: false,
421
- error: "No message content provided"
421
+ error: "No message content provided",
422
+ receipt: createZalouserSendReceipt({
423
+ threadId,
424
+ kind: "text"
425
+ })
422
426
  };
423
427
  }
424
428
  async function sendImageZalouser(threadId, imageUrl, options = {}) {
@@ -446,7 +450,11 @@ async function sendReactionZalouser(params) {
446
450
  });
447
451
  return {
448
452
  ok: result.ok,
449
- error: result.error
453
+ error: result.error,
454
+ receipt: createZalouserSendReceipt({
455
+ threadId: params.threadId,
456
+ kind: "unknown"
457
+ })
450
458
  };
451
459
  }
452
460
  async function sendDeliveredZalouser(params) {
@@ -1,2 +1,2 @@
1
- import { t as zalouserSetupPlugin } from "./channel.setup-CiDeBFrn.js";
1
+ import { t as zalouserSetupPlugin } from "./channel.setup-Tevqgs6C.js";
2
2
  export { zalouserSetupPlugin };
@@ -1,6 +1,6 @@
1
- import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-C00IMUgd.js";
1
+ import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-ClSPNIvj.js";
2
2
  import { r as writeQrDataUrlToTempFile } from "./setup-core-CqipqY98.js";
3
- import { b as waitForZaloQrLogin, c as logoutZaloProfile, d as resolveZaloGroupsByEntries, l as resolveZaloAllowFromEntries, y as startZaloQrLogin } from "./zalo-js-CHCUlY3c.js";
3
+ import { b as waitForZaloQrLogin, c as logoutZaloProfile, d as resolveZaloGroupsByEntries, l as resolveZaloAllowFromEntries, y as startZaloQrLogin } from "./zalo-js-QGi0H5K7.js";
4
4
  import { DEFAULT_ACCOUNT_ID, addWildcardAllowFrom, formatCliCommand, formatDocsLink, formatResolvedUnresolvedNote, mergeAllowFromEntries, normalizeAccountId, patchScopedAccountConfig } from "openclaw/plugin-sdk/setup";
5
5
  //#region \0rolldown/runtime.js
6
6
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-C00IMUgd.js";
1
+ import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-ClSPNIvj.js";
2
2
  import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-DgqHp8E2.js";
3
3
  import { n as isZalouserMutableGroupEntry } from "./security-audit-BZLhil-V.js";
4
4
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
package/dist/test-api.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, n as getZcaUserInfo, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-C00IMUgd.js";
1
+ import { a as resolveZalouserAccountSync, i as resolveDefaultZalouserAccountId, n as getZcaUserInfo, r as listZalouserAccountIds, t as checkZcaAuthenticated } from "./accounts-ClSPNIvj.js";
2
2
  import { r as parseZalouserOutboundTarget } from "./session-route-C0-Xr8bt.js";
3
- import { a as listZaloGroupMembers, b as waitForZaloQrLogin, c as logoutZaloProfile, d as resolveZaloGroupsByEntries, i as listZaloFriendsMatching, l as resolveZaloAllowFromEntries, n as getZaloUserInfo, s as listZaloGroupsMatching, t as checkZaloAuthenticated, y as startZaloQrLogin } from "./zalo-js-CHCUlY3c.js";
4
- import { i as sendMessageZalouser } from "./send-BsmySxe3.js";
3
+ import { a as listZaloGroupMembers, b as waitForZaloQrLogin, c as logoutZaloProfile, d as resolveZaloGroupsByEntries, i as listZaloFriendsMatching, l as resolveZaloAllowFromEntries, n as getZaloUserInfo, s as listZaloGroupsMatching, t as checkZaloAuthenticated, y as startZaloQrLogin } from "./zalo-js-QGi0H5K7.js";
4
+ import { i as sendMessageZalouser } from "./send-CeCQ8UZF.js";
5
5
  export { checkZaloAuthenticated, checkZcaAuthenticated, getZaloUserInfo, getZcaUserInfo, listZaloFriendsMatching, listZaloGroupMembers, listZaloGroupsMatching, listZalouserAccountIds, logoutZaloProfile, parseZalouserOutboundTarget, resolveDefaultZalouserAccountId, resolveZaloAllowFromEntries, resolveZaloGroupsByEntries, resolveZalouserAccountSync, sendMessageZalouser, startZaloQrLogin, waitForZaloQrLogin };
@@ -1,9 +1,12 @@
1
- import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
1
+ import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, sleep } from "openclaw/plugin-sdk/text-runtime";
2
+ import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-message";
2
3
  import path from "node:path";
3
4
  import { randomUUID } from "node:crypto";
4
5
  import fs from "node:fs";
5
6
  import os from "node:os";
7
+ import { extensionForMime } from "openclaw/plugin-sdk/media-mime";
6
8
  import { loadOutboundMediaFromUrl } from "openclaw/plugin-sdk/outbound-media";
9
+ import { privateFileStoreSync, readRegularFileSync, statRegularFileSync, withTimeout } from "openclaw/plugin-sdk/security-runtime";
7
10
  import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
8
11
  //#region extensions/zalouser/src/zca-constants.ts
9
12
  const ThreadType = {
@@ -66,6 +69,24 @@ function normalizeZaloReactionIcon(raw) {
66
69
  return REACTION_ALIAS_MAP.get(normalizeLowercaseStringOrEmpty(trimmed)) ?? REACTION_ALIAS_MAP.get(trimmed) ?? trimmed;
67
70
  }
68
71
  //#endregion
72
+ //#region extensions/zalouser/src/send-receipt.ts
73
+ function createZalouserSendReceipt(params) {
74
+ const platformMessageIds = (params.platformMessageIds ?? [params.messageId]).map((messageId) => messageId?.trim()).filter((messageId) => Boolean(messageId));
75
+ const threadId = params.threadId?.trim();
76
+ return createMessageReceiptFromOutboundResults({
77
+ results: platformMessageIds.map((messageId) => {
78
+ const result = {
79
+ channel: "zalouser",
80
+ messageId
81
+ };
82
+ if (threadId) result.conversationId = threadId;
83
+ return result;
84
+ }),
85
+ ...threadId ? { threadId } : {},
86
+ kind: params.kind ?? "unknown"
87
+ });
88
+ }
89
+ //#endregion
69
90
  //#region extensions/zalouser/src/zca-client.ts
70
91
  let zcaJsRuntimePromise = null;
71
92
  async function loadZcaJsRuntime() {
@@ -110,76 +131,16 @@ function resolveCredentialsPath(profile, env = process.env) {
110
131
  function isNodeErrorCode(error, code) {
111
132
  return typeof error === "object" && error !== null && "code" in error && error.code === code;
112
133
  }
113
- function ensureCredentialsDir() {
114
- const dir = resolveCredentialsDir();
115
- fs.mkdirSync(dir, {
116
- recursive: true,
117
- mode: 448
118
- });
119
- const stat = fs.lstatSync(dir);
120
- if (!stat.isDirectory() || stat.isSymbolicLink()) throw new Error("Refusing to use non-directory Zalo credentials path");
121
- try {
122
- fs.chmodSync(dir, 448);
123
- } catch {}
124
- return dir;
125
- }
126
134
  function isReadableCredentialFile(filePath) {
127
135
  try {
128
- const stat = fs.lstatSync(filePath);
129
- return stat.isFile() && !stat.isSymbolicLink();
136
+ return !statRegularFileSync(filePath).missing;
130
137
  } catch (error) {
131
138
  if (isNodeErrorCode(error, "ENOENT")) return false;
132
139
  throw error;
133
140
  }
134
141
  }
135
- function assertWritableCredentialTarget(filePath) {
136
- try {
137
- const stat = fs.lstatSync(filePath);
138
- if (!stat.isFile() || stat.isSymbolicLink()) throw new Error("Refusing to write Zalo credentials to symlinked path");
139
- } catch (error) {
140
- if (isNodeErrorCode(error, "ENOENT")) return;
141
- throw error;
142
- }
143
- }
144
142
  function writeCredentialFileAtomic(filePath, payload) {
145
- const dir = ensureCredentialsDir();
146
- assertWritableCredentialTarget(filePath);
147
- const tempPath = path.join(dir, `.${path.basename(filePath)}.tmp-${process.pid}-${randomUUID()}`);
148
- try {
149
- fs.writeFileSync(tempPath, payload, {
150
- encoding: "utf-8",
151
- mode: 384,
152
- flag: "wx"
153
- });
154
- try {
155
- fs.chmodSync(tempPath, 384);
156
- } catch {}
157
- fs.renameSync(tempPath, filePath);
158
- try {
159
- fs.chmodSync(filePath, 384);
160
- } catch {}
161
- } finally {
162
- try {
163
- fs.unlinkSync(tempPath);
164
- } catch {}
165
- }
166
- }
167
- function withTimeout(promise, timeoutMs, label) {
168
- return new Promise((resolve, reject) => {
169
- const timer = setTimeout(() => {
170
- reject(new Error(label));
171
- }, timeoutMs);
172
- promise.then((result) => {
173
- clearTimeout(timer);
174
- resolve(result);
175
- }).catch((err) => {
176
- clearTimeout(timer);
177
- reject(err);
178
- });
179
- });
180
- }
181
- function delay(ms) {
182
- return new Promise((resolve) => setTimeout(resolve, ms));
143
+ privateFileStoreSync(resolveCredentialsDir()).writeText(path.basename(filePath), payload);
183
144
  }
184
145
  function normalizeProfile(profile) {
185
146
  const trimmed = profile?.trim();
@@ -380,7 +341,7 @@ function resolveMediaFileName(params) {
380
341
  const fromPath = path.basename(parsed.pathname).trim();
381
342
  if (fromPath) return fromPath;
382
343
  } catch {}
383
- return `upload.${params.contentType === "image/png" ? "png" : params.contentType === "image/webp" ? "webp" : params.contentType === "image/jpeg" ? "jpg" : params.contentType === "video/mp4" ? "mp4" : params.contentType === "audio/mpeg" ? "mp3" : params.contentType === "audio/ogg" ? "ogg" : params.contentType === "audio/wav" ? "wav" : params.kind === "video" ? "mp4" : params.kind === "audio" ? "mp3" : params.kind === "image" ? "jpg" : "bin"}`;
344
+ return `upload.${extensionForMime(params.contentType)?.replace(/^\./u, "") ?? (params.kind === "video" ? "mp4" : params.kind === "audio" ? "mp3" : params.kind === "image" ? "jpg" : "bin")}`;
384
345
  }
385
346
  function resolveUploadedVoiceAsset(uploaded) {
386
347
  for (const item of uploaded) {
@@ -416,7 +377,7 @@ function readCredentials(profile) {
416
377
  const filePath = resolveCredentialsPath(profile);
417
378
  try {
418
379
  if (!isReadableCredentialFile(filePath)) return null;
419
- const raw = fs.readFileSync(filePath, "utf-8");
380
+ const raw = readRegularFileSync({ filePath }).buffer.toString("utf-8");
420
381
  const parsed = JSON.parse(raw);
421
382
  if (typeof parsed.imei !== "string" || !parsed.imei || !parsed.cookie || typeof parsed.userAgent !== "string" || !parsed.userAgent) return null;
422
383
  const credentials = {
@@ -525,7 +486,7 @@ async function ensureApi(profileInput, timeoutMs = API_LOGIN_TIMEOUT_MS) {
525
486
  cookie: stored.cookie,
526
487
  userAgent: stored.userAgent,
527
488
  language: stored.language
528
- }), timeoutMs, `Timed out restoring Zalo session for profile "${profile}"`);
489
+ }), timeoutMs, { message: `Timed out restoring Zalo session for profile "${profile}"` });
529
490
  apiByProfile.set(profile, api);
530
491
  writeApiCredentials(profile, api, stored);
531
492
  return api;
@@ -669,7 +630,7 @@ async function checkZaloAuthenticated(profileInput) {
669
630
  const profile = normalizeProfile(profileInput);
670
631
  if (!zalouserSessionExists(profile)) return false;
671
632
  try {
672
- await withZaloApi(profile, async (api) => await withTimeout(api.fetchAccountInfo(), 12e3, "Timed out checking Zalo session"), { timeoutMs: 12e3 });
633
+ await withZaloApi(profile, async (api) => await withTimeout(api.fetchAccountInfo(), 12e3, { message: "Timed out checking Zalo session" }), { timeoutMs: 12e3 });
673
634
  return true;
674
635
  } catch {
675
636
  invalidateApi(profile);
@@ -799,7 +760,11 @@ async function sendZaloTextMessage(threadId, text, options = {}) {
799
760
  const trimmedThreadId = threadId.trim();
800
761
  if (!trimmedThreadId) return {
801
762
  ok: false,
802
- error: "No threadId provided"
763
+ error: "No threadId provided",
764
+ receipt: createZalouserSendReceipt({
765
+ threadId,
766
+ kind: "unknown"
767
+ })
803
768
  };
804
769
  return await withZaloApi(profile, async (api) => {
805
770
  const type = options.isGroup ? ThreadType.Group : ThreadType.User;
@@ -831,37 +796,59 @@ async function sendZaloTextMessage(threadId, text, options = {}) {
831
796
  }], trimmedThreadId, type));
832
797
  if (!voiceAsset) throw new Error("Failed to resolve uploaded audio URL for voice message");
833
798
  const voiceUrl = buildZaloVoicePlaybackUrl(voiceAsset);
799
+ const voiceMessageId = extractSendMessageId(await api.sendVoice({ voiceUrl }, trimmedThreadId, type));
834
800
  return {
835
801
  ok: true,
836
- messageId: extractSendMessageId(await api.sendVoice({ voiceUrl }, trimmedThreadId, type)) ?? textMessageId
802
+ messageId: voiceMessageId ?? textMessageId,
803
+ receipt: createZalouserSendReceipt({
804
+ platformMessageIds: [textMessageId, voiceMessageId],
805
+ threadId: trimmedThreadId,
806
+ kind: "voice"
807
+ })
837
808
  };
838
809
  }
810
+ const messageId = extractSendMessageId(await api.sendMessage({
811
+ msg: payloadText,
812
+ ...textStyles ? { styles: textStyles } : {},
813
+ attachments: [{
814
+ data: media.buffer,
815
+ filename: fileName.includes(".") ? fileName : `${fileName}.bin`,
816
+ metadata: { totalSize: media.buffer.length }
817
+ }]
818
+ }, trimmedThreadId, type));
839
819
  return {
840
820
  ok: true,
841
- messageId: extractSendMessageId(await api.sendMessage({
842
- msg: payloadText,
843
- ...textStyles ? { styles: textStyles } : {},
844
- attachments: [{
845
- data: media.buffer,
846
- filename: fileName.includes(".") ? fileName : `${fileName}.bin`,
847
- metadata: { totalSize: media.buffer.length }
848
- }]
849
- }, trimmedThreadId, type))
821
+ messageId,
822
+ receipt: createZalouserSendReceipt({
823
+ messageId,
824
+ threadId: trimmedThreadId,
825
+ kind: "media"
826
+ })
850
827
  };
851
828
  }
852
829
  const payloadText = text.slice(0, 2e3);
853
830
  const textStyles = clampTextStyles(payloadText, options.textStyles);
831
+ const messageId = extractSendMessageId(await api.sendMessage(textStyles ? {
832
+ msg: payloadText,
833
+ styles: textStyles
834
+ } : payloadText, trimmedThreadId, type));
854
835
  return {
855
836
  ok: true,
856
- messageId: extractSendMessageId(await api.sendMessage(textStyles ? {
857
- msg: payloadText,
858
- styles: textStyles
859
- } : payloadText, trimmedThreadId, type))
837
+ messageId,
838
+ receipt: createZalouserSendReceipt({
839
+ messageId,
840
+ threadId: trimmedThreadId,
841
+ kind: "text"
842
+ })
860
843
  };
861
844
  } catch (error) {
862
845
  return {
863
846
  ok: false,
864
- error: toErrorMessage(error)
847
+ error: toErrorMessage(error),
848
+ receipt: createZalouserSendReceipt({
849
+ threadId: trimmedThreadId,
850
+ kind: "unknown"
851
+ })
865
852
  };
866
853
  }
867
854
  }, { shouldPersist: (result) => result.ok });
@@ -942,11 +929,19 @@ async function sendZaloLink(threadId, url, options = {}) {
942
929
  const trimmedUrl = url.trim();
943
930
  if (!trimmedThreadId) return {
944
931
  ok: false,
945
- error: "No threadId provided"
932
+ error: "No threadId provided",
933
+ receipt: createZalouserSendReceipt({
934
+ threadId,
935
+ kind: "unknown"
936
+ })
946
937
  };
947
938
  if (!trimmedUrl) return {
948
939
  ok: false,
949
- error: "No URL provided"
940
+ error: "No URL provided",
941
+ receipt: createZalouserSendReceipt({
942
+ threadId: trimmedThreadId,
943
+ kind: "card"
944
+ })
950
945
  };
951
946
  try {
952
947
  return await withZaloApi(profile, async (api) => {
@@ -955,15 +950,25 @@ async function sendZaloLink(threadId, url, options = {}) {
955
950
  link: trimmedUrl,
956
951
  msg: options.caption
957
952
  }, trimmedThreadId, type);
953
+ const messageId = String(response.msgId);
958
954
  return {
959
955
  ok: true,
960
- messageId: String(response.msgId)
956
+ messageId,
957
+ receipt: createZalouserSendReceipt({
958
+ messageId,
959
+ threadId: trimmedThreadId,
960
+ kind: "card"
961
+ })
961
962
  };
962
963
  }, { shouldPersist: (result) => result.ok });
963
964
  } catch (error) {
964
965
  return {
965
966
  ok: false,
966
- error: toErrorMessage(error)
967
+ error: toErrorMessage(error),
968
+ receipt: createZalouserSendReceipt({
969
+ threadId: trimmedThreadId,
970
+ kind: "card"
971
+ })
967
972
  };
968
973
  }
969
974
  }
@@ -1069,7 +1074,7 @@ async function startZaloQrLogin(params) {
1069
1074
  qrDataUrl: active.qrDataUrl,
1070
1075
  message: "Scan this QR with the Zalo app."
1071
1076
  };
1072
- await delay(150);
1077
+ await sleep(150);
1073
1078
  }
1074
1079
  return { message: "Still preparing QR. Call wait to continue checking login status." };
1075
1080
  }
@@ -1108,7 +1113,7 @@ async function waitForZaloQrLogin(params) {
1108
1113
  message: "Login successful."
1109
1114
  };
1110
1115
  }
1111
- await Promise.race([active.waitPromise, delay(400)]);
1116
+ await Promise.race([active.waitPromise, sleep(400)]);
1112
1117
  }
1113
1118
  return {
1114
1119
  connected: false,
@@ -1276,4 +1281,4 @@ async function resolveZaloAllowFromEntries(params) {
1276
1281
  });
1277
1282
  }
1278
1283
  //#endregion
1279
- export { sendZaloTypingEvent as _, listZaloGroupMembers as a, waitForZaloQrLogin as b, logoutZaloProfile as c, resolveZaloGroupsByEntries as d, sendZaloDeliveredEvent as f, sendZaloTextMessage as g, sendZaloSeenEvent as h, listZaloFriendsMatching as i, resolveZaloAllowFromEntries as l, sendZaloReaction as m, getZaloUserInfo as n, listZaloGroups as o, sendZaloLink as p, listZaloFriends as r, listZaloGroupsMatching as s, checkZaloAuthenticated as t, resolveZaloGroupContext as u, startZaloListener as v, TextStyle as x, startZaloQrLogin as y };
1284
+ export { TextStyle as S, sendZaloTypingEvent as _, listZaloGroupMembers as a, waitForZaloQrLogin as b, logoutZaloProfile as c, resolveZaloGroupsByEntries as d, sendZaloDeliveredEvent as f, sendZaloTextMessage as g, sendZaloSeenEvent as h, listZaloFriendsMatching as i, resolveZaloAllowFromEntries as l, sendZaloReaction as m, getZaloUserInfo as n, listZaloGroups as o, sendZaloLink as p, listZaloFriends as r, listZaloGroupsMatching as s, checkZaloAuthenticated as t, resolveZaloGroupContext as u, startZaloListener as v, createZalouserSendReceipt as x, startZaloQrLogin as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/zalouser",
3
- "version": "2026.5.7",
3
+ "version": "2026.5.9-beta.1",
4
4
  "description": "OpenClaw Zalo Personal Account plugin via native zca-js integration",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "type": "module",
10
10
  "dependencies": {
11
- "typebox": "1.1.37",
11
+ "typebox": "1.1.38",
12
12
  "zca-js": "2.1.2"
13
13
  },
14
14
  "devDependencies": {
@@ -16,7 +16,7 @@
16
16
  "openclaw": "workspace:*"
17
17
  },
18
18
  "peerDependencies": {
19
- "openclaw": ">=2026.5.7"
19
+ "openclaw": ">=2026.5.9-beta.1"
20
20
  },
21
21
  "peerDependenciesMeta": {
22
22
  "openclaw": {
@@ -53,10 +53,10 @@
53
53
  "minHostVersion": ">=2026.4.10"
54
54
  },
55
55
  "compat": {
56
- "pluginApi": ">=2026.5.7"
56
+ "pluginApi": ">=2026.5.9-beta.1"
57
57
  },
58
58
  "build": {
59
- "openclawVersion": "2026.5.7"
59
+ "openclawVersion": "2026.5.9-beta.1"
60
60
  },
61
61
  "release": {
62
62
  "publishToClawHub": true,