openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
172 lines (171 loc) • 7.92 kB
JavaScript
import { n as normalizeAccountId } from "./account-id-Df9e41E6.js";
import { l as createScopedDmSecurityResolver, s as createScopedChannelConfigAdapter, t as adaptScopedAccountAccessor } from "./channel-config-helpers-lj5quus3.js";
import { n as describeAccountSnapshot } from "./account-helpers-pcH3lGFY.js";
import { r as createEnvPatchedAccountSetupAdapter } from "./setup-helpers-DO5nSeNy.js";
import { t as formatAllowFromLowercase } from "./allow-from-DCaV3hzI.js";
import { S as createOpenProviderConfiguredRouteWarningCollector } from "./channel-policy-CIW58SA5.js";
import "./setup-runtime-BvLK-H0G.js";
import { a as resolveConfiguredFromCredentialStatuses } from "./account-snapshot-fields-VbzFdu8Y.js";
import { t as inspectDiscordAccount } from "./account-inspect-DVZXXjia.js";
import { a as mergeDiscordAccountConfig, c as resolveDiscordAccountAllowFrom, d as resolveDiscordAccountDmPolicy, n as isDiscordAccountEnabledForRuntime, o as resolveDefaultDiscordAccountId, r as listDiscordAccountIds, s as resolveDiscordAccount, u as resolveDiscordAccountDisabledReason } from "./accounts-BI_6uJlY.js";
import { t as getChatChannelMeta } from "./channel-api-_pvHxxap.js";
import { t as DiscordChannelConfigSchema } from "./config-schema-CQVoj8HM.js";
import { n as normalizeCompatibilityConfig } from "./doctor-contract-BaYPW6iW.js";
import { t as DISCORD_LEGACY_CONFIG_RULES } from "./doctor-shared-cypKrFwC.js";
import { n as secretTargetRegistryEntries, t as collectRuntimeConfigAssignments } from "./secret-config-contract-CUf3v3AJ.js";
import { n as unsupportedSecretRefSurfacePatterns, t as collectUnsupportedSecretRefConfigCandidates } from "./security-contract-BMuakUcR.js";
import { t as deriveLegacySessionChatType } from "./session-contract-BO5tlIdl.js";
//#region extensions/discord/src/security.ts
const resolveDiscordDmPolicy = createScopedDmSecurityResolver({
channelKey: "discord",
resolvePolicy: (account) => account.config.dmPolicy,
resolveAllowFrom: (account) => account.config.allowFrom,
resolveAccess: ({ cfg, account }) => ({
dmPolicy: resolveDiscordAccountDmPolicy({
cfg,
accountId: account.accountId
}),
allowFrom: resolveDiscordAccountAllowFrom({
cfg,
accountId: account.accountId
})
}),
policyPathSuffix: "dmPolicy",
normalizeEntry: (raw) => raw.trim().replace(/^(discord|user):/i, "").replace(/^<@!?(\d+)>$/, "$1")
});
const collectDiscordSecurityWarnings = createOpenProviderConfiguredRouteWarningCollector({
providerConfigPresent: (cfg) => cfg.channels?.discord !== void 0,
resolveGroupPolicy: (account) => account.config.groupPolicy,
resolveRouteAllowlistConfigured: (account) => Object.keys(account.config.guilds ?? {}).length > 0,
configureRouteAllowlist: {
surface: "Discord guilds",
openScope: "any channel not explicitly denied",
groupPolicyPath: "channels.discord.groupPolicy",
routeAllowlistPath: "channels.discord.guilds.<id>.channels"
},
missingRouteAllowlist: {
surface: "Discord guilds",
openBehavior: "with no guild/channel allowlist; any channel can trigger (mention-gated)",
remediation: "Set channels.discord.groupPolicy=\"allowlist\" and configure channels.discord.guilds.<id>.channels"
}
});
let discordSecurityAuditModulePromise;
async function loadDiscordSecurityAuditModule() {
discordSecurityAuditModulePromise ??= import("./security-audit.runtime.js");
return await discordSecurityAuditModulePromise;
}
const discordSecurityAdapter = {
resolveDmPolicy: resolveDiscordDmPolicy,
collectWarnings: collectDiscordSecurityWarnings,
collectAuditFindings: async (params) => (await loadDiscordSecurityAuditModule()).collectDiscordSecurityAuditFindings(params)
};
const discordSetupAdapter = createEnvPatchedAccountSetupAdapter({
channelKey: "discord",
defaultAccountOnlyEnvError: "DISCORD_BOT_TOKEN can only be used for the default account.",
missingCredentialError: "Discord requires token (or --use-env).",
hasCredentials: (input) => Boolean(input.token),
buildPatch: (input) => input.token ? { token: input.token } : {}
});
//#endregion
//#region extensions/discord/src/shared.ts
const DISCORD_CHANNEL = "discord";
let discordDoctorModulePromise;
async function loadDiscordDoctorModule() {
discordDoctorModulePromise ??= import("./doctor-Bn24tl7s.js");
return await discordDoctorModulePromise;
}
const discordDoctor = {
dmAllowFromMode: "topOnly",
groupModel: "route",
groupAllowFromFallbackToAllowFrom: false,
warnOnEmptyGroupSenderAllowlist: false,
legacyConfigRules: DISCORD_LEGACY_CONFIG_RULES,
normalizeCompatibilityConfig,
collectPreviewWarnings: async (params) => (await loadDiscordDoctorModule()).discordDoctor.collectPreviewWarnings?.(params) ?? [],
collectMutableAllowlistWarnings: async (params) => (await loadDiscordDoctorModule()).discordDoctor.collectMutableAllowlistWarnings?.(params) ?? [],
repairConfig: async (params) => (await loadDiscordDoctorModule()).discordDoctor.repairConfig?.(params) ?? {
config: params.cfg,
changes: []
}
};
function resolveDiscordConfigAccessorAccount(params) {
const accountId = normalizeAccountId(params.accountId ?? resolveDefaultDiscordAccountId(params.cfg));
const config = mergeDiscordAccountConfig(params.cfg, accountId);
return {
allowFrom: resolveDiscordAccountAllowFrom({
cfg: params.cfg,
accountId
}),
defaultTo: config.defaultTo
};
}
const discordConfigAdapter = createScopedChannelConfigAdapter({
sectionKey: DISCORD_CHANNEL,
listAccountIds: listDiscordAccountIds,
resolveAccount: adaptScopedAccountAccessor(resolveDiscordAccount),
resolveAccessorAccount: resolveDiscordConfigAccessorAccount,
inspectAccount: adaptScopedAccountAccessor(inspectDiscordAccount),
defaultAccountId: resolveDefaultDiscordAccountId,
clearBaseFields: ["token", "name"],
resolveAllowFrom: (account) => account.allowFrom,
formatAllowFrom: (allowFrom) => formatAllowFromLowercase({ allowFrom }),
resolveDefaultTo: (account) => account.defaultTo
});
function createDiscordPluginBase(params) {
return {
id: DISCORD_CHANNEL,
...params.setupWizard ? { setupWizard: params.setupWizard } : {},
meta: { ...getChatChannelMeta(DISCORD_CHANNEL) },
capabilities: {
chatTypes: [
"direct",
"channel",
"thread"
],
polls: true,
reactions: true,
threads: true,
media: true,
tts: { voice: { synthesisTarget: "voice-note" } },
nativeCommands: true
},
commands: {
nativeCommandsAutoEnabled: true,
nativeSkillsAutoEnabled: true,
resolveNativeCommandName: ({ commandKey, defaultName }) => commandKey === "tts" ? "voice" : defaultName
},
doctor: discordDoctor,
streaming: { blockStreamingCoalesceDefaults: {
minChars: 1500,
idleMs: 1e3
} },
reload: { configPrefixes: ["channels.discord"] },
configSchema: DiscordChannelConfigSchema,
config: {
...discordConfigAdapter,
hasConfiguredState: ({ env }) => typeof env?.DISCORD_BOT_TOKEN === "string" && env.DISCORD_BOT_TOKEN.trim().length > 0,
isEnabled: (account, cfg) => isDiscordAccountEnabledForRuntime(account, cfg),
disabledReason: (account, cfg) => resolveDiscordAccountDisabledReason(account, cfg),
isConfigured: (account) => resolveConfiguredFromCredentialStatuses(account) ?? Boolean(account.token?.trim()),
describeAccount: (account) => describeAccountSnapshot({
account,
configured: resolveConfiguredFromCredentialStatuses(account) ?? Boolean(account.token?.trim()),
extra: {
tokenSource: account.tokenSource,
tokenStatus: account.tokenStatus
}
})
},
messaging: { deriveLegacySessionChatType },
security: discordSecurityAdapter,
secrets: {
secretTargetRegistryEntries,
unsupportedSecretRefSurfacePatterns,
collectUnsupportedSecretRefConfigCandidates,
collectRuntimeConfigAssignments
},
setup: params.setup
};
}
//#endregion
export { discordSecurityAdapter as i, discordConfigAdapter as n, discordSetupAdapter as r, createDiscordPluginBase as t };