@openclaw/zalo 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 (87) hide show
  1. package/dist/accounts-9NLDDlZ8.js +118 -0
  2. package/dist/actions.runtime-kJ65ZxW7.js +5 -0
  3. package/dist/api.js +5 -0
  4. package/dist/channel-VPbtV3Oq.js +343 -0
  5. package/dist/channel-plugin-api.js +2 -0
  6. package/dist/channel.runtime-BnTAWQx5.js +106 -0
  7. package/dist/contract-api.js +3 -0
  8. package/dist/group-access-DZR43lOR.js +30 -0
  9. package/dist/index.js +22 -0
  10. package/dist/monitor-DMysJBWa.js +823 -0
  11. package/dist/monitor.webhook-DqnuvgjV.js +175 -0
  12. package/dist/proxy-CY8VuC6H.js +135 -0
  13. package/dist/runtime-BRFxnYQx.js +8 -0
  14. package/dist/runtime-api-MOTmRW4F.js +19 -0
  15. package/dist/runtime-api.js +3 -0
  16. package/dist/secret-contract-Dw93tGo2.js +87 -0
  17. package/dist/secret-contract-api.js +2 -0
  18. package/dist/send-Gv3l5EGI.js +101 -0
  19. package/dist/setup-api.js +30 -0
  20. package/dist/setup-core-DigRD3j1.js +166 -0
  21. package/dist/setup-entry.js +15 -0
  22. package/dist/setup-surface-2Up3yWov.js +216 -0
  23. package/dist/test-api.js +2 -0
  24. package/package.json +15 -6
  25. package/api.ts +0 -9
  26. package/channel-plugin-api.ts +0 -1
  27. package/contract-api.ts +0 -5
  28. package/index.test.ts +0 -15
  29. package/index.ts +0 -20
  30. package/runtime-api.test.ts +0 -17
  31. package/runtime-api.ts +0 -75
  32. package/secret-contract-api.ts +0 -5
  33. package/setup-api.ts +0 -34
  34. package/setup-entry.ts +0 -13
  35. package/src/accounts.test.ts +0 -70
  36. package/src/accounts.ts +0 -60
  37. package/src/actions.runtime.ts +0 -5
  38. package/src/actions.test.ts +0 -32
  39. package/src/actions.ts +0 -62
  40. package/src/api.test.ts +0 -149
  41. package/src/api.ts +0 -265
  42. package/src/approval-auth.test.ts +0 -17
  43. package/src/approval-auth.ts +0 -25
  44. package/src/channel.directory.test.ts +0 -59
  45. package/src/channel.runtime.ts +0 -93
  46. package/src/channel.startup.test.ts +0 -101
  47. package/src/channel.ts +0 -275
  48. package/src/config-schema.test.ts +0 -30
  49. package/src/config-schema.ts +0 -29
  50. package/src/group-access.ts +0 -49
  51. package/src/monitor.group-policy.test.ts +0 -94
  52. package/src/monitor.image.polling.test.ts +0 -110
  53. package/src/monitor.lifecycle.test.ts +0 -198
  54. package/src/monitor.pairing.lifecycle.test.ts +0 -141
  55. package/src/monitor.polling.media-reply.test.ts +0 -425
  56. package/src/monitor.reply-once.lifecycle.test.ts +0 -171
  57. package/src/monitor.ts +0 -1028
  58. package/src/monitor.types.ts +0 -4
  59. package/src/monitor.webhook.test.ts +0 -806
  60. package/src/monitor.webhook.ts +0 -278
  61. package/src/outbound-media.test.ts +0 -182
  62. package/src/outbound-media.ts +0 -241
  63. package/src/outbound-payload.contract.test.ts +0 -45
  64. package/src/probe.ts +0 -45
  65. package/src/proxy.ts +0 -24
  66. package/src/runtime-api.ts +0 -75
  67. package/src/runtime-support.ts +0 -91
  68. package/src/runtime.ts +0 -9
  69. package/src/secret-contract.ts +0 -109
  70. package/src/secret-input.ts +0 -5
  71. package/src/send.test.ts +0 -120
  72. package/src/send.ts +0 -153
  73. package/src/session-route.ts +0 -32
  74. package/src/setup-allow-from.ts +0 -94
  75. package/src/setup-core.ts +0 -149
  76. package/src/setup-status.test.ts +0 -33
  77. package/src/setup-surface.test.ts +0 -175
  78. package/src/setup-surface.ts +0 -291
  79. package/src/status-issues.test.ts +0 -17
  80. package/src/status-issues.ts +0 -37
  81. package/src/test-support/lifecycle-test-support.ts +0 -413
  82. package/src/test-support/monitor-mocks-test-support.ts +0 -209
  83. package/src/token.test.ts +0 -92
  84. package/src/token.ts +0 -79
  85. package/src/types.ts +0 -50
  86. package/test-api.ts +0 -1
  87. package/tsconfig.json +0 -16
@@ -0,0 +1,166 @@
1
+ import { a as resolveZaloAccount, i as resolveDefaultZaloAccountId } from "./accounts-9NLDDlZ8.js";
2
+ import { DEFAULT_ACCOUNT_ID, addWildcardAllowFrom, createDelegatedSetupWizardProxy, createPatchedAccountSetupAdapter, createSetupInputPresenceValidator, formatDocsLink, mergeAllowFromEntries, normalizeAccountId } from "openclaw/plugin-sdk/setup";
3
+ //#region extensions/zalo/src/setup-allow-from.ts
4
+ async function noteZaloTokenHelp(prompter) {
5
+ await prompter.note([
6
+ "1) Open Zalo Bot Platform: https://bot.zaloplatforms.com",
7
+ "2) Create a bot and get the token",
8
+ "3) Token looks like 12345689:abc-xyz",
9
+ "Tip: you can also set ZALO_BOT_TOKEN in your env.",
10
+ `Docs: ${formatDocsLink("/channels/zalo", "zalo")}`
11
+ ].join("\n"), "Zalo bot token");
12
+ }
13
+ async function promptZaloAllowFrom(params) {
14
+ const { cfg, prompter } = params;
15
+ const accountId = params.accountId ?? resolveDefaultZaloAccountId(cfg);
16
+ const existingAllowFrom = resolveZaloAccount({
17
+ cfg,
18
+ accountId
19
+ }).config.allowFrom ?? [];
20
+ const unique = mergeAllowFromEntries(existingAllowFrom, [(await prompter.text({
21
+ message: "Zalo allowFrom (user id)",
22
+ placeholder: "123456789",
23
+ initialValue: existingAllowFrom[0] ? String(existingAllowFrom[0]) : void 0,
24
+ validate: (value) => {
25
+ const raw = (value ?? "").trim();
26
+ if (!raw) return "Required";
27
+ if (!/^\d+$/.test(raw)) return "Use a numeric Zalo user id";
28
+ }
29
+ })).trim()]);
30
+ if (accountId === DEFAULT_ACCOUNT_ID) return {
31
+ ...cfg,
32
+ channels: {
33
+ ...cfg.channels,
34
+ zalo: {
35
+ ...cfg.channels?.zalo,
36
+ enabled: true,
37
+ dmPolicy: "allowlist",
38
+ allowFrom: unique
39
+ }
40
+ }
41
+ };
42
+ const currentAccount = cfg.channels?.zalo?.accounts?.[accountId];
43
+ return {
44
+ ...cfg,
45
+ channels: {
46
+ ...cfg.channels,
47
+ zalo: {
48
+ ...cfg.channels?.zalo,
49
+ enabled: true,
50
+ accounts: {
51
+ ...cfg.channels?.zalo?.accounts,
52
+ [accountId]: {
53
+ ...currentAccount,
54
+ enabled: currentAccount?.enabled ?? true,
55
+ dmPolicy: "allowlist",
56
+ allowFrom: unique
57
+ }
58
+ }
59
+ }
60
+ }
61
+ };
62
+ }
63
+ //#endregion
64
+ //#region extensions/zalo/src/setup-core.ts
65
+ const channel = "zalo";
66
+ const zaloSetupAdapter = createPatchedAccountSetupAdapter({
67
+ channelKey: channel,
68
+ validateInput: createSetupInputPresenceValidator({
69
+ defaultAccountOnlyEnvError: "ZALO_BOT_TOKEN can only be used for the default account.",
70
+ whenNotUseEnv: [{
71
+ someOf: ["token", "tokenFile"],
72
+ message: "Zalo requires token or --token-file (or --use-env)."
73
+ }]
74
+ }),
75
+ buildPatch: (input) => input.useEnv ? {} : input.tokenFile ? { tokenFile: input.tokenFile } : input.token ? { botToken: input.token } : {}
76
+ });
77
+ const zaloDmPolicy = {
78
+ label: "Zalo",
79
+ channel,
80
+ policyKey: "channels.zalo.dmPolicy",
81
+ allowFromKey: "channels.zalo.allowFrom",
82
+ resolveConfigKeys: (cfg, accountId) => (accountId ?? resolveDefaultZaloAccountId(cfg)) !== DEFAULT_ACCOUNT_ID ? {
83
+ policyKey: `channels.zalo.accounts.${accountId ?? resolveDefaultZaloAccountId(cfg)}.dmPolicy`,
84
+ allowFromKey: `channels.zalo.accounts.${accountId ?? resolveDefaultZaloAccountId(cfg)}.allowFrom`
85
+ } : {
86
+ policyKey: "channels.zalo.dmPolicy",
87
+ allowFromKey: "channels.zalo.allowFrom"
88
+ },
89
+ getCurrent: (cfg, accountId) => resolveZaloAccount({
90
+ cfg,
91
+ accountId: accountId ?? resolveDefaultZaloAccountId(cfg)
92
+ }).config.dmPolicy ?? "pairing",
93
+ setPolicy: (cfg, policy, accountId) => {
94
+ const resolvedAccountId = accountId && normalizeAccountId(accountId) ? normalizeAccountId(accountId) ?? DEFAULT_ACCOUNT_ID : resolveDefaultZaloAccountId(cfg);
95
+ const resolved = resolveZaloAccount({
96
+ cfg,
97
+ accountId: resolvedAccountId
98
+ });
99
+ if (resolvedAccountId === DEFAULT_ACCOUNT_ID) return {
100
+ ...cfg,
101
+ channels: {
102
+ ...cfg.channels,
103
+ zalo: {
104
+ ...cfg.channels?.zalo,
105
+ enabled: true,
106
+ dmPolicy: policy,
107
+ ...policy === "open" ? { allowFrom: addWildcardAllowFrom(resolved.config.allowFrom) } : {}
108
+ }
109
+ }
110
+ };
111
+ const currentAccount = cfg.channels?.zalo?.accounts?.[resolvedAccountId];
112
+ return {
113
+ ...cfg,
114
+ channels: {
115
+ ...cfg.channels,
116
+ zalo: {
117
+ ...cfg.channels?.zalo,
118
+ enabled: true,
119
+ accounts: {
120
+ ...cfg.channels?.zalo?.accounts,
121
+ [resolvedAccountId]: {
122
+ ...currentAccount,
123
+ enabled: currentAccount?.enabled ?? true,
124
+ dmPolicy: policy,
125
+ ...policy === "open" ? { allowFrom: addWildcardAllowFrom(resolved.config.allowFrom) } : {}
126
+ }
127
+ }
128
+ }
129
+ }
130
+ };
131
+ },
132
+ promptAllowFrom: async ({ cfg, prompter, accountId }) => promptZaloAllowFrom({
133
+ cfg,
134
+ prompter,
135
+ accountId: accountId ?? resolveDefaultZaloAccountId(cfg)
136
+ })
137
+ };
138
+ function createZaloSetupWizardProxy(loadWizard) {
139
+ return createDelegatedSetupWizardProxy({
140
+ channel,
141
+ loadWizard,
142
+ status: {
143
+ configuredLabel: "configured",
144
+ unconfiguredLabel: "needs token",
145
+ configuredHint: "recommended · configured",
146
+ unconfiguredHint: "recommended · newcomer-friendly",
147
+ configuredScore: 1,
148
+ unconfiguredScore: 10
149
+ },
150
+ credentials: [],
151
+ delegateFinalize: true,
152
+ dmPolicy: zaloDmPolicy,
153
+ disable: (cfg) => ({
154
+ ...cfg,
155
+ channels: {
156
+ ...cfg.channels,
157
+ zalo: {
158
+ ...cfg.channels?.zalo,
159
+ enabled: false
160
+ }
161
+ }
162
+ })
163
+ });
164
+ }
165
+ //#endregion
166
+ export { promptZaloAllowFrom as a, noteZaloTokenHelp as i, zaloDmPolicy as n, zaloSetupAdapter as r, createZaloSetupWizardProxy as t };
@@ -0,0 +1,15 @@
1
+ import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entry-contract";
2
+ //#region extensions/zalo/setup-entry.ts
3
+ var setup_entry_default = defineBundledChannelSetupEntry({
4
+ importMetaUrl: import.meta.url,
5
+ plugin: {
6
+ specifier: "./api.js",
7
+ exportName: "zaloPlugin"
8
+ },
9
+ secrets: {
10
+ specifier: "./secret-contract-api.js",
11
+ exportName: "channelSecrets"
12
+ }
13
+ });
14
+ //#endregion
15
+ export { setup_entry_default as default };
@@ -0,0 +1,216 @@
1
+ import { a as resolveZaloAccount } from "./accounts-9NLDDlZ8.js";
2
+ import { a as promptZaloAllowFrom, i as noteZaloTokenHelp, n as zaloDmPolicy } from "./setup-core-DigRD3j1.js";
3
+ import { DEFAULT_ACCOUNT_ID, buildSingleChannelSecretPromptState, createStandardChannelSetupStatus, hasConfiguredSecretInput, promptSingleChannelSecretInput, runSingleChannelSecretStep } from "openclaw/plugin-sdk/setup";
4
+ //#region extensions/zalo/src/setup-surface.ts
5
+ const channel = "zalo";
6
+ function setZaloUpdateMode(cfg, accountId, mode, webhookUrl, webhookSecret, webhookPath) {
7
+ const isDefault = accountId === DEFAULT_ACCOUNT_ID;
8
+ if (mode === "polling") {
9
+ if (isDefault) {
10
+ const { webhookUrl: _url, webhookSecret: _secret, webhookPath: _path, ...rest } = cfg.channels?.zalo ?? {};
11
+ return {
12
+ ...cfg,
13
+ channels: {
14
+ ...cfg.channels,
15
+ zalo: rest
16
+ }
17
+ };
18
+ }
19
+ const accounts = { ...cfg.channels?.zalo?.accounts };
20
+ const { webhookUrl: _url, webhookSecret: _secret, webhookPath: _path, ...rest } = accounts[accountId] ?? {};
21
+ accounts[accountId] = rest;
22
+ return {
23
+ ...cfg,
24
+ channels: {
25
+ ...cfg.channels,
26
+ zalo: {
27
+ ...cfg.channels?.zalo,
28
+ accounts
29
+ }
30
+ }
31
+ };
32
+ }
33
+ if (isDefault) return {
34
+ ...cfg,
35
+ channels: {
36
+ ...cfg.channels,
37
+ zalo: {
38
+ ...cfg.channels?.zalo,
39
+ webhookUrl,
40
+ webhookSecret,
41
+ webhookPath
42
+ }
43
+ }
44
+ };
45
+ const accounts = { ...cfg.channels?.zalo?.accounts };
46
+ accounts[accountId] = {
47
+ ...accounts[accountId],
48
+ webhookUrl,
49
+ webhookSecret,
50
+ webhookPath
51
+ };
52
+ return {
53
+ ...cfg,
54
+ channels: {
55
+ ...cfg.channels,
56
+ zalo: {
57
+ ...cfg.channels?.zalo,
58
+ accounts
59
+ }
60
+ }
61
+ };
62
+ }
63
+ const zaloSetupWizard = {
64
+ channel,
65
+ status: createStandardChannelSetupStatus({
66
+ channelLabel: "Zalo",
67
+ configuredLabel: "configured",
68
+ unconfiguredLabel: "needs token",
69
+ configuredHint: "recommended · configured",
70
+ unconfiguredHint: "recommended · newcomer-friendly",
71
+ configuredScore: 1,
72
+ unconfiguredScore: 10,
73
+ includeStatusLine: true,
74
+ resolveConfigured: ({ cfg, accountId }) => {
75
+ const account = resolveZaloAccount({
76
+ cfg,
77
+ accountId,
78
+ allowUnresolvedSecretRef: true
79
+ });
80
+ return Boolean(account.token) || hasConfiguredSecretInput(account.config.botToken) || Boolean(account.config.tokenFile?.trim());
81
+ }
82
+ }),
83
+ credentials: [],
84
+ finalize: async ({ cfg, accountId, forceAllowFrom, options, prompter }) => {
85
+ let next = cfg;
86
+ const resolvedAccount = resolveZaloAccount({
87
+ cfg: next,
88
+ accountId,
89
+ allowUnresolvedSecretRef: true
90
+ });
91
+ const accountConfigured = Boolean(resolvedAccount.token);
92
+ const allowEnv = accountId === DEFAULT_ACCOUNT_ID;
93
+ const hasConfigToken = Boolean(hasConfiguredSecretInput(resolvedAccount.config.botToken) || resolvedAccount.config.tokenFile);
94
+ next = (await runSingleChannelSecretStep({
95
+ cfg: next,
96
+ prompter,
97
+ providerHint: "zalo",
98
+ credentialLabel: "bot token",
99
+ secretInputMode: options?.secretInputMode,
100
+ accountConfigured,
101
+ hasConfigToken,
102
+ allowEnv,
103
+ envValue: process.env.ZALO_BOT_TOKEN,
104
+ envPrompt: "ZALO_BOT_TOKEN detected. Use env var?",
105
+ keepPrompt: "Zalo token already configured. Keep it?",
106
+ inputPrompt: "Enter Zalo bot token",
107
+ preferredEnvVar: "ZALO_BOT_TOKEN",
108
+ onMissingConfigured: async () => await noteZaloTokenHelp(prompter),
109
+ applyUseEnv: async (currentCfg) => accountId === DEFAULT_ACCOUNT_ID ? {
110
+ ...currentCfg,
111
+ channels: {
112
+ ...currentCfg.channels,
113
+ zalo: {
114
+ ...currentCfg.channels?.zalo,
115
+ enabled: true
116
+ }
117
+ }
118
+ } : currentCfg,
119
+ applySet: async (currentCfg, value) => accountId === DEFAULT_ACCOUNT_ID ? {
120
+ ...currentCfg,
121
+ channels: {
122
+ ...currentCfg.channels,
123
+ zalo: {
124
+ ...currentCfg.channels?.zalo,
125
+ enabled: true,
126
+ botToken: value
127
+ }
128
+ }
129
+ } : {
130
+ ...currentCfg,
131
+ channels: {
132
+ ...currentCfg.channels,
133
+ zalo: {
134
+ ...currentCfg.channels?.zalo,
135
+ enabled: true,
136
+ accounts: {
137
+ ...currentCfg.channels?.zalo?.accounts,
138
+ [accountId]: {
139
+ ...currentCfg.channels?.zalo?.accounts?.[accountId],
140
+ enabled: true,
141
+ botToken: value
142
+ }
143
+ }
144
+ }
145
+ }
146
+ }
147
+ })).cfg;
148
+ if (await prompter.confirm({
149
+ message: "Use webhook mode for Zalo?",
150
+ initialValue: Boolean(resolvedAccount.config.webhookUrl)
151
+ })) {
152
+ const webhookUrl = (await prompter.text({
153
+ message: "Webhook URL (https://...) ",
154
+ initialValue: resolvedAccount.config.webhookUrl,
155
+ validate: (value) => value?.trim()?.startsWith("https://") ? void 0 : "HTTPS URL required"
156
+ })).trim();
157
+ const defaultPath = (() => {
158
+ try {
159
+ return new URL(webhookUrl).pathname || "/zalo-webhook";
160
+ } catch {
161
+ return "/zalo-webhook";
162
+ }
163
+ })();
164
+ let webhookSecretResult = await promptSingleChannelSecretInput({
165
+ cfg: next,
166
+ prompter,
167
+ providerHint: "zalo-webhook",
168
+ credentialLabel: "webhook secret",
169
+ secretInputMode: options?.secretInputMode,
170
+ ...buildSingleChannelSecretPromptState({
171
+ accountConfigured: hasConfiguredSecretInput(resolvedAccount.config.webhookSecret),
172
+ hasConfigToken: hasConfiguredSecretInput(resolvedAccount.config.webhookSecret),
173
+ allowEnv: false
174
+ }),
175
+ envPrompt: "",
176
+ keepPrompt: "Zalo webhook secret already configured. Keep it?",
177
+ inputPrompt: "Webhook secret (8-256 chars)",
178
+ preferredEnvVar: "ZALO_WEBHOOK_SECRET"
179
+ });
180
+ while (webhookSecretResult.action === "set" && typeof webhookSecretResult.value === "string" && (webhookSecretResult.value.length < 8 || webhookSecretResult.value.length > 256)) {
181
+ await prompter.note("Webhook secret must be between 8 and 256 characters.", "Zalo webhook");
182
+ webhookSecretResult = await promptSingleChannelSecretInput({
183
+ cfg: next,
184
+ prompter,
185
+ providerHint: "zalo-webhook",
186
+ credentialLabel: "webhook secret",
187
+ secretInputMode: options?.secretInputMode,
188
+ ...buildSingleChannelSecretPromptState({
189
+ accountConfigured: false,
190
+ hasConfigToken: false,
191
+ allowEnv: false
192
+ }),
193
+ envPrompt: "",
194
+ keepPrompt: "Zalo webhook secret already configured. Keep it?",
195
+ inputPrompt: "Webhook secret (8-256 chars)",
196
+ preferredEnvVar: "ZALO_WEBHOOK_SECRET"
197
+ });
198
+ }
199
+ const webhookSecret = webhookSecretResult.action === "set" ? webhookSecretResult.value : resolvedAccount.config.webhookSecret;
200
+ const webhookPath = (await prompter.text({
201
+ message: "Webhook path (optional)",
202
+ initialValue: resolvedAccount.config.webhookPath ?? defaultPath
203
+ })).trim();
204
+ next = setZaloUpdateMode(next, accountId, "webhook", webhookUrl, webhookSecret, webhookPath || void 0);
205
+ } else next = setZaloUpdateMode(next, accountId, "polling");
206
+ if (forceAllowFrom) next = await promptZaloAllowFrom({
207
+ cfg: next,
208
+ prompter,
209
+ accountId
210
+ });
211
+ return { cfg: next };
212
+ },
213
+ dmPolicy: zaloDmPolicy
214
+ };
215
+ //#endregion
216
+ export { zaloSetupWizard };
@@ -0,0 +1,2 @@
1
+ import { r as resolveZaloRuntimeGroupPolicy, t as evaluateZaloGroupAccess } from "./group-access-DZR43lOR.js";
2
+ export { evaluateZaloGroupAccess, resolveZaloRuntimeGroupPolicy };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/zalo",
3
- "version": "2026.5.2",
3
+ "version": "2026.5.3-beta.2",
4
4
  "description": "OpenClaw Zalo channel plugin",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,7 +15,7 @@
15
15
  "openclaw": "workspace:*"
16
16
  },
17
17
  "peerDependencies": {
18
- "openclaw": ">=2026.5.2"
18
+ "openclaw": ">=2026.5.3-beta.2"
19
19
  },
20
20
  "peerDependenciesMeta": {
21
21
  "openclaw": {
@@ -46,14 +46,23 @@
46
46
  "minHostVersion": ">=2026.4.10"
47
47
  },
48
48
  "compat": {
49
- "pluginApi": ">=2026.5.2"
49
+ "pluginApi": ">=2026.5.3-beta.2"
50
50
  },
51
51
  "build": {
52
- "openclawVersion": "2026.5.2"
52
+ "openclawVersion": "2026.5.3-beta.2"
53
53
  },
54
54
  "release": {
55
55
  "publishToClawHub": true,
56
56
  "publishToNpm": true
57
- }
58
- }
57
+ },
58
+ "runtimeExtensions": [
59
+ "./dist/index.js"
60
+ ],
61
+ "runtimeSetupEntry": "./dist/setup-entry.js"
62
+ },
63
+ "files": [
64
+ "dist/**",
65
+ "openclaw.plugin.json",
66
+ "README.md"
67
+ ]
59
68
  }
package/api.ts DELETED
@@ -1,9 +0,0 @@
1
- export { zaloPlugin } from "./src/channel.js";
2
- export {
3
- createZaloSetupWizardProxy,
4
- evaluateZaloGroupAccess,
5
- resolveZaloRuntimeGroupPolicy,
6
- zaloDmPolicy,
7
- zaloSetupAdapter,
8
- zaloSetupWizard,
9
- } from "./setup-api.js";
@@ -1 +0,0 @@
1
- export { zaloPlugin } from "./src/channel.js";
package/contract-api.ts DELETED
@@ -1,5 +0,0 @@
1
- export { evaluateZaloGroupAccess, resolveZaloRuntimeGroupPolicy } from "./src/group-access.js";
2
- export {
3
- collectRuntimeConfigAssignments,
4
- secretTargetRegistryEntries,
5
- } from "./src/secret-contract.js";
package/index.test.ts DELETED
@@ -1,15 +0,0 @@
1
- import { assertBundledChannelEntries } from "openclaw/plugin-sdk/channel-test-helpers";
2
- import { describe } from "vitest";
3
- import entry from "./index.js";
4
- import setupEntry from "./setup-entry.js";
5
-
6
- describe("zalo bundled entries", () => {
7
- assertBundledChannelEntries({
8
- entry,
9
- expectedId: "zalo",
10
- expectedName: "Zalo",
11
- setupEntry,
12
- channelMessage: "declares the channel plugin without a runtime-barrel cycle",
13
- setupMessage: "declares the setup plugin without a runtime-barrel cycle",
14
- });
15
- });
package/index.ts DELETED
@@ -1,20 +0,0 @@
1
- import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
2
-
3
- export default defineBundledChannelEntry({
4
- id: "zalo",
5
- name: "Zalo",
6
- description: "Zalo channel plugin",
7
- importMetaUrl: import.meta.url,
8
- plugin: {
9
- specifier: "./channel-plugin-api.js",
10
- exportName: "zaloPlugin",
11
- },
12
- secrets: {
13
- specifier: "./secret-contract-api.js",
14
- exportName: "channelSecrets",
15
- },
16
- runtime: {
17
- specifier: "./runtime-api.js",
18
- exportName: "setZaloRuntime",
19
- },
20
- });
@@ -1,17 +0,0 @@
1
- import { runDirectImportSmoke } from "openclaw/plugin-sdk/plugin-test-contracts";
2
- import { describe, expect, it } from "vitest";
3
-
4
- describe("zalo runtime api", () => {
5
- it("loads the narrow runtime api without reentering setup surfaces", async () => {
6
- const stdout = await runDirectImportSmoke(
7
- `const runtime = await import("./extensions/zalo/runtime-api.ts");
8
- process.stdout.write(JSON.stringify({
9
- hasZaloPlugin: Object.hasOwn(runtime, "zaloPlugin"),
10
- hasZaloSetupWizard: Object.hasOwn(runtime, "zaloSetupWizard"),
11
- type: typeof runtime.setZaloRuntime,
12
- }));`,
13
- );
14
-
15
- expect(stdout).toBe('{"hasZaloPlugin":false,"hasZaloSetupWizard":false,"type":"function"}');
16
- }, 45_000);
17
- });
package/runtime-api.ts DELETED
@@ -1,75 +0,0 @@
1
- export {
2
- addWildcardAllowFrom,
3
- applyAccountNameToChannelSection,
4
- applyBasicWebhookRequestGuards,
5
- applySetupAccountConfigPatch,
6
- type BaseProbeResult,
7
- type BaseTokenResolution,
8
- buildBaseAccountStatusSnapshot,
9
- buildChannelConfigSchema,
10
- buildSecretInputSchema,
11
- buildSingleChannelSecretPromptState,
12
- buildTokenChannelStatusSummary,
13
- type ChannelAccountSnapshot,
14
- type ChannelMessageActionAdapter,
15
- type ChannelMessageActionName,
16
- type ChannelPlugin,
17
- type ChannelStatusIssue,
18
- chunkTextForOutbound,
19
- createChannelPairingController,
20
- createChannelReplyPipeline,
21
- createDedupeCache,
22
- createFixedWindowRateLimiter,
23
- createWebhookAnomalyTracker,
24
- DEFAULT_ACCOUNT_ID,
25
- deliverTextOrMediaReply,
26
- evaluateSenderGroupAccess,
27
- formatAllowFromLowercase,
28
- formatPairingApproveHint,
29
- type GroupPolicy,
30
- hasConfiguredSecretInput,
31
- isNormalizedSenderAllowed,
32
- isNumericTargetId,
33
- jsonResult,
34
- logTypingFailure,
35
- type MarkdownTableMode,
36
- mergeAllowFromEntries,
37
- migrateBaseNameToDefaultAccount,
38
- normalizeAccountId,
39
- normalizeResolvedSecretInputString,
40
- normalizeSecretInputString,
41
- type OpenClawConfig,
42
- type OutboundReplyPayload,
43
- PAIRING_APPROVED_MESSAGE,
44
- type PluginRuntime,
45
- promptSingleChannelSecretInput,
46
- readJsonWebhookBodyOrReject,
47
- readStringParam,
48
- registerPluginHttpRoute,
49
- type RegisterWebhookPluginRouteOptions,
50
- registerWebhookTarget,
51
- type RegisterWebhookTargetOptions,
52
- registerWebhookTargetWithPluginRoute,
53
- type ReplyPayload,
54
- resolveClientIp,
55
- resolveDefaultGroupPolicy,
56
- resolveDirectDmAuthorizationOutcome,
57
- resolveInboundRouteEnvelopeBuilderWithRuntime,
58
- resolveOpenProviderRuntimeGroupPolicy,
59
- resolveSenderCommandAuthorizationWithRuntime,
60
- resolveWebhookPath,
61
- resolveWebhookTargetWithAuthOrRejectSync,
62
- runSingleChannelSecretStep,
63
- type RuntimeEnv,
64
- type SecretInput,
65
- type SenderGroupAccessDecision,
66
- sendPayloadWithChunkedTextAndMedia,
67
- setTopLevelChannelDmPolicyWithAllowFrom,
68
- setZaloRuntime,
69
- waitForAbortSignal,
70
- warnMissingProviderGroupPolicyFallbackOnce,
71
- WEBHOOK_ANOMALY_COUNTER_DEFAULTS,
72
- WEBHOOK_RATE_LIMIT_DEFAULTS,
73
- withResolvedWebhookRequestPipeline,
74
- type WizardPrompter,
75
- } from "./src/runtime-api.js";
@@ -1,5 +0,0 @@
1
- export {
2
- channelSecrets,
3
- collectRuntimeConfigAssignments,
4
- secretTargetRegistryEntries,
5
- } from "./src/secret-contract.js";
package/setup-api.ts DELETED
@@ -1,34 +0,0 @@
1
- import { loadBundledEntryExportSync } from "openclaw/plugin-sdk/channel-entry-contract";
2
-
3
- type SetupSurfaceModule = typeof import("./src/setup-surface.js");
4
-
5
- function createLazyObjectValue<T extends object>(load: () => T): T {
6
- return new Proxy({} as T, {
7
- get(_target, property, receiver) {
8
- return Reflect.get(load(), property, receiver);
9
- },
10
- has(_target, property) {
11
- return property in load();
12
- },
13
- ownKeys() {
14
- return Reflect.ownKeys(load());
15
- },
16
- getOwnPropertyDescriptor(_target, property) {
17
- const descriptor = Object.getOwnPropertyDescriptor(load(), property);
18
- return descriptor ? { ...descriptor, configurable: true } : undefined;
19
- },
20
- });
21
- }
22
-
23
- function loadSetupSurfaceModule(): SetupSurfaceModule {
24
- return loadBundledEntryExportSync<SetupSurfaceModule>(import.meta.url, {
25
- specifier: "./src/setup-surface.js",
26
- });
27
- }
28
-
29
- export { zaloDmPolicy, zaloSetupAdapter, createZaloSetupWizardProxy } from "./src/setup-core.js";
30
- export { evaluateZaloGroupAccess, resolveZaloRuntimeGroupPolicy } from "./src/group-access.js";
31
-
32
- export const zaloSetupWizard: SetupSurfaceModule["zaloSetupWizard"] = createLazyObjectValue(
33
- () => loadSetupSurfaceModule().zaloSetupWizard as object,
34
- ) as SetupSurfaceModule["zaloSetupWizard"];
package/setup-entry.ts DELETED
@@ -1,13 +0,0 @@
1
- import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entry-contract";
2
-
3
- export default defineBundledChannelSetupEntry({
4
- importMetaUrl: import.meta.url,
5
- plugin: {
6
- specifier: "./api.js",
7
- exportName: "zaloPlugin",
8
- },
9
- secrets: {
10
- specifier: "./secret-contract-api.js",
11
- exportName: "channelSecrets",
12
- },
13
- });