@kodelyth/zalo 2026.5.42 → 2026.6.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/klaw.plugin.json +509 -2
- package/package.json +19 -6
- package/api.ts +0 -8
- 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 -10
- package/runtime-api.ts +0 -71
- 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 -95
- package/src/accounts.ts +0 -65
- 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 -166
- 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 -56
- package/src/channel.runtime.ts +0 -89
- package/src/channel.startup.test.ts +0 -121
- package/src/channel.ts +0 -309
- package/src/config-schema.test.ts +0 -30
- package/src/config-schema.ts +0 -29
- package/src/group-access.ts +0 -23
- package/src/monitor-durable.test.ts +0 -49
- package/src/monitor-durable.ts +0 -38
- package/src/monitor.group-policy.test.ts +0 -213
- package/src/monitor.image.polling.test.ts +0 -113
- package/src/monitor.lifecycle.test.ts +0 -194
- package/src/monitor.pairing.lifecycle.test.ts +0 -139
- package/src/monitor.polling.media-reply.test.ts +0 -433
- package/src/monitor.reply-once.lifecycle.test.ts +0 -178
- package/src/monitor.ts +0 -1009
- package/src/monitor.types.ts +0 -4
- package/src/monitor.webhook.test.ts +0 -808
- package/src/monitor.webhook.ts +0 -278
- package/src/outbound-media.test.ts +0 -186
- package/src/outbound-media.ts +0 -236
- package/src/outbound-payload.contract.test.ts +0 -143
- package/src/probe.ts +0 -45
- package/src/proxy.ts +0 -18
- package/src/runtime-api.ts +0 -71
- package/src/runtime-support.ts +0 -82
- 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 -150
- package/src/send.ts +0 -207
- package/src/session-route.ts +0 -32
- package/src/setup-allow-from.ts +0 -97
- package/src/setup-core.ts +0 -152
- package/src/setup-status.test.ts +0 -33
- package/src/setup-surface.test.ts +0 -193
- package/src/setup-surface.ts +0 -294
- package/src/status-issues.test.ts +0 -17
- package/src/status-issues.ts +0 -34
- package/src/test-support/lifecycle-test-support.ts +0 -456
- 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/send.ts
DELETED
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createMessageReceiptFromOutboundResults,
|
|
3
|
-
type MessageReceipt,
|
|
4
|
-
type MessageReceiptPartKind,
|
|
5
|
-
} from "klaw/plugin-sdk/channel-message";
|
|
6
|
-
import type { KlawConfig } from "klaw/plugin-sdk/config-contracts";
|
|
7
|
-
import { formatErrorMessage } from "klaw/plugin-sdk/error-runtime";
|
|
8
|
-
import { resolveZaloAccount } from "./accounts.js";
|
|
9
|
-
import type { ZaloFetch } from "./api.js";
|
|
10
|
-
import { sendMessage, sendPhoto } from "./api.js";
|
|
11
|
-
import { resolveZaloProxyFetch } from "./proxy.js";
|
|
12
|
-
import { resolveZaloToken } from "./token.js";
|
|
13
|
-
|
|
14
|
-
type ZaloSendOptions = {
|
|
15
|
-
token?: string;
|
|
16
|
-
accountId?: string;
|
|
17
|
-
cfg?: KlawConfig;
|
|
18
|
-
mediaUrl?: string;
|
|
19
|
-
caption?: string;
|
|
20
|
-
verbose?: boolean;
|
|
21
|
-
proxy?: string;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
type ZaloSendResult = {
|
|
25
|
-
ok: boolean;
|
|
26
|
-
messageId?: string;
|
|
27
|
-
receipt: MessageReceipt;
|
|
28
|
-
error?: string;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
function createZaloSendReceipt(params: {
|
|
32
|
-
messageId?: string;
|
|
33
|
-
chatId: string;
|
|
34
|
-
kind: MessageReceiptPartKind;
|
|
35
|
-
}): MessageReceipt {
|
|
36
|
-
const messageId = params.messageId?.trim();
|
|
37
|
-
return createMessageReceiptFromOutboundResults({
|
|
38
|
-
results: messageId
|
|
39
|
-
? [
|
|
40
|
-
{
|
|
41
|
-
channel: "zalo",
|
|
42
|
-
messageId,
|
|
43
|
-
chatId: params.chatId,
|
|
44
|
-
},
|
|
45
|
-
]
|
|
46
|
-
: [],
|
|
47
|
-
kind: params.kind,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function toZaloSendResult(
|
|
52
|
-
response: {
|
|
53
|
-
ok?: boolean;
|
|
54
|
-
result?: { message_id?: string };
|
|
55
|
-
},
|
|
56
|
-
params: { chatId: string; kind: MessageReceiptPartKind },
|
|
57
|
-
): ZaloSendResult {
|
|
58
|
-
if (response.ok && response.result) {
|
|
59
|
-
return {
|
|
60
|
-
ok: true,
|
|
61
|
-
messageId: response.result.message_id,
|
|
62
|
-
receipt: createZaloSendReceipt({
|
|
63
|
-
messageId: response.result.message_id,
|
|
64
|
-
chatId: params.chatId,
|
|
65
|
-
kind: params.kind,
|
|
66
|
-
}),
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
return {
|
|
70
|
-
ok: false,
|
|
71
|
-
error: "Failed to send message",
|
|
72
|
-
receipt: createZaloSendReceipt({ chatId: params.chatId, kind: params.kind }),
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async function runZaloSend(
|
|
77
|
-
failureMessage: string,
|
|
78
|
-
params: { chatId: string; kind: MessageReceiptPartKind },
|
|
79
|
-
send: () => Promise<{ ok?: boolean; result?: { message_id?: string } }>,
|
|
80
|
-
): Promise<ZaloSendResult> {
|
|
81
|
-
try {
|
|
82
|
-
const result = toZaloSendResult(await send(), params);
|
|
83
|
-
return result.ok ? result : { ok: false, error: failureMessage, receipt: result.receipt };
|
|
84
|
-
} catch (err) {
|
|
85
|
-
return {
|
|
86
|
-
ok: false,
|
|
87
|
-
error: formatErrorMessage(err),
|
|
88
|
-
receipt: createZaloSendReceipt({ chatId: params.chatId, kind: params.kind }),
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function resolveSendContext(options: ZaloSendOptions): {
|
|
94
|
-
token: string;
|
|
95
|
-
fetcher?: ZaloFetch;
|
|
96
|
-
} {
|
|
97
|
-
if (options.cfg) {
|
|
98
|
-
const account = resolveZaloAccount({
|
|
99
|
-
cfg: options.cfg,
|
|
100
|
-
accountId: options.accountId,
|
|
101
|
-
});
|
|
102
|
-
const token = options.token || account.token;
|
|
103
|
-
const proxy = options.proxy ?? account.config.proxy;
|
|
104
|
-
return { token, fetcher: resolveZaloProxyFetch(proxy) };
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const token = options.token ?? resolveZaloToken(undefined, options.accountId).token;
|
|
108
|
-
const proxy = options.proxy;
|
|
109
|
-
return { token, fetcher: resolveZaloProxyFetch(proxy) };
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function resolveValidatedSendContext(
|
|
113
|
-
chatId: string,
|
|
114
|
-
options: ZaloSendOptions,
|
|
115
|
-
): { ok: true; chatId: string; token: string; fetcher?: ZaloFetch } | { ok: false; error: string } {
|
|
116
|
-
const { token, fetcher } = resolveSendContext(options);
|
|
117
|
-
if (!token) {
|
|
118
|
-
return { ok: false, error: "No Zalo bot token configured" };
|
|
119
|
-
}
|
|
120
|
-
const trimmedChatId = chatId?.trim();
|
|
121
|
-
if (!trimmedChatId) {
|
|
122
|
-
return { ok: false, error: "No chat_id provided" };
|
|
123
|
-
}
|
|
124
|
-
return { ok: true, chatId: trimmedChatId, token, fetcher };
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function resolveSendContextOrFailure(
|
|
128
|
-
chatId: string,
|
|
129
|
-
options: ZaloSendOptions,
|
|
130
|
-
):
|
|
131
|
-
| { context: { chatId: string; token: string; fetcher?: ZaloFetch } }
|
|
132
|
-
| { failure: ZaloSendResult } {
|
|
133
|
-
const context = resolveValidatedSendContext(chatId, options);
|
|
134
|
-
return context.ok
|
|
135
|
-
? { context }
|
|
136
|
-
: {
|
|
137
|
-
failure: {
|
|
138
|
-
ok: false,
|
|
139
|
-
error: context.error,
|
|
140
|
-
receipt: createZaloSendReceipt({ chatId, kind: "unknown" }),
|
|
141
|
-
},
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export async function sendMessageZalo(
|
|
146
|
-
chatId: string,
|
|
147
|
-
text: string,
|
|
148
|
-
options: ZaloSendOptions = {},
|
|
149
|
-
): Promise<ZaloSendResult> {
|
|
150
|
-
const resolved = resolveSendContextOrFailure(chatId, options);
|
|
151
|
-
if ("failure" in resolved) {
|
|
152
|
-
return resolved.failure;
|
|
153
|
-
}
|
|
154
|
-
const { context } = resolved;
|
|
155
|
-
|
|
156
|
-
if (options.mediaUrl) {
|
|
157
|
-
return sendPhotoZalo(context.chatId, options.mediaUrl, {
|
|
158
|
-
...options,
|
|
159
|
-
token: context.token,
|
|
160
|
-
caption: text || options.caption,
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return await runZaloSend("Failed to send message", { chatId: context.chatId, kind: "text" }, () =>
|
|
165
|
-
sendMessage(
|
|
166
|
-
context.token,
|
|
167
|
-
{
|
|
168
|
-
chat_id: context.chatId,
|
|
169
|
-
text: text.slice(0, 2000),
|
|
170
|
-
},
|
|
171
|
-
context.fetcher,
|
|
172
|
-
),
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export async function sendPhotoZalo(
|
|
177
|
-
chatId: string,
|
|
178
|
-
photoUrl: string,
|
|
179
|
-
options: ZaloSendOptions = {},
|
|
180
|
-
): Promise<ZaloSendResult> {
|
|
181
|
-
const resolved = resolveSendContextOrFailure(chatId, options);
|
|
182
|
-
if ("failure" in resolved) {
|
|
183
|
-
return resolved.failure;
|
|
184
|
-
}
|
|
185
|
-
const { context } = resolved;
|
|
186
|
-
|
|
187
|
-
if (!photoUrl?.trim()) {
|
|
188
|
-
return {
|
|
189
|
-
ok: false,
|
|
190
|
-
error: "No photo URL provided",
|
|
191
|
-
receipt: createZaloSendReceipt({ chatId: context.chatId, kind: "media" }),
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return await runZaloSend("Failed to send photo", { chatId: context.chatId, kind: "media" }, () =>
|
|
196
|
-
(async () =>
|
|
197
|
-
sendPhoto(
|
|
198
|
-
context.token,
|
|
199
|
-
{
|
|
200
|
-
chat_id: context.chatId,
|
|
201
|
-
photo: photoUrl.trim(),
|
|
202
|
-
caption: options.caption?.slice(0, 2000),
|
|
203
|
-
},
|
|
204
|
-
context.fetcher,
|
|
205
|
-
))(),
|
|
206
|
-
);
|
|
207
|
-
}
|
package/src/session-route.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildChannelOutboundSessionRoute,
|
|
3
|
-
stripChannelTargetPrefix,
|
|
4
|
-
stripTargetKindPrefix,
|
|
5
|
-
type ChannelOutboundSessionRouteParams,
|
|
6
|
-
} from "klaw/plugin-sdk/core";
|
|
7
|
-
import { normalizeLowercaseStringOrEmpty } from "klaw/plugin-sdk/string-coerce-runtime";
|
|
8
|
-
|
|
9
|
-
export function resolveZaloOutboundSessionRoute(params: ChannelOutboundSessionRouteParams) {
|
|
10
|
-
const trimmed = stripChannelTargetPrefix(params.target, "zalo", "zl");
|
|
11
|
-
if (!trimmed) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
const isGroup = normalizeLowercaseStringOrEmpty(trimmed).startsWith("group:");
|
|
15
|
-
const peerId = stripTargetKindPrefix(trimmed);
|
|
16
|
-
if (!peerId) {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
return buildChannelOutboundSessionRoute({
|
|
20
|
-
cfg: params.cfg,
|
|
21
|
-
agentId: params.agentId,
|
|
22
|
-
channel: "zalo",
|
|
23
|
-
accountId: params.accountId,
|
|
24
|
-
peer: {
|
|
25
|
-
kind: isGroup ? "group" : "direct",
|
|
26
|
-
id: peerId,
|
|
27
|
-
},
|
|
28
|
-
chatType: isGroup ? "group" : "direct",
|
|
29
|
-
from: isGroup ? `zalo:group:${peerId}` : `zalo:${peerId}`,
|
|
30
|
-
to: `zalo:${peerId}`,
|
|
31
|
-
});
|
|
32
|
-
}
|
package/src/setup-allow-from.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DEFAULT_ACCOUNT_ID,
|
|
3
|
-
createSetupTranslator,
|
|
4
|
-
formatDocsLink,
|
|
5
|
-
mergeAllowFromEntries,
|
|
6
|
-
type ChannelSetupDmPolicy,
|
|
7
|
-
type ChannelSetupWizard,
|
|
8
|
-
type KlawConfig,
|
|
9
|
-
} from "klaw/plugin-sdk/setup";
|
|
10
|
-
import { resolveDefaultZaloAccountId, resolveZaloAccount } from "./accounts.js";
|
|
11
|
-
|
|
12
|
-
const t = createSetupTranslator();
|
|
13
|
-
|
|
14
|
-
type ZaloAccountSetupConfig = {
|
|
15
|
-
enabled?: boolean;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export async function noteZaloTokenHelp(
|
|
19
|
-
prompter: Parameters<NonNullable<ChannelSetupWizard["finalize"]>>[0]["prompter"],
|
|
20
|
-
): Promise<void> {
|
|
21
|
-
await prompter.note(
|
|
22
|
-
[
|
|
23
|
-
t("wizard.zalo.helpOpenPlatform"),
|
|
24
|
-
t("wizard.zalo.helpCreateBot"),
|
|
25
|
-
t("wizard.zalo.helpTokenFormat"),
|
|
26
|
-
t("wizard.zalo.helpEnvTip"),
|
|
27
|
-
`Docs: ${formatDocsLink("/channels/zalo", "zalo")}`,
|
|
28
|
-
].join("\n"),
|
|
29
|
-
t("wizard.zalo.botTokenTitle"),
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export async function promptZaloAllowFrom(params: {
|
|
34
|
-
cfg: KlawConfig;
|
|
35
|
-
prompter: Parameters<NonNullable<ChannelSetupDmPolicy["promptAllowFrom"]>>[0]["prompter"];
|
|
36
|
-
accountId?: string;
|
|
37
|
-
}): Promise<KlawConfig> {
|
|
38
|
-
const { cfg, prompter } = params;
|
|
39
|
-
const accountId = params.accountId ?? resolveDefaultZaloAccountId(cfg);
|
|
40
|
-
const resolved = resolveZaloAccount({ cfg, accountId });
|
|
41
|
-
const existingAllowFrom = resolved.config.allowFrom ?? [];
|
|
42
|
-
const entry = await prompter.text({
|
|
43
|
-
message: t("wizard.zalo.allowFromPrompt"),
|
|
44
|
-
placeholder: "123456789",
|
|
45
|
-
initialValue: existingAllowFrom[0] ? String(existingAllowFrom[0]) : undefined,
|
|
46
|
-
validate: (value) => {
|
|
47
|
-
const raw = (value ?? "").trim();
|
|
48
|
-
if (!raw) {
|
|
49
|
-
return t("common.required");
|
|
50
|
-
}
|
|
51
|
-
if (!/^\d+$/.test(raw)) {
|
|
52
|
-
return t("wizard.zalo.allowFromNumeric");
|
|
53
|
-
}
|
|
54
|
-
return undefined;
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
const normalized = entry.trim();
|
|
58
|
-
const unique = mergeAllowFromEntries(existingAllowFrom, [normalized]);
|
|
59
|
-
|
|
60
|
-
if (accountId === DEFAULT_ACCOUNT_ID) {
|
|
61
|
-
return {
|
|
62
|
-
...cfg,
|
|
63
|
-
channels: {
|
|
64
|
-
...cfg.channels,
|
|
65
|
-
zalo: {
|
|
66
|
-
...cfg.channels?.zalo,
|
|
67
|
-
enabled: true,
|
|
68
|
-
dmPolicy: "allowlist",
|
|
69
|
-
allowFrom: unique,
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
} as KlawConfig;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const currentAccount = cfg.channels?.zalo?.accounts?.[accountId] as
|
|
76
|
-
| ZaloAccountSetupConfig
|
|
77
|
-
| undefined;
|
|
78
|
-
return {
|
|
79
|
-
...cfg,
|
|
80
|
-
channels: {
|
|
81
|
-
...cfg.channels,
|
|
82
|
-
zalo: {
|
|
83
|
-
...cfg.channels?.zalo,
|
|
84
|
-
enabled: true,
|
|
85
|
-
accounts: {
|
|
86
|
-
...cfg.channels?.zalo?.accounts,
|
|
87
|
-
[accountId]: {
|
|
88
|
-
...currentAccount,
|
|
89
|
-
enabled: currentAccount?.enabled ?? true,
|
|
90
|
-
dmPolicy: "allowlist",
|
|
91
|
-
allowFrom: unique,
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
} as KlawConfig;
|
|
97
|
-
}
|
package/src/setup-core.ts
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
addWildcardAllowFrom,
|
|
3
|
-
createDelegatedSetupWizardProxy,
|
|
4
|
-
createPatchedAccountSetupAdapter,
|
|
5
|
-
createSetupInputPresenceValidator,
|
|
6
|
-
DEFAULT_ACCOUNT_ID,
|
|
7
|
-
normalizeAccountId,
|
|
8
|
-
createSetupTranslator,
|
|
9
|
-
type ChannelSetupDmPolicy,
|
|
10
|
-
type ChannelSetupWizard,
|
|
11
|
-
} from "klaw/plugin-sdk/setup";
|
|
12
|
-
import { resolveDefaultZaloAccountId, resolveZaloAccount } from "./accounts.js";
|
|
13
|
-
import { promptZaloAllowFrom } from "./setup-allow-from.js";
|
|
14
|
-
|
|
15
|
-
const t = createSetupTranslator();
|
|
16
|
-
|
|
17
|
-
const channel = "zalo" as const;
|
|
18
|
-
|
|
19
|
-
type ZaloAccountSetupConfig = {
|
|
20
|
-
enabled?: boolean;
|
|
21
|
-
dmPolicy?: string;
|
|
22
|
-
allowFrom?: Array<string | number> | ReadonlyArray<string | number>;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export const zaloSetupAdapter = createPatchedAccountSetupAdapter({
|
|
26
|
-
channelKey: channel,
|
|
27
|
-
validateInput: createSetupInputPresenceValidator({
|
|
28
|
-
defaultAccountOnlyEnvError: "ZALO_BOT_TOKEN can only be used for the default account.",
|
|
29
|
-
whenNotUseEnv: [
|
|
30
|
-
{
|
|
31
|
-
someOf: ["token", "tokenFile"],
|
|
32
|
-
message: "Zalo requires token or --token-file (or --use-env).",
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
}),
|
|
36
|
-
buildPatch: (input) =>
|
|
37
|
-
input.useEnv
|
|
38
|
-
? {}
|
|
39
|
-
: input.tokenFile
|
|
40
|
-
? { tokenFile: input.tokenFile }
|
|
41
|
-
: input.token
|
|
42
|
-
? { botToken: input.token }
|
|
43
|
-
: {},
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
export const zaloDmPolicy: ChannelSetupDmPolicy = {
|
|
47
|
-
label: "Zalo",
|
|
48
|
-
channel,
|
|
49
|
-
policyKey: "channels.zalo.dmPolicy",
|
|
50
|
-
allowFromKey: "channels.zalo.allowFrom",
|
|
51
|
-
resolveConfigKeys: (cfg, accountId) =>
|
|
52
|
-
(accountId ?? resolveDefaultZaloAccountId(cfg)) !== DEFAULT_ACCOUNT_ID
|
|
53
|
-
? {
|
|
54
|
-
policyKey: `channels.zalo.accounts.${accountId ?? resolveDefaultZaloAccountId(cfg)}.dmPolicy`,
|
|
55
|
-
allowFromKey: `channels.zalo.accounts.${accountId ?? resolveDefaultZaloAccountId(cfg)}.allowFrom`,
|
|
56
|
-
}
|
|
57
|
-
: {
|
|
58
|
-
policyKey: "channels.zalo.dmPolicy",
|
|
59
|
-
allowFromKey: "channels.zalo.allowFrom",
|
|
60
|
-
},
|
|
61
|
-
getCurrent: (cfg, accountId) =>
|
|
62
|
-
resolveZaloAccount({
|
|
63
|
-
cfg: cfg,
|
|
64
|
-
accountId: accountId ?? resolveDefaultZaloAccountId(cfg),
|
|
65
|
-
}).config.dmPolicy ?? "pairing",
|
|
66
|
-
setPolicy: (cfg, policy, accountId) => {
|
|
67
|
-
const resolvedAccountId =
|
|
68
|
-
accountId && normalizeAccountId(accountId)
|
|
69
|
-
? (normalizeAccountId(accountId) ?? DEFAULT_ACCOUNT_ID)
|
|
70
|
-
: resolveDefaultZaloAccountId(cfg);
|
|
71
|
-
const resolved = resolveZaloAccount({
|
|
72
|
-
cfg: cfg,
|
|
73
|
-
accountId: resolvedAccountId,
|
|
74
|
-
});
|
|
75
|
-
if (resolvedAccountId === DEFAULT_ACCOUNT_ID) {
|
|
76
|
-
return {
|
|
77
|
-
...cfg,
|
|
78
|
-
channels: {
|
|
79
|
-
...cfg.channels,
|
|
80
|
-
zalo: {
|
|
81
|
-
...cfg.channels?.zalo,
|
|
82
|
-
enabled: true,
|
|
83
|
-
dmPolicy: policy,
|
|
84
|
-
...(policy === "open"
|
|
85
|
-
? { allowFrom: addWildcardAllowFrom(resolved.config.allowFrom) }
|
|
86
|
-
: {}),
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
const currentAccount = cfg.channels?.zalo?.accounts?.[resolvedAccountId] as
|
|
92
|
-
| ZaloAccountSetupConfig
|
|
93
|
-
| undefined;
|
|
94
|
-
return {
|
|
95
|
-
...cfg,
|
|
96
|
-
channels: {
|
|
97
|
-
...cfg.channels,
|
|
98
|
-
zalo: {
|
|
99
|
-
...cfg.channels?.zalo,
|
|
100
|
-
enabled: true,
|
|
101
|
-
accounts: {
|
|
102
|
-
...cfg.channels?.zalo?.accounts,
|
|
103
|
-
[resolvedAccountId]: {
|
|
104
|
-
...currentAccount,
|
|
105
|
-
enabled: currentAccount?.enabled ?? true,
|
|
106
|
-
dmPolicy: policy,
|
|
107
|
-
...(policy === "open"
|
|
108
|
-
? { allowFrom: addWildcardAllowFrom(resolved.config.allowFrom) }
|
|
109
|
-
: {}),
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
},
|
|
116
|
-
promptAllowFrom: async ({ cfg, prompter, accountId }) =>
|
|
117
|
-
promptZaloAllowFrom({
|
|
118
|
-
cfg,
|
|
119
|
-
prompter,
|
|
120
|
-
accountId: accountId ?? resolveDefaultZaloAccountId(cfg),
|
|
121
|
-
}),
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
export function createZaloSetupWizardProxy(
|
|
125
|
-
loadWizard: () => Promise<ChannelSetupWizard>,
|
|
126
|
-
): ChannelSetupWizard {
|
|
127
|
-
return createDelegatedSetupWizardProxy({
|
|
128
|
-
channel,
|
|
129
|
-
loadWizard,
|
|
130
|
-
status: {
|
|
131
|
-
configuredLabel: t("wizard.channels.statusConfigured"),
|
|
132
|
-
unconfiguredLabel: t("wizard.channels.statusNeedsToken"),
|
|
133
|
-
configuredHint: t("wizard.channels.statusRecommendedConfigured"),
|
|
134
|
-
unconfiguredHint: t("wizard.channels.statusRecommendedNewcomerFriendly"),
|
|
135
|
-
configuredScore: 1,
|
|
136
|
-
unconfiguredScore: 10,
|
|
137
|
-
},
|
|
138
|
-
credentials: [],
|
|
139
|
-
delegateFinalize: true,
|
|
140
|
-
dmPolicy: zaloDmPolicy,
|
|
141
|
-
disable: (cfg) => ({
|
|
142
|
-
...cfg,
|
|
143
|
-
channels: {
|
|
144
|
-
...cfg.channels,
|
|
145
|
-
zalo: {
|
|
146
|
-
...cfg.channels?.zalo,
|
|
147
|
-
enabled: false,
|
|
148
|
-
},
|
|
149
|
-
},
|
|
150
|
-
}),
|
|
151
|
-
});
|
|
152
|
-
}
|
package/src/setup-status.test.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { createPluginSetupWizardStatus } from "klaw/plugin-sdk/plugin-test-runtime";
|
|
2
|
-
import { describe, expect, it } from "vitest";
|
|
3
|
-
import type { KlawConfig } from "../runtime-api.js";
|
|
4
|
-
import { zaloSetupWizard } from "./setup-surface.js";
|
|
5
|
-
|
|
6
|
-
const zaloGetStatus = createPluginSetupWizardStatus({
|
|
7
|
-
id: "zalo",
|
|
8
|
-
meta: {
|
|
9
|
-
label: "Zalo",
|
|
10
|
-
},
|
|
11
|
-
setupWizard: zaloSetupWizard,
|
|
12
|
-
} as never);
|
|
13
|
-
|
|
14
|
-
describe("zalo setup wizard status", () => {
|
|
15
|
-
it("treats SecretRef botToken as configured", async () => {
|
|
16
|
-
const status = await zaloGetStatus({
|
|
17
|
-
cfg: {
|
|
18
|
-
channels: {
|
|
19
|
-
zalo: {
|
|
20
|
-
botToken: {
|
|
21
|
-
source: "env",
|
|
22
|
-
provider: "default",
|
|
23
|
-
id: "ZALO_BOT_TOKEN",
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
} as KlawConfig,
|
|
28
|
-
accountOverrides: {},
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
expect(status.configured).toBe(true);
|
|
32
|
-
});
|
|
33
|
-
});
|