mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-21 21:55:07 +00:00
style(extensions): format channel integration updates
This commit is contained in:
@@ -21,8 +21,8 @@ export function setBlueBubblesDmPolicy(
|
||||
const existingAllowFrom =
|
||||
resolvedAccountId === "default"
|
||||
? cfg.channels?.bluebubbles?.allowFrom
|
||||
: cfg.channels?.bluebubbles?.accounts?.[resolvedAccountId]?.allowFrom ??
|
||||
cfg.channels?.bluebubbles?.allowFrom;
|
||||
: (cfg.channels?.bluebubbles?.accounts?.[resolvedAccountId]?.allowFrom ??
|
||||
cfg.channels?.bluebubbles?.allowFrom);
|
||||
return patchScopedAccountConfig({
|
||||
cfg,
|
||||
channelKey: channel,
|
||||
|
||||
@@ -149,14 +149,9 @@ const dmPolicy: ChannelSetupDmPolicy = {
|
||||
resolveBlueBubblesAccount({
|
||||
cfg,
|
||||
accountId: accountId ?? resolveDefaultBlueBubblesAccountId(cfg),
|
||||
}).config
|
||||
.dmPolicy ?? "pairing",
|
||||
}).config.dmPolicy ?? "pairing",
|
||||
setPolicy: (cfg, policy, accountId) =>
|
||||
setBlueBubblesDmPolicy(
|
||||
cfg,
|
||||
accountId ?? resolveDefaultBlueBubblesAccountId(cfg),
|
||||
policy,
|
||||
),
|
||||
setBlueBubblesDmPolicy(cfg, accountId ?? resolveDefaultBlueBubblesAccountId(cfg), policy),
|
||||
promptAllowFrom: promptBlueBubblesAllowFrom,
|
||||
};
|
||||
|
||||
|
||||
@@ -108,7 +108,8 @@ export async function handleDiscordGuildAction(
|
||||
const userId = readStringParam(params, "userId", {
|
||||
required: true,
|
||||
});
|
||||
const effectiveAccountId = accountId ?? (cfg ? resolveDefaultDiscordAccountId(cfg) : undefined);
|
||||
const effectiveAccountId =
|
||||
accountId ?? (cfg ? resolveDefaultDiscordAccountId(cfg) : undefined);
|
||||
const member = effectiveAccountId
|
||||
? await discordGuildActionRuntime.fetchMemberInfoDiscord(guildId, userId, {
|
||||
accountId: effectiveAccountId,
|
||||
|
||||
@@ -499,7 +499,9 @@ describe("handleDiscordGuildAction", () => {
|
||||
client_status: {},
|
||||
} as never);
|
||||
|
||||
discordGuildActionRuntime.fetchMemberInfoDiscord = vi.fn(async () => ({ user: { id: "U1" } })) as never;
|
||||
discordGuildActionRuntime.fetchMemberInfoDiscord = vi.fn(async () => ({
|
||||
user: { id: "U1" },
|
||||
})) as never;
|
||||
|
||||
const result = await handleDiscordGuildAction(
|
||||
"memberInfo",
|
||||
|
||||
@@ -90,9 +90,7 @@ describe("discordMessageActions", () => {
|
||||
accountId: "work",
|
||||
});
|
||||
|
||||
expect(defaultDiscovery?.actions).toEqual(
|
||||
expect.arrayContaining(["send", "poll"]),
|
||||
);
|
||||
expect(defaultDiscovery?.actions).toEqual(expect.arrayContaining(["send", "poll"]));
|
||||
expect(defaultDiscovery?.actions).not.toContain("react");
|
||||
expect(workDiscovery?.actions).toEqual(
|
||||
expect.arrayContaining(["send", "react", "reactions", "emoji-list"]),
|
||||
|
||||
@@ -80,10 +80,7 @@ function resolveDiscordPolicyContext(params: ChannelGroupContext) {
|
||||
(params.accountId
|
||||
? params.cfg.channels?.discord?.accounts?.[params.accountId]?.guilds
|
||||
: undefined) ?? params.cfg.channels?.discord?.guilds;
|
||||
const guildEntry = resolveDiscordGuildEntry(
|
||||
guilds,
|
||||
params.groupSpace,
|
||||
);
|
||||
const guildEntry = resolveDiscordGuildEntry(guilds, params.groupSpace);
|
||||
const channelEntries = guildEntry?.channels;
|
||||
const channelEntry =
|
||||
channelEntries && Object.keys(channelEntries).length > 0
|
||||
|
||||
@@ -22,6 +22,7 @@ import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/routing";
|
||||
import { logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { getChildLogger } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { logDebug } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { resolveDefaultDiscordAccountId } from "../accounts.js";
|
||||
import {
|
||||
isDiscordGroupAllowedByPolicy,
|
||||
normalizeDiscordSlug,
|
||||
@@ -34,7 +35,6 @@ import {
|
||||
} from "./allow-list.js";
|
||||
import { resolveDiscordDmCommandAccess } from "./dm-command-auth.js";
|
||||
import { handleDiscordDmCommandDecision } from "./dm-command-decision.js";
|
||||
import { resolveDefaultDiscordAccountId } from "../accounts.js";
|
||||
import {
|
||||
formatDiscordUserTag,
|
||||
resolveDiscordSystemLocation,
|
||||
|
||||
@@ -36,7 +36,10 @@ function resolveImplicitToolAccountId(params: {
|
||||
}
|
||||
|
||||
const contextualAccountId = normalizeOptionalAccountId(params.defaultAccountId);
|
||||
if (contextualAccountId && listFeishuAccountIds(params.api.config).includes(contextualAccountId)) {
|
||||
if (
|
||||
contextualAccountId &&
|
||||
listFeishuAccountIds(params.api.config).includes(contextualAccountId)
|
||||
) {
|
||||
const contextualAccount = resolveFeishuAccount({
|
||||
cfg: params.api.config,
|
||||
accountId: contextualAccountId,
|
||||
|
||||
@@ -82,9 +82,7 @@ const googlechatDmPolicy: ChannelSetupDmPolicy = {
|
||||
dm: {
|
||||
...currentDm,
|
||||
policy,
|
||||
...(policy === "open"
|
||||
? { allowFrom: addWildcardAllowFrom(currentDm?.allowFrom) }
|
||||
: {}),
|
||||
...(policy === "open" ? { allowFrom: addWildcardAllowFrom(currentDm?.allowFrom) } : {}),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -328,10 +328,7 @@ describe("googlechat setup", () => {
|
||||
|
||||
expect(next?.channels?.googlechat?.dm?.policy).toBeUndefined();
|
||||
expect(next?.channels?.googlechat?.accounts?.alerts?.dm?.policy).toBe("open");
|
||||
expect(next?.channels?.googlechat?.accounts?.alerts?.dm?.allowFrom).toEqual([
|
||||
"users/123",
|
||||
"*",
|
||||
]);
|
||||
expect(next?.channels?.googlechat?.accounts?.alerts?.dm?.allowFrom).toEqual(["users/123", "*"]);
|
||||
});
|
||||
|
||||
it("keeps startAccount pending until abort, then unregisters", async () => {
|
||||
|
||||
@@ -94,9 +94,7 @@ export function resolveLineAccount(params: {
|
||||
accountId?: string;
|
||||
}): ResolvedLineAccount {
|
||||
const cfg = params.cfg;
|
||||
const accountId = normalizeSharedAccountId(
|
||||
params.accountId ?? resolveDefaultLineAccountId(cfg),
|
||||
);
|
||||
const accountId = normalizeSharedAccountId(params.accountId ?? resolveDefaultLineAccountId(cfg));
|
||||
const lineConfig = cfg.channels?.line as LineConfig | undefined;
|
||||
const accounts = lineConfig?.accounts;
|
||||
const accountConfig =
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
beginWebhookRequestPipelineOrReject,
|
||||
createWebhookInFlightLimiter,
|
||||
} from "openclaw/plugin-sdk/webhook-request-guards";
|
||||
import { resolveDefaultLineAccountId } from "./accounts.js";
|
||||
import { deliverLineAutoReply } from "./auto-reply-delivery.js";
|
||||
import { createLineBot } from "./bot.js";
|
||||
import { processLineMessage } from "./markdown-to-line.js";
|
||||
@@ -37,7 +38,6 @@ import {
|
||||
showLoadingAnimation,
|
||||
} from "./send.js";
|
||||
import { buildTemplateMessageFromPayload } from "./template-messages.js";
|
||||
import { resolveDefaultLineAccountId } from "./accounts.js";
|
||||
import type { LineChannelData, ResolvedLineAccount } from "./types.js";
|
||||
import { createLineNodeWebhookHandler } from "./webhook-node.js";
|
||||
|
||||
|
||||
@@ -1124,10 +1124,7 @@ describe("resolveMatrixAuth", () => {
|
||||
env: {} as NodeJS.ProcessEnv,
|
||||
});
|
||||
|
||||
expect(matrixDoRequestMock).toHaveBeenCalledWith(
|
||||
"GET",
|
||||
"/_matrix/client/v3/account/whoami",
|
||||
);
|
||||
expect(matrixDoRequestMock).toHaveBeenCalledWith("GET", "/_matrix/client/v3/account/whoami");
|
||||
expect(auth).toMatchObject({
|
||||
accountId: "default",
|
||||
homeserver: "https://matrix.example.org",
|
||||
|
||||
@@ -192,9 +192,7 @@ export const nextcloudTalkDmPolicy: ChannelSetupDmPolicy = {
|
||||
});
|
||||
return setNextcloudTalkAccountConfig(cfg as CoreConfig, resolvedAccountId, {
|
||||
dmPolicy: policy,
|
||||
...(policy === "open"
|
||||
? { allowFrom: addWildcardAllowFrom(resolved.config.allowFrom) }
|
||||
: {}),
|
||||
...(policy === "open" ? { allowFrom: addWildcardAllowFrom(resolved.config.allowFrom) } : {}),
|
||||
});
|
||||
},
|
||||
promptAllowFrom: promptNextcloudTalkAllowFromForAccount,
|
||||
|
||||
@@ -5,11 +5,7 @@ import { validateJsonSchemaValue } from "../../../src/plugins/schema-validator.j
|
||||
import { qqbotPlugin } from "./channel.js";
|
||||
import { qqbotSetupPlugin } from "./channel.setup.js";
|
||||
import { QQBotConfigSchema } from "./config-schema.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
resolveDefaultQQBotAccountId,
|
||||
resolveQQBotAccount,
|
||||
} from "./config.js";
|
||||
import { DEFAULT_ACCOUNT_ID, resolveDefaultQQBotAccountId, resolveQQBotAccount } from "./config.js";
|
||||
|
||||
describe("qqbot config", () => {
|
||||
it("accepts top-level speech overrides in the manifest schema", () => {
|
||||
|
||||
@@ -52,9 +52,9 @@ describe("signalMessageActions", () => {
|
||||
it("honors account-scoped reaction gates during discovery", () => {
|
||||
const cfg = createSignalAccountOverrideCfg();
|
||||
|
||||
expect(signalMessageActions.describeMessageTool?.({ cfg, accountId: "default" })?.actions).toEqual(
|
||||
["send"],
|
||||
);
|
||||
expect(
|
||||
signalMessageActions.describeMessageTool?.({ cfg, accountId: "default" })?.actions,
|
||||
).toEqual(["send"]);
|
||||
expect(signalMessageActions.describeMessageTool?.({ cfg, accountId: "work" })?.actions).toEqual(
|
||||
["send", "react"],
|
||||
);
|
||||
|
||||
@@ -140,7 +140,11 @@ export const signalDmPolicy = {
|
||||
getCurrent: (cfg: OpenClawConfig, accountId?: string) =>
|
||||
resolveSignalAccount({ cfg, accountId: accountId ?? resolveDefaultSignalAccountId(cfg) }).config
|
||||
.dmPolicy ?? "pairing",
|
||||
setPolicy: (cfg: OpenClawConfig, policy: "pairing" | "allowlist" | "open" | "disabled", accountId?: string) =>
|
||||
setPolicy: (
|
||||
cfg: OpenClawConfig,
|
||||
policy: "pairing" | "allowlist" | "open" | "disabled",
|
||||
accountId?: string,
|
||||
) =>
|
||||
patchChannelConfigForAccount({
|
||||
cfg,
|
||||
channel,
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
__resetSlackChannelTypeCacheForTest,
|
||||
resolveSlackChannelType,
|
||||
} from "./channel-type.js";
|
||||
import { __resetSlackChannelTypeCacheForTest, resolveSlackChannelType } from "./channel-type.js";
|
||||
|
||||
const conversationsInfoMock = vi.fn();
|
||||
|
||||
|
||||
@@ -8,9 +8,8 @@ export function listSlackMessageActions(
|
||||
cfg: OpenClawConfig,
|
||||
accountId?: string | null,
|
||||
): ChannelMessageActionName[] {
|
||||
const accounts = (accountId
|
||||
? [resolveSlackAccount({ cfg, accountId })]
|
||||
: listEnabledSlackAccounts(cfg)
|
||||
const accounts = (
|
||||
accountId ? [resolveSlackAccount({ cfg, accountId })] : listEnabledSlackAccounts(cfg)
|
||||
).filter((account) => account.enabled && account.botTokenSource !== "none");
|
||||
if (accounts.length === 0) {
|
||||
return [];
|
||||
|
||||
@@ -166,8 +166,7 @@ export function createSlackSetupWizardBase(handlers: {
|
||||
unconfiguredHint: "needs tokens",
|
||||
configuredScore: 2,
|
||||
unconfiguredScore: 1,
|
||||
resolveConfigured: ({ cfg, accountId }) =>
|
||||
inspectSlackAccount({ cfg, accountId }).configured,
|
||||
resolveConfigured: ({ cfg, accountId }) => inspectSlackAccount({ cfg, accountId }).configured,
|
||||
}),
|
||||
introNote: {
|
||||
title: "Slack socket mode tokens",
|
||||
|
||||
@@ -45,6 +45,7 @@ import {
|
||||
resolveDefaultAgentId,
|
||||
resolveDefaultModelForAgent,
|
||||
} from "./bot-handlers.agent.runtime.js";
|
||||
import { buildTelegramInboundDebounceKey } from "./bot-handlers.debounce-key.js";
|
||||
import {
|
||||
hasInboundMedia,
|
||||
hasReplyTargetMedia,
|
||||
@@ -101,7 +102,6 @@ import {
|
||||
resolveModelSelection,
|
||||
type ProviderInfo,
|
||||
} from "./model-buttons.js";
|
||||
import { buildTelegramInboundDebounceKey } from "./bot-handlers.debounce-key.js";
|
||||
import { buildInlineKeyboard } from "./send.js";
|
||||
|
||||
export const registerTelegramHandlers = ({
|
||||
|
||||
@@ -32,7 +32,9 @@ const loadTlonChannelRuntime = createLazyRuntimeModule(() => import("./channel.r
|
||||
|
||||
const tlonSetupWizardProxy = createTlonSetupWizardBase({
|
||||
resolveConfigured: async ({ cfg, accountId }) =>
|
||||
await (await loadTlonChannelRuntime()).tlonSetupWizard.status.resolveConfigured({
|
||||
await (
|
||||
await loadTlonChannelRuntime()
|
||||
).tlonSetupWizard.status.resolveConfigured({
|
||||
cfg,
|
||||
accountId,
|
||||
}),
|
||||
|
||||
@@ -135,7 +135,9 @@ export async function resolveTlonSetupConfigured(
|
||||
}
|
||||
const accountIds = listTlonAccountIds(cfg);
|
||||
return accountIds.length > 0
|
||||
? accountIds.some((resolvedAccountId) => isConfigured(resolveTlonAccount(cfg, resolvedAccountId)))
|
||||
? accountIds.some((resolvedAccountId) =>
|
||||
isConfigured(resolveTlonAccount(cfg, resolvedAccountId)),
|
||||
)
|
||||
: isConfigured(resolveTlonAccount(cfg, DEFAULT_ACCOUNT_ID));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, it, vi, beforeEach } from "vitest";
|
||||
import { twitchMessageActions } from "./actions.js";
|
||||
import { twitchOutbound } from "./outbound.js";
|
||||
import { resolveTwitchAccountContext } from "./config.js";
|
||||
import { twitchOutbound } from "./outbound.js";
|
||||
|
||||
vi.mock("./config.js", () => ({
|
||||
DEFAULT_ACCOUNT_ID: "default",
|
||||
|
||||
@@ -10,11 +10,7 @@ import {
|
||||
type OpenClawConfig,
|
||||
type WizardPrompter,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
getAccountConfig,
|
||||
resolveDefaultTwitchAccountId,
|
||||
} from "./config.js";
|
||||
import { DEFAULT_ACCOUNT_ID, getAccountConfig, resolveDefaultTwitchAccountId } from "./config.js";
|
||||
import type { TwitchAccountConfig, TwitchRole } from "./types.js";
|
||||
import { isAccountConfigured } from "./utils/twitch.js";
|
||||
|
||||
@@ -233,11 +229,15 @@ function setTwitchAccessControl(
|
||||
return cfg;
|
||||
}
|
||||
|
||||
return setTwitchAccount(cfg, {
|
||||
...account,
|
||||
allowedRoles,
|
||||
requireMention,
|
||||
}, accountId);
|
||||
return setTwitchAccount(
|
||||
cfg,
|
||||
{
|
||||
...account,
|
||||
allowedRoles,
|
||||
requireMention,
|
||||
},
|
||||
accountId,
|
||||
);
|
||||
}
|
||||
|
||||
function resolveTwitchGroupPolicy(cfg: OpenClawConfig): "open" | "allowlist" | "disabled" {
|
||||
@@ -266,7 +266,10 @@ const twitchDmPolicy: ChannelSetupDmPolicy = {
|
||||
policyKey: "channels.twitch.allowedRoles",
|
||||
allowFromKey: "channels.twitch.accounts.<default>.allowFrom",
|
||||
getCurrent: (cfg) => {
|
||||
const account = getAccountConfig(cfg as OpenClawConfig, resolveSetupAccountId(cfg as OpenClawConfig));
|
||||
const account = getAccountConfig(
|
||||
cfg as OpenClawConfig,
|
||||
resolveSetupAccountId(cfg as OpenClawConfig),
|
||||
);
|
||||
if (account?.allowedRoles?.includes("all")) {
|
||||
return "open";
|
||||
}
|
||||
@@ -296,10 +299,14 @@ const twitchDmPolicy: ChannelSetupDmPolicy = {
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
|
||||
return setTwitchAccount(cfg as OpenClawConfig, {
|
||||
...(account ?? undefined),
|
||||
allowFrom,
|
||||
}, accountId);
|
||||
return setTwitchAccount(
|
||||
cfg as OpenClawConfig,
|
||||
{
|
||||
...(account ?? undefined),
|
||||
allowFrom,
|
||||
},
|
||||
accountId,
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -309,11 +316,17 @@ const twitchGroupAccess: NonNullable<ChannelSetupWizard["groupAccess"]> = {
|
||||
skipAllowlistEntries: true,
|
||||
currentPolicy: ({ cfg }) => resolveTwitchGroupPolicy(cfg as OpenClawConfig),
|
||||
currentEntries: ({ cfg }) => {
|
||||
const account = getAccountConfig(cfg as OpenClawConfig, resolveSetupAccountId(cfg as OpenClawConfig));
|
||||
const account = getAccountConfig(
|
||||
cfg as OpenClawConfig,
|
||||
resolveSetupAccountId(cfg as OpenClawConfig),
|
||||
);
|
||||
return account?.allowFrom ?? [];
|
||||
},
|
||||
updatePrompt: ({ cfg }) => {
|
||||
const account = getAccountConfig(cfg as OpenClawConfig, resolveSetupAccountId(cfg as OpenClawConfig));
|
||||
const account = getAccountConfig(
|
||||
cfg as OpenClawConfig,
|
||||
resolveSetupAccountId(cfg as OpenClawConfig),
|
||||
);
|
||||
return Boolean(account?.allowedRoles?.length || account?.allowFrom?.length);
|
||||
},
|
||||
setPolicy: ({ cfg, policy }) => setTwitchGroupPolicy(cfg as OpenClawConfig, policy),
|
||||
@@ -324,9 +337,13 @@ const twitchGroupAccess: NonNullable<ChannelSetupWizard["groupAccess"]> = {
|
||||
export const twitchSetupAdapter: ChannelSetupAdapter = {
|
||||
resolveAccountId: ({ cfg }) => resolveSetupAccountId(cfg as OpenClawConfig),
|
||||
applyAccountConfig: ({ cfg, accountId }) =>
|
||||
setTwitchAccount(cfg, {
|
||||
enabled: true,
|
||||
}, accountId),
|
||||
setTwitchAccount(
|
||||
cfg,
|
||||
{
|
||||
enabled: true,
|
||||
},
|
||||
accountId,
|
||||
),
|
||||
};
|
||||
|
||||
export const twitchSetupWizard: ChannelSetupWizard = {
|
||||
@@ -339,7 +356,10 @@ export const twitchSetupWizard: ChannelSetupWizard = {
|
||||
configuredHint: "configured",
|
||||
unconfiguredHint: "needs setup",
|
||||
resolveConfigured: ({ cfg }) => {
|
||||
const account = getAccountConfig(cfg as OpenClawConfig, resolveSetupAccountId(cfg as OpenClawConfig));
|
||||
const account = getAccountConfig(
|
||||
cfg as OpenClawConfig,
|
||||
resolveSetupAccountId(cfg as OpenClawConfig),
|
||||
);
|
||||
return account ? isAccountConfigured(account) : false;
|
||||
},
|
||||
resolveStatusLines: ({ cfg }) => {
|
||||
@@ -382,15 +402,19 @@ export const twitchSetupWizard: ChannelSetupWizard = {
|
||||
const channelName = await promptChannelName(prompter, account);
|
||||
const { clientSecret, refreshToken } = await promptRefreshTokenSetup(prompter, account);
|
||||
|
||||
const cfgWithAccount = setTwitchAccount(cfg as OpenClawConfig, {
|
||||
username,
|
||||
accessToken: token,
|
||||
clientId,
|
||||
channel: channelName,
|
||||
clientSecret,
|
||||
refreshToken,
|
||||
enabled: true,
|
||||
}, accountId);
|
||||
const cfgWithAccount = setTwitchAccount(
|
||||
cfg as OpenClawConfig,
|
||||
{
|
||||
username,
|
||||
accessToken: token,
|
||||
clientId,
|
||||
channel: channelName,
|
||||
clientSecret,
|
||||
refreshToken,
|
||||
enabled: true,
|
||||
},
|
||||
accountId,
|
||||
);
|
||||
|
||||
const cfgWithAllowFrom =
|
||||
forceAllowFrom && twitchDmPolicy.promptAllowFrom
|
||||
|
||||
@@ -2,8 +2,8 @@ import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/routing";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { createQueuedWizardPrompter } from "../../../test/helpers/plugins/setup-wizard.js";
|
||||
import type { OpenClawConfig } from "./runtime-api.js";
|
||||
import { whatsappPlugin } from "./channel.js";
|
||||
import type { OpenClawConfig } from "./runtime-api.js";
|
||||
import { finalizeWhatsAppSetup } from "./setup-finalize.js";
|
||||
|
||||
const hoisted = vi.hoisted(() => ({
|
||||
|
||||
@@ -167,11 +167,7 @@ describe("resolveWhatsAppHeartbeatRecipients", () => {
|
||||
{ accountId: "work" },
|
||||
);
|
||||
|
||||
expect(readChannelAllowFromStoreSyncMock).toHaveBeenCalledWith(
|
||||
"whatsapp",
|
||||
process.env,
|
||||
"work",
|
||||
);
|
||||
expect(readChannelAllowFromStoreSyncMock).toHaveBeenCalledWith("whatsapp", process.env, "work");
|
||||
expect(result).toEqual({
|
||||
recipients: ["+15550000003", "+15550000002"],
|
||||
source: "allowFrom",
|
||||
@@ -198,11 +194,7 @@ describe("resolveWhatsAppHeartbeatRecipients", () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(readChannelAllowFromStoreSyncMock).toHaveBeenCalledWith(
|
||||
"whatsapp",
|
||||
process.env,
|
||||
"work",
|
||||
);
|
||||
expect(readChannelAllowFromStoreSyncMock).toHaveBeenCalledWith("whatsapp", process.env, "work");
|
||||
expect(result).toEqual({
|
||||
recipients: ["+15550000003", "+15550000002"],
|
||||
source: "allowFrom",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { resolveDefaultWhatsAppAccountId, resolveWhatsAppAccount } from "./accounts.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
loadSessionStore,
|
||||
@@ -7,7 +8,6 @@ import {
|
||||
resolveStorePath,
|
||||
type OpenClawConfig,
|
||||
} from "./heartbeat-recipients.runtime.js";
|
||||
import { resolveDefaultWhatsAppAccountId, resolveWhatsAppAccount } from "./accounts.js";
|
||||
|
||||
type HeartbeatRecipientsResult = { recipients: string[]; source: string };
|
||||
type HeartbeatRecipientsOpts = { to?: string; all?: boolean; accountId?: string };
|
||||
@@ -58,10 +58,11 @@ export function resolveWhatsAppHeartbeatRecipients(
|
||||
const sessionRecipients = getSessionRecipients(cfg);
|
||||
const resolvedAccountId =
|
||||
opts.accountId?.trim() || resolveDefaultWhatsAppAccountId(cfg) || DEFAULT_ACCOUNT_ID;
|
||||
const configuredAllowFrom =
|
||||
(resolveWhatsAppAccount({ cfg, accountId: resolvedAccountId }).allowFrom ?? [])
|
||||
.filter((value) => value !== "*")
|
||||
.map(normalizeE164);
|
||||
const configuredAllowFrom = (
|
||||
resolveWhatsAppAccount({ cfg, accountId: resolvedAccountId }).allowFrom ?? []
|
||||
)
|
||||
.filter((value) => value !== "*")
|
||||
.map(normalizeE164);
|
||||
const storeAllowFrom = readChannelAllowFromStoreSync(
|
||||
"whatsapp",
|
||||
process.env,
|
||||
|
||||
@@ -57,9 +57,8 @@ export async function sendMessageWhatsApp(
|
||||
cfg,
|
||||
accountId: options.accountId,
|
||||
});
|
||||
const { listener: active, accountId: resolvedAccountId } = requireActiveWebListener(
|
||||
effectiveAccountId,
|
||||
);
|
||||
const { listener: active, accountId: resolvedAccountId } =
|
||||
requireActiveWebListener(effectiveAccountId);
|
||||
const account = resolveWhatsAppAccount({
|
||||
cfg,
|
||||
accountId: resolvedAccountId ?? options.accountId,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { OpenClawConfig } from "./runtime-api.js";
|
||||
import { zaloMessageActions } from "./actions.js";
|
||||
import type { OpenClawConfig } from "./runtime-api.js";
|
||||
|
||||
describe("zaloMessageActions.describeMessageTool", () => {
|
||||
it("honors the selected Zalo account during discovery", () => {
|
||||
|
||||
@@ -82,7 +82,14 @@ function buildReplayEventCacheKey(
|
||||
): string {
|
||||
const chatId = update.message?.chat?.id ?? "";
|
||||
const senderId = update.message?.from?.id ?? "";
|
||||
return JSON.stringify([target.path, target.account.accountId, update.event_name, chatId, senderId, messageId]);
|
||||
return JSON.stringify([
|
||||
target.path,
|
||||
target.account.accountId,
|
||||
update.event_name,
|
||||
chatId,
|
||||
senderId,
|
||||
messageId,
|
||||
]);
|
||||
}
|
||||
|
||||
function isReplayEvent(target: ZaloWebhookTarget, update: ZaloUpdate, nowMs: number): boolean {
|
||||
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
normalizeAccountId,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import type { OpenClawConfig } from "./runtime-api.js";
|
||||
import { resolveDefaultZaloAccountId, resolveZaloAccount } from "./accounts.js";
|
||||
import type { OpenClawConfig } from "./runtime-api.js";
|
||||
|
||||
const channel = "zalo" as const;
|
||||
|
||||
|
||||
@@ -69,15 +69,11 @@ function setZalouserDmPolicy(
|
||||
resolvedAccountId,
|
||||
{
|
||||
dmPolicy: policy,
|
||||
...(policy === "open"
|
||||
? { allowFrom: addWildcardAllowFrom(resolved.config.allowFrom) }
|
||||
: {}),
|
||||
...(policy === "open" ? { allowFrom: addWildcardAllowFrom(resolved.config.allowFrom) } : {}),
|
||||
},
|
||||
{
|
||||
dmPolicy: policy,
|
||||
...(policy === "open"
|
||||
? { allowFrom: addWildcardAllowFrom(resolved.config.allowFrom) }
|
||||
: {}),
|
||||
...(policy === "open" ? { allowFrom: addWildcardAllowFrom(resolved.config.allowFrom) } : {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -318,9 +314,10 @@ export const zalouserSetupWizard: ChannelSetupWizard = {
|
||||
},
|
||||
resolveStatusLines: async ({ cfg, accountId, configured }) => {
|
||||
void cfg;
|
||||
const label = accountId && accountId !== DEFAULT_ACCOUNT_ID
|
||||
? `Zalo Personal (${accountId})`
|
||||
: "Zalo Personal";
|
||||
const label =
|
||||
accountId && accountId !== DEFAULT_ACCOUNT_ID
|
||||
? `Zalo Personal (${accountId})`
|
||||
: "Zalo Personal";
|
||||
return [`${label}: ${configured ? "logged in" : "needs QR login"}`];
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user