feat: migrate zalo plugin to sdk

This commit is contained in:
Peter Steinberger
2026-01-18 03:34:02 +00:00
parent 5fa1a63978
commit b6d470a679
22 changed files with 182 additions and 654 deletions

View File

@@ -1,25 +1,29 @@
import type { ChannelAccountSnapshot, ChannelDock, ChannelPlugin } from "clawdbot/plugin-sdk";
import { buildChannelConfigSchema } from "clawdbot/plugin-sdk";
import type {
ChannelAccountSnapshot,
ChannelDock,
ChannelPlugin,
ClawdbotConfig,
} from "clawdbot/plugin-sdk";
import {
applyAccountNameToChannelSection,
buildChannelConfigSchema,
DEFAULT_ACCOUNT_ID,
deleteAccountFromConfigSection,
formatPairingApproveHint,
migrateBaseNameToDefaultAccount,
normalizeAccountId,
PAIRING_APPROVED_MESSAGE,
setAccountEnabledInConfigSection,
} from "clawdbot/plugin-sdk";
import { listZaloAccountIds, resolveDefaultZaloAccountId, resolveZaloAccount, type ResolvedZaloAccount } from "./accounts.js";
import { zaloMessageActions } from "./actions.js";
import { ZaloConfigSchema } from "./config-schema.js";
import {
deleteAccountFromConfigSection,
setAccountEnabledInConfigSection,
} from "./shared/channel-config.js";
import { zaloOnboardingAdapter } from "./onboarding.js";
import { formatPairingApproveHint, PAIRING_APPROVED_MESSAGE } from "./shared/pairing.js";
import { resolveZaloProxyFetch } from "./proxy.js";
import { probeZalo } from "./probe.js";
import { sendMessageZalo } from "./send.js";
import {
applyAccountNameToChannelSection,
migrateBaseNameToDefaultAccount,
} from "./shared/channel-setup.js";
import { collectZaloStatusIssues } from "./status-issues.js";
import type { CoreConfig } from "./types.js";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "./shared/account-ids.js";
const meta = {
id: "zalo",
@@ -33,7 +37,6 @@ const meta = {
quickstartAllowFrom: true,
};
function normalizeZaloMessagingTarget(raw: string): string | undefined {
const trimmed = raw?.trim();
if (!trimmed) return undefined;
@@ -50,7 +53,7 @@ export const zaloDock: ChannelDock = {
outbound: { textChunkLimit: 2000 },
config: {
resolveAllowFrom: ({ cfg, accountId }) =>
(resolveZaloAccount({ cfg: cfg as CoreConfig, accountId }).config.allowFrom ?? []).map(
(resolveZaloAccount({ cfg: cfg as ClawdbotConfig, accountId }).config.allowFrom ?? []).map(
(entry) => String(entry),
),
formatAllowFrom: ({ allowFrom }) =>
@@ -84,12 +87,12 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
reload: { configPrefixes: ["channels.zalo"] },
configSchema: buildChannelConfigSchema(ZaloConfigSchema),
config: {
listAccountIds: (cfg) => listZaloAccountIds(cfg as CoreConfig),
resolveAccount: (cfg, accountId) => resolveZaloAccount({ cfg: cfg as CoreConfig, accountId }),
defaultAccountId: (cfg) => resolveDefaultZaloAccountId(cfg as CoreConfig),
listAccountIds: (cfg) => listZaloAccountIds(cfg as ClawdbotConfig),
resolveAccount: (cfg, accountId) => resolveZaloAccount({ cfg: cfg as ClawdbotConfig, accountId }),
defaultAccountId: (cfg) => resolveDefaultZaloAccountId(cfg as ClawdbotConfig),
setAccountEnabled: ({ cfg, accountId, enabled }) =>
setAccountEnabledInConfigSection({
cfg: cfg as CoreConfig,
cfg: cfg as ClawdbotConfig,
sectionKey: "zalo",
accountId,
enabled,
@@ -97,7 +100,7 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
}),
deleteAccount: ({ cfg, accountId }) =>
deleteAccountFromConfigSection({
cfg: cfg as CoreConfig,
cfg: cfg as ClawdbotConfig,
sectionKey: "zalo",
accountId,
clearBaseFields: ["botToken", "tokenFile", "name"],
@@ -111,7 +114,7 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
tokenSource: account.tokenSource,
}),
resolveAllowFrom: ({ cfg, accountId }) =>
(resolveZaloAccount({ cfg: cfg as CoreConfig, accountId }).config.allowFrom ?? []).map(
(resolveZaloAccount({ cfg: cfg as ClawdbotConfig, accountId }).config.allowFrom ?? []).map(
(entry) => String(entry),
),
formatAllowFrom: ({ allowFrom }) =>
@@ -125,7 +128,7 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
resolveDmPolicy: ({ cfg, accountId, account }) => {
const resolvedAccountId = accountId ?? account.accountId ?? DEFAULT_ACCOUNT_ID;
const useAccountPath = Boolean(
(cfg as CoreConfig).channels?.zalo?.accounts?.[resolvedAccountId],
(cfg as ClawdbotConfig).channels?.zalo?.accounts?.[resolvedAccountId],
);
const basePath = useAccountPath
? `channels.zalo.accounts.${resolvedAccountId}.`
@@ -161,7 +164,7 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
directory: {
self: async () => null,
listPeers: async ({ cfg, accountId, query, limit }) => {
const account = resolveZaloAccount({ cfg: cfg as CoreConfig, accountId });
const account = resolveZaloAccount({ cfg: cfg as ClawdbotConfig, accountId });
const q = query?.trim().toLowerCase() || "";
const peers = Array.from(
new Set(
@@ -182,7 +185,7 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
resolveAccountId: ({ accountId }) => normalizeAccountId(accountId),
applyAccountName: ({ cfg, accountId, name }) =>
applyAccountNameToChannelSection({
cfg: cfg as CoreConfig,
cfg: cfg as ClawdbotConfig,
channelKey: "zalo",
accountId,
name,
@@ -198,7 +201,7 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
},
applyAccountConfig: ({ cfg, accountId, input }) => {
const namedConfig = applyAccountNameToChannelSection({
cfg: cfg as CoreConfig,
cfg: cfg as ClawdbotConfig,
channelKey: "zalo",
accountId,
name: input.name,
@@ -227,7 +230,7 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
: {}),
},
},
} as CoreConfig;
} as ClawdbotConfig;
}
return {
...next,
@@ -250,14 +253,14 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
},
},
},
} as CoreConfig;
} as ClawdbotConfig;
},
},
pairing: {
idLabel: "zaloUserId",
normalizeAllowEntry: (entry) => entry.replace(/^(zalo|zl):/i, ""),
notifyApproval: async ({ cfg, id }) => {
const account = resolveZaloAccount({ cfg: cfg as CoreConfig });
const account = resolveZaloAccount({ cfg: cfg as ClawdbotConfig });
if (!account.token) throw new Error("Zalo token not configured");
await sendMessageZalo(id, PAIRING_APPROVED_MESSAGE, { token: account.token });
},
@@ -289,7 +292,7 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
sendText: async ({ to, text, accountId, cfg }) => {
const result = await sendMessageZalo(to, text, {
accountId: accountId ?? undefined,
cfg: cfg as CoreConfig,
cfg: cfg as ClawdbotConfig,
});
return {
channel: "zalo",
@@ -302,7 +305,7 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
const result = await sendMessageZalo(to, text, {
accountId: accountId ?? undefined,
mediaUrl,
cfg: cfg as CoreConfig,
cfg: cfg as ClawdbotConfig,
});
return {
channel: "zalo",
@@ -375,7 +378,7 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
return monitorZaloProvider({
token,
account,
config: ctx.cfg as CoreConfig,
config: ctx.cfg as ClawdbotConfig,
runtime: ctx.runtime,
abortSignal: ctx.abortSignal,
useWebhook: Boolean(account.config.webhookUrl),