@openclaw/zalouser 2026.5.2 → 2026.5.3-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/accounts-C00IMUgd.js +63 -0
  2. package/dist/accounts.runtime-uG7S8cXT.js +2 -0
  3. package/dist/api-BRwdUWuS.js +139 -0
  4. package/dist/api.js +7 -0
  5. package/dist/channel-ou_w_2j-.js +484 -0
  6. package/dist/channel-plugin-api.js +2 -0
  7. package/dist/channel.runtime-C9WxiAiR.js +25 -0
  8. package/dist/channel.setup-CiDeBFrn.js +10 -0
  9. package/dist/contract-api.js +3 -0
  10. package/dist/doctor-contract-DgqHp8E2.js +128 -0
  11. package/dist/doctor-contract-api.js +2 -0
  12. package/dist/index.js +27 -0
  13. package/dist/monitor-Cg7K_s_s.js +705 -0
  14. package/dist/runtime-QNU7vLgI.js +106 -0
  15. package/dist/runtime-api.js +22 -0
  16. package/dist/secret-contract-api.js +5 -0
  17. package/dist/security-audit-BZLhil-V.js +34 -0
  18. package/dist/send-BsmySxe3.js +534 -0
  19. package/dist/session-route-C0-Xr8bt.js +92 -0
  20. package/dist/setup-core-CqipqY98.js +40 -0
  21. package/dist/setup-entry.js +11 -0
  22. package/dist/setup-plugin-api.js +2 -0
  23. package/dist/setup-surface-NCOuKu-l.js +359 -0
  24. package/dist/shared-DSy8aIUx.js +120 -0
  25. package/dist/test-api.js +5 -0
  26. package/dist/zalo-js-CHCUlY3c.js +1279 -0
  27. package/package.json +15 -6
  28. package/api.ts +0 -9
  29. package/channel-plugin-api.ts +0 -3
  30. package/contract-api.ts +0 -2
  31. package/doctor-contract-api.ts +0 -1
  32. package/index.ts +0 -34
  33. package/runtime-api.ts +0 -67
  34. package/secret-contract-api.ts +0 -4
  35. package/setup-entry.ts +0 -9
  36. package/setup-plugin-api.ts +0 -2
  37. package/src/accounts.runtime.ts +0 -1
  38. package/src/accounts.test-mocks.ts +0 -14
  39. package/src/accounts.test.ts +0 -266
  40. package/src/accounts.ts +0 -131
  41. package/src/channel-api.ts +0 -20
  42. package/src/channel.adapters.ts +0 -391
  43. package/src/channel.directory.test.ts +0 -59
  44. package/src/channel.runtime.ts +0 -12
  45. package/src/channel.sendpayload.test.ts +0 -172
  46. package/src/channel.setup.test.ts +0 -33
  47. package/src/channel.setup.ts +0 -12
  48. package/src/channel.test.ts +0 -377
  49. package/src/channel.ts +0 -219
  50. package/src/config-schema.ts +0 -33
  51. package/src/directory.ts +0 -54
  52. package/src/doctor-contract.ts +0 -156
  53. package/src/doctor.test.ts +0 -77
  54. package/src/doctor.ts +0 -37
  55. package/src/group-policy.test.ts +0 -61
  56. package/src/group-policy.ts +0 -83
  57. package/src/message-sid.test.ts +0 -66
  58. package/src/message-sid.ts +0 -80
  59. package/src/monitor.account-scope.test.ts +0 -107
  60. package/src/monitor.group-gating.test.ts +0 -816
  61. package/src/monitor.send-mocks.ts +0 -20
  62. package/src/monitor.ts +0 -1044
  63. package/src/probe.test.ts +0 -60
  64. package/src/probe.ts +0 -35
  65. package/src/qr-temp-file.ts +0 -22
  66. package/src/reaction.test.ts +0 -19
  67. package/src/reaction.ts +0 -32
  68. package/src/runtime.ts +0 -9
  69. package/src/security-audit.test.ts +0 -80
  70. package/src/security-audit.ts +0 -71
  71. package/src/send.test.ts +0 -395
  72. package/src/send.ts +0 -272
  73. package/src/session-route.ts +0 -121
  74. package/src/setup-core.ts +0 -33
  75. package/src/setup-surface.test.ts +0 -363
  76. package/src/setup-surface.ts +0 -470
  77. package/src/setup-test-helpers.ts +0 -42
  78. package/src/shared.ts +0 -92
  79. package/src/status-issues.test.ts +0 -31
  80. package/src/status-issues.ts +0 -58
  81. package/src/test-helpers.ts +0 -26
  82. package/src/text-styles.test.ts +0 -203
  83. package/src/text-styles.ts +0 -540
  84. package/src/tool.test.ts +0 -212
  85. package/src/tool.ts +0 -210
  86. package/src/types.ts +0 -125
  87. package/src/zalo-js.credentials.test.ts +0 -465
  88. package/src/zalo-js.test-mocks.ts +0 -89
  89. package/src/zalo-js.ts +0 -1911
  90. package/src/zca-client.test.ts +0 -24
  91. package/src/zca-client.ts +0 -259
  92. package/src/zca-constants.ts +0 -55
  93. package/src/zca-js-exports.d.ts +0 -22
  94. package/test-api.ts +0 -21
  95. package/tsconfig.json +0 -16
@@ -1,377 +0,0 @@
1
- import { createNonExitingRuntimeEnv } from "openclaw/plugin-sdk/plugin-test-runtime";
2
- import { beforeEach, describe, expect, it, vi } from "vitest";
3
- import "./zalo-js.test-mocks.js";
4
- import {
5
- zalouserAuthAdapter,
6
- zalouserGroupsAdapter,
7
- zalouserMessageActions,
8
- zalouserOutboundAdapter,
9
- zalouserPairingTextAdapter,
10
- zalouserResolverAdapter,
11
- zalouserSecurityAdapter,
12
- } from "./channel.adapters.js";
13
- import { setZalouserRuntime } from "./runtime.js";
14
- import { sendMessageZalouser, sendReactionZalouser } from "./send.js";
15
- import {
16
- listZaloFriendsMatchingMock,
17
- startZaloQrLoginMock,
18
- waitForZaloQrLoginMock,
19
- } from "./zalo-js.test-mocks.js";
20
-
21
- vi.mock("./qr-temp-file.js", () => ({
22
- writeQrDataUrlToTempFile: vi.fn(async () => null),
23
- }));
24
-
25
- vi.mock("./send.js", async () => {
26
- const actual = (await vi.importActual("./send.js")) as Record<string, unknown>;
27
- return {
28
- ...actual,
29
- sendMessageZalouser: vi.fn(async () => ({ ok: true, messageId: "mid-1" })),
30
- sendReactionZalouser: vi.fn(async () => ({ ok: true })),
31
- };
32
- });
33
-
34
- const mockSendMessage = vi.mocked(sendMessageZalouser);
35
- const mockSendReaction = vi.mocked(sendReactionZalouser);
36
-
37
- function requireZalouserSendText() {
38
- const sendText = zalouserOutboundAdapter.sendText;
39
- if (!sendText) {
40
- throw new Error("zalouser outbound.sendText unavailable");
41
- }
42
- return sendText;
43
- }
44
-
45
- function getResolveToolPolicy() {
46
- const resolveToolPolicy = zalouserGroupsAdapter.resolveToolPolicy;
47
- if (!resolveToolPolicy) {
48
- throw new Error("resolveToolPolicy unavailable");
49
- }
50
- return resolveToolPolicy;
51
- }
52
-
53
- function requireZalouserResolveRequireMention() {
54
- const resolveRequireMention = zalouserGroupsAdapter.resolveRequireMention;
55
- if (!resolveRequireMention) {
56
- throw new Error("resolveRequireMention unavailable");
57
- }
58
- return resolveRequireMention;
59
- }
60
-
61
- function requireZalouserPairingNormalizer() {
62
- const normalizeAllowEntry = zalouserPairingTextAdapter.normalizeAllowEntry;
63
- if (!normalizeAllowEntry) {
64
- throw new Error("pairing.normalizeAllowEntry unavailable");
65
- }
66
- return normalizeAllowEntry;
67
- }
68
-
69
- function resolveGroupToolPolicy(
70
- groups: Record<string, { tools: { allow?: string[]; deny?: string[] } }>,
71
- groupId: string,
72
- ) {
73
- return getResolveToolPolicy()({
74
- cfg: {
75
- channels: {
76
- zalouser: {
77
- groups,
78
- },
79
- },
80
- },
81
- accountId: "default",
82
- groupId,
83
- groupChannel: groupId,
84
- });
85
- }
86
-
87
- describe("zalouser outbound", () => {
88
- beforeEach(() => {
89
- mockSendMessage.mockClear();
90
- setZalouserRuntime({
91
- channel: {
92
- text: {
93
- resolveChunkMode: vi.fn(() => "newline"),
94
- resolveTextChunkLimit: vi.fn(() => 10),
95
- },
96
- },
97
- } as never);
98
- });
99
-
100
- it("passes markdown chunk settings through sendText", async () => {
101
- const sendText = requireZalouserSendText();
102
-
103
- const result = await sendText({
104
- cfg: { channels: { zalouser: { enabled: true } } } as never,
105
- to: "group:123456",
106
- text: "hello world\nthis is a test",
107
- accountId: "default",
108
- } as never);
109
-
110
- expect(mockSendMessage).toHaveBeenCalledWith(
111
- "123456",
112
- "hello world\nthis is a test",
113
- expect.objectContaining({
114
- profile: "default",
115
- isGroup: true,
116
- textMode: "markdown",
117
- textChunkMode: "newline",
118
- textChunkLimit: 10,
119
- }),
120
- );
121
- expect(result).toEqual(
122
- expect.objectContaining({
123
- channel: "zalouser",
124
- messageId: "mid-1",
125
- ok: true,
126
- }),
127
- );
128
- });
129
- });
130
-
131
- describe("zalouser outbound chunking", () => {
132
- it("chunks outbound text without requiring Zalouser runtime initialization", () => {
133
- const chunker = zalouserOutboundAdapter.chunker;
134
- if (!chunker) {
135
- throw new Error("zalouser outbound.chunker unavailable");
136
- }
137
-
138
- expect(chunker("alpha beta", 5)).toEqual(["alpha", "beta"]);
139
- });
140
- });
141
-
142
- describe("zalouser channel policies", () => {
143
- beforeEach(() => {
144
- mockSendReaction.mockClear();
145
- mockSendReaction.mockResolvedValue({ ok: true });
146
- });
147
-
148
- it("normalizes dm allowlist entries after trimming channel prefixes", () => {
149
- const resolveDmPolicy = zalouserSecurityAdapter.resolveDmPolicy;
150
- if (!resolveDmPolicy) {
151
- throw new Error("resolveDmPolicy unavailable");
152
- }
153
-
154
- const cfg = {
155
- channels: {
156
- zalouser: {
157
- dmPolicy: "allowlist",
158
- allowFrom: [" zlu:123456 "],
159
- },
160
- },
161
- } as never;
162
- const account = {
163
- accountId: "default",
164
- enabled: true,
165
- authenticated: false,
166
- profile: "default",
167
- config: {
168
- dmPolicy: "allowlist",
169
- allowFrom: [" zlu:123456 "],
170
- },
171
- } as never;
172
-
173
- const result = resolveDmPolicy({ cfg, account });
174
- if (!result) {
175
- throw new Error("zalouser resolveDmPolicy returned null");
176
- }
177
-
178
- expect(result.policy).toBe("allowlist");
179
- expect(result.allowFrom).toEqual([" zlu:123456 "]);
180
- expect(result.normalizeEntry?.(" zlu:123456 ")).toBe("123456");
181
- });
182
-
183
- it("normalizes pairing allowlist entries after trimming channel prefixes", () => {
184
- const normalizeAllowEntry = requireZalouserPairingNormalizer();
185
-
186
- expect(normalizeAllowEntry(" zlu:123456 ")).toBe("123456");
187
- expect(normalizeAllowEntry(" zalouser:654321 ")).toBe("654321");
188
- });
189
-
190
- it("resolves requireMention from group config", () => {
191
- const resolveRequireMention = requireZalouserResolveRequireMention();
192
- const requireMention = resolveRequireMention({
193
- cfg: {
194
- channels: {
195
- zalouser: {
196
- groups: {
197
- "123": { requireMention: false },
198
- },
199
- },
200
- },
201
- },
202
- accountId: "default",
203
- groupId: "123",
204
- groupChannel: "123",
205
- });
206
- expect(requireMention).toBe(false);
207
- });
208
-
209
- it("resolves group tool policy by explicit group id", () => {
210
- const policy = resolveGroupToolPolicy({ "123": { tools: { allow: ["search"] } } }, "123");
211
- expect(policy).toEqual({ allow: ["search"] });
212
- });
213
-
214
- it("falls back to wildcard group policy", () => {
215
- const policy = resolveGroupToolPolicy({ "*": { tools: { deny: ["system.run"] } } }, "missing");
216
- expect(policy).toEqual({ deny: ["system.run"] });
217
- });
218
-
219
- it("handles react action", async () => {
220
- const actions = zalouserMessageActions;
221
- expect(
222
- actions?.describeMessageTool?.({ cfg: { channels: { zalouser: { enabled: true } } } })
223
- ?.actions,
224
- ).toEqual(["react"]);
225
- const result = await actions?.handleAction?.({
226
- channel: "zalouser",
227
- action: "react",
228
- params: {
229
- threadId: "123456",
230
- messageId: "111",
231
- cliMsgId: "222",
232
- emoji: "👍",
233
- },
234
- cfg: {
235
- channels: {
236
- zalouser: {
237
- enabled: true,
238
- profile: "default",
239
- },
240
- },
241
- },
242
- });
243
- expect(mockSendReaction).toHaveBeenCalledWith({
244
- profile: "default",
245
- threadId: "123456",
246
- isGroup: false,
247
- msgId: "111",
248
- cliMsgId: "222",
249
- emoji: "👍",
250
- remove: false,
251
- });
252
- expect(result).toMatchObject({
253
- content: [{ type: "text", text: "Reacted 👍 on 111" }],
254
- details: {
255
- messageId: "111",
256
- cliMsgId: "222",
257
- threadId: "123456",
258
- },
259
- });
260
- });
261
-
262
- it("honors the selected Zalouser account during discovery", () => {
263
- const actions = zalouserMessageActions;
264
- const cfg = {
265
- channels: {
266
- zalouser: {
267
- enabled: true,
268
- profile: "default",
269
- accounts: {
270
- default: {
271
- enabled: false,
272
- profile: "default",
273
- },
274
- work: {
275
- enabled: true,
276
- profile: "work",
277
- },
278
- },
279
- },
280
- },
281
- };
282
-
283
- expect(actions?.describeMessageTool?.({ cfg, accountId: "default" })).toBeNull();
284
- expect(actions?.describeMessageTool?.({ cfg, accountId: "work" })?.actions).toEqual(["react"]);
285
- });
286
- });
287
-
288
- describe("zalouser account resolution", () => {
289
- beforeEach(() => {
290
- listZaloFriendsMatchingMock.mockReset();
291
- startZaloQrLoginMock.mockReset();
292
- waitForZaloQrLoginMock.mockReset();
293
- });
294
-
295
- it("uses the configured default account for omitted target lookup", async () => {
296
- const resolveTargets = zalouserResolverAdapter.resolveTargets;
297
- if (!resolveTargets) {
298
- throw new Error("zalouser resolver.resolveTargets unavailable");
299
- }
300
-
301
- listZaloFriendsMatchingMock.mockResolvedValue([
302
- { userId: "42", displayName: "Work User" } as never,
303
- ]);
304
-
305
- const result = await resolveTargets({
306
- cfg: {
307
- channels: {
308
- zalouser: {
309
- defaultAccount: "work",
310
- accounts: {
311
- work: {
312
- profile: "work-profile",
313
- },
314
- },
315
- },
316
- },
317
- } as never,
318
- inputs: ["Work User"],
319
- kind: "user",
320
- runtime: createNonExitingRuntimeEnv(),
321
- });
322
-
323
- expect(listZaloFriendsMatchingMock).toHaveBeenCalledWith("work-profile", "Work User");
324
- expect(result).toEqual([
325
- expect.objectContaining({
326
- input: "Work User",
327
- resolved: true,
328
- id: "42",
329
- name: "Work User",
330
- }),
331
- ]);
332
- });
333
-
334
- it("uses the configured default account for omitted qr login", async () => {
335
- const login = zalouserAuthAdapter.login;
336
- if (!login) {
337
- throw new Error("zalouser auth.login unavailable");
338
- }
339
-
340
- startZaloQrLoginMock.mockResolvedValue({
341
- message: "qr ready",
342
- qrDataUrl: "data:image/png;base64,abc",
343
- } as never);
344
- waitForZaloQrLoginMock.mockResolvedValue({
345
- connected: true,
346
- userId: "u-1",
347
- displayName: "Work User",
348
- } as never);
349
-
350
- const runtime = createNonExitingRuntimeEnv();
351
-
352
- await login({
353
- cfg: {
354
- channels: {
355
- zalouser: {
356
- defaultAccount: "work",
357
- accounts: {
358
- work: {
359
- profile: "work-profile",
360
- },
361
- },
362
- },
363
- },
364
- } as never,
365
- runtime,
366
- });
367
-
368
- expect(startZaloQrLoginMock).toHaveBeenCalledWith({
369
- profile: "work-profile",
370
- timeoutMs: 35_000,
371
- });
372
- expect(waitForZaloQrLoginMock).toHaveBeenCalledWith({
373
- profile: "work-profile",
374
- timeoutMs: 180_000,
375
- });
376
- });
377
- });
package/src/channel.ts DELETED
@@ -1,219 +0,0 @@
1
- import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
2
- import { createAccountStatusSink } from "openclaw/plugin-sdk/channel-lifecycle";
3
- import { buildPassiveProbedChannelStatusSummary } from "openclaw/plugin-sdk/extension-shared";
4
- import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
5
- import {
6
- createAsyncComputedAccountStatusAdapter,
7
- createDefaultChannelRuntimeState,
8
- } from "openclaw/plugin-sdk/status-helpers";
9
- import {
10
- checkZcaAuthenticated,
11
- resolveZalouserAccountSync,
12
- type ResolvedZalouserAccount,
13
- } from "./accounts.js";
14
- import type { ChannelDirectoryEntry, ChannelPlugin } from "./channel-api.js";
15
- import { DEFAULT_ACCOUNT_ID } from "./channel-api.js";
16
- import {
17
- zalouserAuthAdapter,
18
- zalouserGroupsAdapter,
19
- zalouserMessageActions,
20
- zalouserMessagingAdapter,
21
- zalouserOutboundAdapter,
22
- zalouserPairingTextAdapter,
23
- resolveZalouserQrProfile,
24
- zalouserResolverAdapter,
25
- zalouserSecurityAdapter,
26
- zalouserThreadingAdapter,
27
- } from "./channel.adapters.js";
28
- import { listZalouserDirectoryGroupMembers } from "./directory.js";
29
- import type { ZalouserProbeResult } from "./probe.js";
30
- import { createZalouserSetupWizardProxy, zalouserSetupAdapter } from "./setup-core.js";
31
- import { createZalouserPluginBase } from "./shared.js";
32
- import { collectZalouserStatusIssues } from "./status-issues.js";
33
-
34
- const loadZalouserChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime.js"));
35
- const zalouserSetupWizardProxy = createZalouserSetupWizardProxy(
36
- async () => (await import("./setup-surface.js")).zalouserSetupWizard,
37
- );
38
-
39
- function mapUser(params: {
40
- id: string;
41
- name?: string | null;
42
- avatarUrl?: string | null;
43
- raw?: unknown;
44
- }): ChannelDirectoryEntry {
45
- return {
46
- kind: "user",
47
- id: params.id,
48
- name: params.name ?? undefined,
49
- avatarUrl: params.avatarUrl ?? undefined,
50
- raw: params.raw,
51
- };
52
- }
53
-
54
- function mapGroup(params: {
55
- id: string;
56
- name?: string | null;
57
- raw?: unknown;
58
- }): ChannelDirectoryEntry {
59
- return {
60
- kind: "group",
61
- id: params.id,
62
- name: params.name ?? undefined,
63
- raw: params.raw,
64
- };
65
- }
66
-
67
- export const zalouserPlugin: ChannelPlugin<ResolvedZalouserAccount, ZalouserProbeResult> =
68
- createChatChannelPlugin({
69
- base: {
70
- ...createZalouserPluginBase({
71
- setupWizard: zalouserSetupWizardProxy,
72
- setup: zalouserSetupAdapter,
73
- }),
74
- groups: zalouserGroupsAdapter,
75
- actions: zalouserMessageActions,
76
- messaging: zalouserMessagingAdapter,
77
- directory: {
78
- self: async ({ cfg, accountId }) => {
79
- const { getZaloUserInfo } = await loadZalouserChannelRuntime();
80
- const account = resolveZalouserAccountSync({ cfg: cfg, accountId });
81
- const parsed = await getZaloUserInfo(account.profile);
82
- if (!parsed?.userId) {
83
- return null;
84
- }
85
- return mapUser({
86
- id: parsed.userId,
87
- name: parsed.displayName ?? null,
88
- avatarUrl: parsed.avatar ?? null,
89
- raw: parsed,
90
- });
91
- },
92
- listPeers: async ({ cfg, accountId, query, limit }) => {
93
- const { listZaloFriendsMatching } = await loadZalouserChannelRuntime();
94
- const account = resolveZalouserAccountSync({ cfg: cfg, accountId });
95
- const friends = await listZaloFriendsMatching(account.profile, query);
96
- const rows = friends.map((friend) =>
97
- mapUser({
98
- id: friend.userId,
99
- name: friend.displayName ?? null,
100
- avatarUrl: friend.avatar ?? null,
101
- raw: friend,
102
- }),
103
- );
104
- return typeof limit === "number" && limit > 0 ? rows.slice(0, limit) : rows;
105
- },
106
- listGroups: async ({ cfg, accountId, query, limit }) => {
107
- const { listZaloGroupsMatching } = await loadZalouserChannelRuntime();
108
- const account = resolveZalouserAccountSync({ cfg: cfg, accountId });
109
- const groups = await listZaloGroupsMatching(account.profile, query);
110
- const rows = groups.map((group) =>
111
- mapGroup({
112
- id: `group:${group.groupId}`,
113
- name: group.name ?? null,
114
- raw: group,
115
- }),
116
- );
117
- return typeof limit === "number" && limit > 0 ? rows.slice(0, limit) : rows;
118
- },
119
- listGroupMembers: async ({ cfg, accountId, groupId, limit }) => {
120
- const { listZaloGroupMembers } = await loadZalouserChannelRuntime();
121
- return await listZalouserDirectoryGroupMembers(
122
- {
123
- cfg,
124
- accountId: accountId ?? undefined,
125
- groupId,
126
- limit: limit ?? undefined,
127
- },
128
- { listZaloGroupMembers },
129
- );
130
- },
131
- },
132
- resolver: zalouserResolverAdapter,
133
- auth: zalouserAuthAdapter,
134
- status: createAsyncComputedAccountStatusAdapter<ResolvedZalouserAccount, ZalouserProbeResult>(
135
- {
136
- defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID),
137
- collectStatusIssues: collectZalouserStatusIssues,
138
- buildChannelSummary: ({ snapshot }) => buildPassiveProbedChannelStatusSummary(snapshot),
139
- probeAccount: async ({ account, timeoutMs }) =>
140
- (await loadZalouserChannelRuntime()).probeZalouser(account.profile, timeoutMs),
141
- resolveAccountSnapshot: async ({ account, runtime }) => {
142
- const configured = await checkZcaAuthenticated(account.profile);
143
- const configError = "not authenticated";
144
- return {
145
- accountId: account.accountId,
146
- name: account.name,
147
- enabled: account.enabled,
148
- configured,
149
- extra: {
150
- dmPolicy: account.config.dmPolicy ?? "pairing",
151
- lastError: configured
152
- ? (runtime?.lastError ?? null)
153
- : (runtime?.lastError ?? configError),
154
- },
155
- };
156
- },
157
- },
158
- ),
159
- gateway: {
160
- startAccount: async (ctx) => {
161
- const { getZaloUserInfo } = await loadZalouserChannelRuntime();
162
- const account = ctx.account;
163
- let userLabel = "";
164
- try {
165
- const userInfo = await getZaloUserInfo(account.profile);
166
- if (userInfo?.displayName) {
167
- userLabel = ` (${userInfo.displayName})`;
168
- }
169
- ctx.setStatus({
170
- accountId: account.accountId,
171
- profile: userInfo,
172
- });
173
- } catch {
174
- // ignore probe errors
175
- }
176
- const statusSink = createAccountStatusSink({
177
- accountId: ctx.accountId,
178
- setStatus: ctx.setStatus,
179
- });
180
- ctx.log?.info(`[${account.accountId}] starting zalouser provider${userLabel}`);
181
- const { monitorZalouserProvider } = await import("./monitor.js");
182
- return monitorZalouserProvider({
183
- account,
184
- config: ctx.cfg,
185
- runtime: ctx.runtime,
186
- abortSignal: ctx.abortSignal,
187
- statusSink,
188
- });
189
- },
190
- loginWithQrStart: async (params) => {
191
- const { startZaloQrLogin } = await loadZalouserChannelRuntime();
192
- const profile = resolveZalouserQrProfile(params.accountId);
193
- return await startZaloQrLogin({
194
- profile,
195
- force: params.force,
196
- timeoutMs: params.timeoutMs,
197
- });
198
- },
199
- loginWithQrWait: async (params) => {
200
- const { waitForZaloQrLogin } = await loadZalouserChannelRuntime();
201
- const profile = resolveZalouserQrProfile(params.accountId);
202
- return await waitForZaloQrLogin({
203
- profile,
204
- timeoutMs: params.timeoutMs,
205
- });
206
- },
207
- logoutAccount: async (ctx) =>
208
- await (
209
- await loadZalouserChannelRuntime()
210
- ).logoutZaloProfile(ctx.account.profile || resolveZalouserQrProfile(ctx.accountId)),
211
- },
212
- },
213
- security: zalouserSecurityAdapter,
214
- threading: zalouserThreadingAdapter,
215
- pairing: {
216
- text: zalouserPairingTextAdapter,
217
- },
218
- outbound: zalouserOutboundAdapter,
219
- });
@@ -1,33 +0,0 @@
1
- import {
2
- AllowFromListSchema,
3
- buildCatchallMultiAccountChannelSchema,
4
- DmPolicySchema,
5
- GroupPolicySchema,
6
- MarkdownConfigSchema,
7
- ToolPolicySchema,
8
- } from "openclaw/plugin-sdk/channel-config-schema";
9
- import { z } from "openclaw/plugin-sdk/zod";
10
-
11
- const groupConfigSchema = z.object({
12
- enabled: z.boolean().optional(),
13
- requireMention: z.boolean().optional(),
14
- tools: ToolPolicySchema,
15
- });
16
-
17
- const zalouserAccountSchema = z.object({
18
- name: z.string().optional(),
19
- enabled: z.boolean().optional(),
20
- markdown: MarkdownConfigSchema,
21
- profile: z.string().optional(),
22
- dangerouslyAllowNameMatching: z.boolean().optional(),
23
- dmPolicy: DmPolicySchema.optional(),
24
- allowFrom: AllowFromListSchema,
25
- historyLimit: z.number().int().min(0).optional(),
26
- groupAllowFrom: AllowFromListSchema,
27
- groupPolicy: GroupPolicySchema.optional().default("allowlist"),
28
- groups: z.object({}).catchall(groupConfigSchema).optional(),
29
- messagePrefix: z.string().optional(),
30
- responsePrefix: z.string().optional(),
31
- });
32
-
33
- export const ZalouserConfigSchema = buildCatchallMultiAccountChannelSchema(zalouserAccountSchema);
package/src/directory.ts DELETED
@@ -1,54 +0,0 @@
1
- import { resolveZalouserAccountSync } from "./accounts.js";
2
- import type { ChannelDirectoryEntry, OpenClawConfig } from "./channel-api.js";
3
- import { parseZalouserDirectoryGroupId } from "./session-route.js";
4
-
5
- type ZalouserDirectoryDeps = {
6
- listZaloGroupMembers: (
7
- profile: string,
8
- groupId: string,
9
- ) => Promise<
10
- Array<{
11
- userId: string;
12
- displayName?: string | null;
13
- avatar?: string | null;
14
- }>
15
- >;
16
- };
17
-
18
- function mapUser(params: {
19
- id: string;
20
- name?: string | null;
21
- avatarUrl?: string | null;
22
- raw?: unknown;
23
- }): ChannelDirectoryEntry {
24
- return {
25
- kind: "user",
26
- id: params.id,
27
- name: params.name ?? undefined,
28
- avatarUrl: params.avatarUrl ?? undefined,
29
- raw: params.raw,
30
- };
31
- }
32
-
33
- export async function listZalouserDirectoryGroupMembers(
34
- params: {
35
- cfg: OpenClawConfig;
36
- accountId?: string;
37
- groupId: string;
38
- limit?: number;
39
- },
40
- deps: ZalouserDirectoryDeps,
41
- ) {
42
- const account = resolveZalouserAccountSync({ cfg: params.cfg, accountId: params.accountId });
43
- const normalizedGroupId = parseZalouserDirectoryGroupId(params.groupId);
44
- const members = await deps.listZaloGroupMembers(account.profile, normalizedGroupId);
45
- const rows = members.map((member) =>
46
- mapUser({
47
- id: member.userId,
48
- name: member.displayName,
49
- avatarUrl: member.avatar ?? null,
50
- raw: member,
51
- }),
52
- );
53
- return typeof params.limit === "number" && params.limit > 0 ? rows.slice(0, params.limit) : rows;
54
- }