mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 00:13:28 +00:00
refactor!: rename chat providers to channels
This commit is contained in:
203
src/channels/plugins/onboarding/discord.ts
Normal file
203
src/channels/plugins/onboarding/discord.ts
Normal file
@@ -0,0 +1,203 @@
|
||||
import type { ClawdbotConfig } from "../../../config/config.js";
|
||||
import type { DmPolicy } from "../../../config/types.js";
|
||||
import {
|
||||
listDiscordAccountIds,
|
||||
resolveDefaultDiscordAccountId,
|
||||
resolveDiscordAccount,
|
||||
} from "../../../discord/accounts.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
normalizeAccountId,
|
||||
} from "../../../routing/session-key.js";
|
||||
import { formatDocsLink } from "../../../terminal/links.js";
|
||||
import type { WizardPrompter } from "../../../wizard/prompts.js";
|
||||
import type {
|
||||
ChannelOnboardingAdapter,
|
||||
ChannelOnboardingDmPolicy,
|
||||
} from "../onboarding-types.js";
|
||||
import { addWildcardAllowFrom, promptAccountId } from "./helpers.js";
|
||||
|
||||
const channel = "discord" as const;
|
||||
|
||||
function setDiscordDmPolicy(cfg: ClawdbotConfig, dmPolicy: DmPolicy) {
|
||||
const allowFrom =
|
||||
dmPolicy === "open"
|
||||
? addWildcardAllowFrom(cfg.channels?.discord?.dm?.allowFrom)
|
||||
: undefined;
|
||||
return {
|
||||
...cfg,
|
||||
channels: {
|
||||
...cfg.channels,
|
||||
discord: {
|
||||
...cfg.channels?.discord,
|
||||
dm: {
|
||||
...cfg.channels?.discord?.dm,
|
||||
enabled: cfg.channels?.discord?.dm?.enabled ?? true,
|
||||
policy: dmPolicy,
|
||||
...(allowFrom ? { allowFrom } : {}),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function noteDiscordTokenHelp(prompter: WizardPrompter): Promise<void> {
|
||||
await prompter.note(
|
||||
[
|
||||
"1) Discord Developer Portal → Applications → New Application",
|
||||
"2) Bot → Add Bot → Reset Token → copy token",
|
||||
"3) OAuth2 → URL Generator → scope 'bot' → invite to your server",
|
||||
"Tip: enable Message Content Intent if you need message text.",
|
||||
`Docs: ${formatDocsLink("/discord", "discord")}`,
|
||||
].join("\n"),
|
||||
"Discord bot token",
|
||||
);
|
||||
}
|
||||
|
||||
const dmPolicy: ChannelOnboardingDmPolicy = {
|
||||
label: "Discord",
|
||||
channel,
|
||||
policyKey: "channels.discord.dm.policy",
|
||||
allowFromKey: "channels.discord.dm.allowFrom",
|
||||
getCurrent: (cfg) => cfg.channels?.discord?.dm?.policy ?? "pairing",
|
||||
setPolicy: (cfg, policy) => setDiscordDmPolicy(cfg, policy),
|
||||
};
|
||||
|
||||
export const discordOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
channel,
|
||||
getStatus: async ({ cfg }) => {
|
||||
const configured = listDiscordAccountIds(cfg).some((accountId) =>
|
||||
Boolean(resolveDiscordAccount({ cfg, accountId }).token),
|
||||
);
|
||||
return {
|
||||
channel,
|
||||
configured,
|
||||
statusLines: [`Discord: ${configured ? "configured" : "needs token"}`],
|
||||
selectionHint: configured ? "configured" : "needs token",
|
||||
quickstartScore: configured ? 2 : 1,
|
||||
};
|
||||
},
|
||||
configure: async ({
|
||||
cfg,
|
||||
prompter,
|
||||
accountOverrides,
|
||||
shouldPromptAccountIds,
|
||||
}) => {
|
||||
const discordOverride = accountOverrides.discord?.trim();
|
||||
const defaultDiscordAccountId = resolveDefaultDiscordAccountId(cfg);
|
||||
let discordAccountId = discordOverride
|
||||
? normalizeAccountId(discordOverride)
|
||||
: defaultDiscordAccountId;
|
||||
if (shouldPromptAccountIds && !discordOverride) {
|
||||
discordAccountId = await promptAccountId({
|
||||
cfg,
|
||||
prompter,
|
||||
label: "Discord",
|
||||
currentId: discordAccountId,
|
||||
listAccountIds: listDiscordAccountIds,
|
||||
defaultAccountId: defaultDiscordAccountId,
|
||||
});
|
||||
}
|
||||
|
||||
let next = cfg;
|
||||
const resolvedAccount = resolveDiscordAccount({
|
||||
cfg: next,
|
||||
accountId: discordAccountId,
|
||||
});
|
||||
const accountConfigured = Boolean(resolvedAccount.token);
|
||||
const allowEnv = discordAccountId === DEFAULT_ACCOUNT_ID;
|
||||
const canUseEnv =
|
||||
allowEnv && Boolean(process.env.DISCORD_BOT_TOKEN?.trim());
|
||||
const hasConfigToken = Boolean(resolvedAccount.config.token);
|
||||
|
||||
let token: string | null = null;
|
||||
if (!accountConfigured) {
|
||||
await noteDiscordTokenHelp(prompter);
|
||||
}
|
||||
if (canUseEnv && !resolvedAccount.config.token) {
|
||||
const keepEnv = await prompter.confirm({
|
||||
message: "DISCORD_BOT_TOKEN detected. Use env var?",
|
||||
initialValue: true,
|
||||
});
|
||||
if (keepEnv) {
|
||||
next = {
|
||||
...next,
|
||||
channels: {
|
||||
...next.channels,
|
||||
discord: { ...next.channels?.discord, enabled: true },
|
||||
},
|
||||
};
|
||||
} else {
|
||||
token = String(
|
||||
await prompter.text({
|
||||
message: "Enter Discord bot token",
|
||||
validate: (value) => (value?.trim() ? undefined : "Required"),
|
||||
}),
|
||||
).trim();
|
||||
}
|
||||
} else if (hasConfigToken) {
|
||||
const keep = await prompter.confirm({
|
||||
message: "Discord token already configured. Keep it?",
|
||||
initialValue: true,
|
||||
});
|
||||
if (!keep) {
|
||||
token = String(
|
||||
await prompter.text({
|
||||
message: "Enter Discord bot token",
|
||||
validate: (value) => (value?.trim() ? undefined : "Required"),
|
||||
}),
|
||||
).trim();
|
||||
}
|
||||
} else {
|
||||
token = String(
|
||||
await prompter.text({
|
||||
message: "Enter Discord bot token",
|
||||
validate: (value) => (value?.trim() ? undefined : "Required"),
|
||||
}),
|
||||
).trim();
|
||||
}
|
||||
|
||||
if (token) {
|
||||
if (discordAccountId === DEFAULT_ACCOUNT_ID) {
|
||||
next = {
|
||||
...next,
|
||||
channels: {
|
||||
...next.channels,
|
||||
discord: { ...next.channels?.discord, enabled: true, token },
|
||||
},
|
||||
};
|
||||
} else {
|
||||
next = {
|
||||
...next,
|
||||
channels: {
|
||||
...next.channels,
|
||||
discord: {
|
||||
...next.channels?.discord,
|
||||
enabled: true,
|
||||
accounts: {
|
||||
...next.channels?.discord?.accounts,
|
||||
[discordAccountId]: {
|
||||
...next.channels?.discord?.accounts?.[discordAccountId],
|
||||
enabled:
|
||||
next.channels?.discord?.accounts?.[discordAccountId]
|
||||
?.enabled ?? true,
|
||||
token,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return { cfg: next, accountId: discordAccountId };
|
||||
},
|
||||
dmPolicy,
|
||||
disable: (cfg) => ({
|
||||
...cfg,
|
||||
channels: {
|
||||
...cfg.channels,
|
||||
discord: { ...cfg.channels?.discord, enabled: false },
|
||||
},
|
||||
}),
|
||||
};
|
||||
Reference in New Issue
Block a user