@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.
- package/dist/accounts-9NLDDlZ8.js +118 -0
- package/dist/actions.runtime-kJ65ZxW7.js +5 -0
- package/dist/api.js +5 -0
- package/dist/channel-VPbtV3Oq.js +343 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel.runtime-BnTAWQx5.js +106 -0
- package/dist/contract-api.js +3 -0
- package/dist/group-access-DZR43lOR.js +30 -0
- package/dist/index.js +22 -0
- package/dist/monitor-DMysJBWa.js +823 -0
- package/dist/monitor.webhook-DqnuvgjV.js +175 -0
- package/dist/proxy-CY8VuC6H.js +135 -0
- package/dist/runtime-BRFxnYQx.js +8 -0
- package/dist/runtime-api-MOTmRW4F.js +19 -0
- package/dist/runtime-api.js +3 -0
- package/dist/secret-contract-Dw93tGo2.js +87 -0
- package/dist/secret-contract-api.js +2 -0
- package/dist/send-Gv3l5EGI.js +101 -0
- package/dist/setup-api.js +30 -0
- package/dist/setup-core-DigRD3j1.js +166 -0
- package/dist/setup-entry.js +15 -0
- package/dist/setup-surface-2Up3yWov.js +216 -0
- package/dist/test-api.js +2 -0
- package/package.json +15 -6
- package/api.ts +0 -9
- package/channel-plugin-api.ts +0 -1
- package/contract-api.ts +0 -5
- package/index.test.ts +0 -15
- package/index.ts +0 -20
- package/runtime-api.test.ts +0 -17
- package/runtime-api.ts +0 -75
- package/secret-contract-api.ts +0 -5
- package/setup-api.ts +0 -34
- package/setup-entry.ts +0 -13
- package/src/accounts.test.ts +0 -70
- package/src/accounts.ts +0 -60
- package/src/actions.runtime.ts +0 -5
- package/src/actions.test.ts +0 -32
- package/src/actions.ts +0 -62
- package/src/api.test.ts +0 -149
- package/src/api.ts +0 -265
- package/src/approval-auth.test.ts +0 -17
- package/src/approval-auth.ts +0 -25
- package/src/channel.directory.test.ts +0 -59
- package/src/channel.runtime.ts +0 -93
- package/src/channel.startup.test.ts +0 -101
- package/src/channel.ts +0 -275
- package/src/config-schema.test.ts +0 -30
- package/src/config-schema.ts +0 -29
- package/src/group-access.ts +0 -49
- package/src/monitor.group-policy.test.ts +0 -94
- package/src/monitor.image.polling.test.ts +0 -110
- package/src/monitor.lifecycle.test.ts +0 -198
- package/src/monitor.pairing.lifecycle.test.ts +0 -141
- package/src/monitor.polling.media-reply.test.ts +0 -425
- package/src/monitor.reply-once.lifecycle.test.ts +0 -171
- package/src/monitor.ts +0 -1028
- package/src/monitor.types.ts +0 -4
- package/src/monitor.webhook.test.ts +0 -806
- package/src/monitor.webhook.ts +0 -278
- package/src/outbound-media.test.ts +0 -182
- package/src/outbound-media.ts +0 -241
- package/src/outbound-payload.contract.test.ts +0 -45
- package/src/probe.ts +0 -45
- package/src/proxy.ts +0 -24
- package/src/runtime-api.ts +0 -75
- package/src/runtime-support.ts +0 -91
- package/src/runtime.ts +0 -9
- package/src/secret-contract.ts +0 -109
- package/src/secret-input.ts +0 -5
- package/src/send.test.ts +0 -120
- package/src/send.ts +0 -153
- package/src/session-route.ts +0 -32
- package/src/setup-allow-from.ts +0 -94
- package/src/setup-core.ts +0 -149
- package/src/setup-status.test.ts +0 -33
- package/src/setup-surface.test.ts +0 -175
- package/src/setup-surface.ts +0 -291
- package/src/status-issues.test.ts +0 -17
- package/src/status-issues.ts +0 -37
- package/src/test-support/lifecycle-test-support.ts +0 -413
- package/src/test-support/monitor-mocks-test-support.ts +0 -209
- package/src/token.test.ts +0 -92
- package/src/token.ts +0 -79
- package/src/types.ts +0 -50
- package/test-api.ts +0 -1
- package/tsconfig.json +0 -16
package/src/token.test.ts
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import os from "node:os";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { describe, expect, it } from "vitest";
|
|
5
|
-
import { resolveZaloToken } from "./token.js";
|
|
6
|
-
import type { ZaloConfig } from "./types.js";
|
|
7
|
-
|
|
8
|
-
describe("resolveZaloToken", () => {
|
|
9
|
-
it("falls back to top-level token for non-default accounts without overrides", () => {
|
|
10
|
-
const cfg = {
|
|
11
|
-
botToken: "top-level-token",
|
|
12
|
-
accounts: {
|
|
13
|
-
work: {},
|
|
14
|
-
},
|
|
15
|
-
} as ZaloConfig;
|
|
16
|
-
const res = resolveZaloToken(cfg, "work");
|
|
17
|
-
expect(res.token).toBe("top-level-token");
|
|
18
|
-
expect(res.source).toBe("config");
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it("uses accounts.default botToken for default account when configured", () => {
|
|
22
|
-
const cfg = {
|
|
23
|
-
botToken: "top-level-token",
|
|
24
|
-
accounts: {
|
|
25
|
-
default: {
|
|
26
|
-
botToken: "default-account-token",
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
} as ZaloConfig;
|
|
30
|
-
const res = resolveZaloToken(cfg, "default");
|
|
31
|
-
expect(res.token).toBe("default-account-token");
|
|
32
|
-
expect(res.source).toBe("config");
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("uses configured defaultAccount token when accountId is omitted", () => {
|
|
36
|
-
const cfg = {
|
|
37
|
-
defaultAccount: "work",
|
|
38
|
-
botToken: "top-level-token",
|
|
39
|
-
accounts: {
|
|
40
|
-
work: {
|
|
41
|
-
botToken: "work-token",
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
} as ZaloConfig;
|
|
45
|
-
const res = resolveZaloToken(cfg);
|
|
46
|
-
expect(res.token).toBe("work-token");
|
|
47
|
-
expect(res.source).toBe("config");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("does not inherit top-level token when account token is explicitly blank", () => {
|
|
51
|
-
const cfg = {
|
|
52
|
-
botToken: "top-level-token",
|
|
53
|
-
accounts: {
|
|
54
|
-
work: {
|
|
55
|
-
botToken: "",
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
} as ZaloConfig;
|
|
59
|
-
const res = resolveZaloToken(cfg, "work");
|
|
60
|
-
expect(res.token).toBe("");
|
|
61
|
-
expect(res.source).toBe("none");
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("resolves account token when account key casing differs from normalized id", () => {
|
|
65
|
-
const cfg = {
|
|
66
|
-
accounts: {
|
|
67
|
-
Work: {
|
|
68
|
-
botToken: "work-token",
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
} as ZaloConfig;
|
|
72
|
-
const res = resolveZaloToken(cfg, "work");
|
|
73
|
-
expect(res.token).toBe("work-token");
|
|
74
|
-
expect(res.source).toBe("config");
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it.runIf(process.platform !== "win32")("rejects symlinked token files", () => {
|
|
78
|
-
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-zalo-token-"));
|
|
79
|
-
const tokenFile = path.join(dir, "token.txt");
|
|
80
|
-
const tokenLink = path.join(dir, "token-link.txt");
|
|
81
|
-
fs.writeFileSync(tokenFile, "file-token\n", "utf8");
|
|
82
|
-
fs.symlinkSync(tokenFile, tokenLink);
|
|
83
|
-
|
|
84
|
-
const cfg = {
|
|
85
|
-
tokenFile: tokenLink,
|
|
86
|
-
} as ZaloConfig;
|
|
87
|
-
const res = resolveZaloToken(cfg);
|
|
88
|
-
expect(res.token).toBe("");
|
|
89
|
-
expect(res.source).toBe("none");
|
|
90
|
-
fs.rmSync(dir, { recursive: true, force: true });
|
|
91
|
-
});
|
|
92
|
-
});
|
package/src/token.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
2
|
-
import type { BaseTokenResolution } from "openclaw/plugin-sdk/channel-contract";
|
|
3
|
-
import { tryReadSecretFileSync } from "openclaw/plugin-sdk/core";
|
|
4
|
-
import { resolveAccountEntry } from "openclaw/plugin-sdk/routing";
|
|
5
|
-
import { normalizeResolvedSecretInputString, normalizeSecretInputString } from "./secret-input.js";
|
|
6
|
-
import type { ZaloConfig } from "./types.js";
|
|
7
|
-
|
|
8
|
-
type ZaloTokenResolution = BaseTokenResolution & {
|
|
9
|
-
source: "env" | "config" | "configFile" | "none";
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
function readTokenFromFile(tokenFile: string | undefined): string {
|
|
13
|
-
return tryReadSecretFileSync(tokenFile, "Zalo token file", { rejectSymlink: true }) ?? "";
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function resolveZaloToken(
|
|
17
|
-
config: ZaloConfig | undefined,
|
|
18
|
-
accountId?: string | null,
|
|
19
|
-
options?: { allowUnresolvedSecretRef?: boolean },
|
|
20
|
-
): ZaloTokenResolution {
|
|
21
|
-
const resolvedAccountId = normalizeAccountId(accountId ?? config?.defaultAccount);
|
|
22
|
-
const isDefaultAccount = resolvedAccountId === DEFAULT_ACCOUNT_ID;
|
|
23
|
-
const baseConfig = config;
|
|
24
|
-
const accountConfig = resolveAccountEntry(
|
|
25
|
-
baseConfig?.accounts as Record<string, ZaloConfig> | undefined,
|
|
26
|
-
normalizeAccountId(resolvedAccountId),
|
|
27
|
-
);
|
|
28
|
-
const accountHasBotToken = Boolean(
|
|
29
|
-
accountConfig && Object.prototype.hasOwnProperty.call(accountConfig, "botToken"),
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
if (accountConfig && accountHasBotToken) {
|
|
33
|
-
const token = options?.allowUnresolvedSecretRef
|
|
34
|
-
? normalizeSecretInputString(accountConfig.botToken)
|
|
35
|
-
: normalizeResolvedSecretInputString({
|
|
36
|
-
value: accountConfig.botToken,
|
|
37
|
-
path: `channels.zalo.accounts.${resolvedAccountId}.botToken`,
|
|
38
|
-
});
|
|
39
|
-
if (token) {
|
|
40
|
-
return { token, source: "config" };
|
|
41
|
-
}
|
|
42
|
-
const fileToken = readTokenFromFile(accountConfig.tokenFile);
|
|
43
|
-
if (fileToken) {
|
|
44
|
-
return { token: fileToken, source: "configFile" };
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (!accountHasBotToken) {
|
|
49
|
-
const fileToken = readTokenFromFile(accountConfig?.tokenFile);
|
|
50
|
-
if (fileToken) {
|
|
51
|
-
return { token: fileToken, source: "configFile" };
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (!accountHasBotToken) {
|
|
56
|
-
const token = options?.allowUnresolvedSecretRef
|
|
57
|
-
? normalizeSecretInputString(baseConfig?.botToken)
|
|
58
|
-
: normalizeResolvedSecretInputString({
|
|
59
|
-
value: baseConfig?.botToken,
|
|
60
|
-
path: "channels.zalo.botToken",
|
|
61
|
-
});
|
|
62
|
-
if (token) {
|
|
63
|
-
return { token, source: "config" };
|
|
64
|
-
}
|
|
65
|
-
const fileToken = readTokenFromFile(baseConfig?.tokenFile);
|
|
66
|
-
if (fileToken) {
|
|
67
|
-
return { token: fileToken, source: "configFile" };
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (isDefaultAccount) {
|
|
72
|
-
const envToken = process.env.ZALO_BOT_TOKEN?.trim();
|
|
73
|
-
if (envToken) {
|
|
74
|
-
return { token: envToken, source: "env" };
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return { token: "", source: "none" };
|
|
79
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { SecretInput } from "openclaw/plugin-sdk/secret-input";
|
|
2
|
-
|
|
3
|
-
export type ZaloAccountConfig = {
|
|
4
|
-
/** Optional display name for this account (used in CLI/UI lists). */
|
|
5
|
-
name?: string;
|
|
6
|
-
/** If false, do not start this Zalo account. Default: true. */
|
|
7
|
-
enabled?: boolean;
|
|
8
|
-
/** Bot token from Zalo Bot Creator. */
|
|
9
|
-
botToken?: SecretInput;
|
|
10
|
-
/** Path to file containing the bot token. */
|
|
11
|
-
tokenFile?: string;
|
|
12
|
-
/** Webhook URL for receiving updates (HTTPS required). */
|
|
13
|
-
webhookUrl?: string;
|
|
14
|
-
/** Webhook secret token (8-256 chars) for request verification. */
|
|
15
|
-
webhookSecret?: SecretInput;
|
|
16
|
-
/** Webhook path for the gateway HTTP server (defaults to webhook URL path). */
|
|
17
|
-
webhookPath?: string;
|
|
18
|
-
/** Direct message access policy (default: pairing). */
|
|
19
|
-
dmPolicy?: "pairing" | "allowlist" | "open" | "disabled";
|
|
20
|
-
/** Allowlist for DM senders (Zalo user IDs). */
|
|
21
|
-
allowFrom?: Array<string | number>;
|
|
22
|
-
/** Group-message access policy. */
|
|
23
|
-
groupPolicy?: "open" | "allowlist" | "disabled";
|
|
24
|
-
/** Allowlist for group senders (falls back to allowFrom when unset). */
|
|
25
|
-
groupAllowFrom?: Array<string | number>;
|
|
26
|
-
/** Max inbound media size in MB. */
|
|
27
|
-
mediaMaxMb?: number;
|
|
28
|
-
/** Proxy URL for API requests. */
|
|
29
|
-
proxy?: string;
|
|
30
|
-
/** Outbound response prefix override for this channel/account. */
|
|
31
|
-
responsePrefix?: string;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export type ZaloConfig = {
|
|
35
|
-
/** Optional per-account Zalo configuration (multi-account). */
|
|
36
|
-
accounts?: Record<string, ZaloAccountConfig>;
|
|
37
|
-
/** Default account ID when multiple accounts are configured. */
|
|
38
|
-
defaultAccount?: string;
|
|
39
|
-
} & ZaloAccountConfig;
|
|
40
|
-
|
|
41
|
-
type ZaloTokenSource = "env" | "config" | "configFile" | "none";
|
|
42
|
-
|
|
43
|
-
export type ResolvedZaloAccount = {
|
|
44
|
-
accountId: string;
|
|
45
|
-
name?: string;
|
|
46
|
-
enabled: boolean;
|
|
47
|
-
token: string;
|
|
48
|
-
tokenSource: ZaloTokenSource;
|
|
49
|
-
config: ZaloAccountConfig;
|
|
50
|
-
};
|
package/test-api.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { evaluateZaloGroupAccess, resolveZaloRuntimeGroupPolicy } from "./src/group-access.js";
|
package/tsconfig.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../tsconfig.package-boundary.base.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"rootDir": "."
|
|
5
|
-
},
|
|
6
|
-
"include": ["./*.ts", "./src/**/*.ts"],
|
|
7
|
-
"exclude": [
|
|
8
|
-
"./**/*.test.ts",
|
|
9
|
-
"./dist/**",
|
|
10
|
-
"./node_modules/**",
|
|
11
|
-
"./src/test-support/**",
|
|
12
|
-
"./src/**/*test-helpers.ts",
|
|
13
|
-
"./src/**/*test-harness.ts",
|
|
14
|
-
"./src/**/*test-support.ts"
|
|
15
|
-
]
|
|
16
|
-
}
|