Skip to content

Commit a0e7e3c

Browse files
committed
refactor(discord): share plugin base config
1 parent b058077 commit a0e7e3c

File tree

3 files changed

+108
-80
lines changed

3 files changed

+108
-80
lines changed
Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,8 @@
1-
import {
2-
buildChannelConfigSchema,
3-
DiscordConfigSchema,
4-
getChatChannelMeta,
5-
type ChannelPlugin,
6-
} from "../../../src/plugin-sdk-internal/discord.js";
7-
import { type ResolvedDiscordAccount } from "./accounts.js";
8-
import { discordConfigAccessors, discordConfigBase, discordSetupWizard } from "./plugin-shared.js";
1+
import type { ChannelPlugin } from "openclaw/plugin-sdk/discord";
2+
import type { ResolvedDiscordAccount } from "./accounts.js";
93
import { discordSetupAdapter } from "./setup-core.js";
4+
import { createDiscordPluginBase } from "./shared.js";
105

11-
export const discordSetupPlugin: ChannelPlugin<ResolvedDiscordAccount> = {
12-
id: "discord",
13-
meta: {
14-
...getChatChannelMeta("discord"),
15-
},
16-
setupWizard: discordSetupWizard,
17-
capabilities: {
18-
chatTypes: ["direct", "channel", "thread"],
19-
polls: true,
20-
reactions: true,
21-
threads: true,
22-
media: true,
23-
nativeCommands: true,
24-
},
25-
streaming: {
26-
blockStreamingCoalesceDefaults: { minChars: 1500, idleMs: 1000 },
27-
},
28-
reload: { configPrefixes: ["channels.discord"] },
29-
configSchema: buildChannelConfigSchema(DiscordConfigSchema),
30-
config: {
31-
...discordConfigBase,
32-
isConfigured: (account) => Boolean(account.token?.trim()),
33-
describeAccount: (account) => ({
34-
accountId: account.accountId,
35-
name: account.name,
36-
enabled: account.enabled,
37-
configured: Boolean(account.token?.trim()),
38-
tokenSource: account.tokenSource,
39-
}),
40-
...discordConfigAccessors,
41-
},
6+
export const discordSetupPlugin: ChannelPlugin<ResolvedDiscordAccount> = createDiscordPluginBase({
427
setup: discordSetupAdapter,
43-
};
8+
});

extensions/discord/src/channel.ts

Lines changed: 9 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
import { Separator, TextDisplay } from "@buape/carbon";
2-
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
32
import {
43
buildAccountScopedAllowlistConfigEditor,
54
buildAccountScopedDmSecurityPolicy,
6-
collectOpenGroupPolicyConfiguredRouteWarnings,
75
collectOpenProviderGroupPolicyWarnings,
8-
} from "../../../src/plugin-sdk-internal/channel-config.js";
6+
collectOpenGroupPolicyConfiguredRouteWarnings,
7+
} from "openclaw/plugin-sdk/compat";
98
import {
109
buildAgentSessionKey,
1110
resolveThreadSessionKeys,
1211
type RoutePeer,
13-
} from "../../../src/plugin-sdk-internal/core.js";
12+
} from "openclaw/plugin-sdk/core";
1413
import {
1514
buildComputedAccountStatusSnapshot,
16-
buildChannelConfigSchema,
1715
buildTokenChannelStatusSummary,
1816
DEFAULT_ACCOUNT_ID,
19-
DiscordConfigSchema,
20-
getChatChannelMeta,
2117
listDiscordDirectoryGroupsFromConfig,
2218
listDiscordDirectoryPeersFromConfig,
2319
PAIRING_APPROVED_MESSAGE,
@@ -28,7 +24,8 @@ import {
2824
type ChannelMessageActionAdapter,
2925
type ChannelPlugin,
3026
type OpenClawConfig,
31-
} from "../../../src/plugin-sdk-internal/discord.js";
27+
} from "openclaw/plugin-sdk/discord";
28+
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
3229
import { normalizeMessageChannel } from "../../../src/utils/message-channel.js";
3330
import {
3431
listDiscordAccountIds,
@@ -45,12 +42,12 @@ import {
4542
normalizeDiscordMessagingTarget,
4643
normalizeDiscordOutboundTarget,
4744
} from "./normalize.js";
48-
import { discordConfigAccessors, discordConfigBase, discordSetupWizard } from "./plugin-shared.js";
4945
import type { DiscordProbe } from "./probe.js";
5046
import { resolveDiscordUserAllowlist } from "./resolve-users.js";
5147
import { getDiscordRuntime } from "./runtime.js";
5248
import { fetchChannelPermissionsDiscord } from "./send.js";
5349
import { discordSetupAdapter } from "./setup-core.js";
50+
import { createDiscordPluginBase, discordConfigAccessors } from "./shared.js";
5451
import { collectDiscordStatusIssues } from "./status-issues.js";
5552
import { parseDiscordTarget } from "./targets.js";
5653
import { DiscordUiContainer } from "./ui.js";
@@ -59,7 +56,6 @@ type DiscordSendFn = ReturnType<
5956
typeof getDiscordRuntime
6057
>["channel"]["discord"]["sendMessageDiscord"];
6158

62-
const meta = getChatChannelMeta("discord");
6359
const REQUIRED_DISCORD_PERMISSIONS = ["ViewChannel", "SendMessages"] as const;
6460

6561
function formatDiscordIntents(intents?: {
@@ -297,11 +293,9 @@ function resolveDiscordOutboundSessionRoute(params: {
297293
}
298294

299295
export const discordPlugin: ChannelPlugin<ResolvedDiscordAccount> = {
300-
id: "discord",
301-
meta: {
302-
...meta,
303-
},
304-
setupWizard: discordSetupWizard,
296+
...createDiscordPluginBase({
297+
setup: discordSetupAdapter,
298+
}),
305299
pairing: {
306300
idLabel: "discordUserId",
307301
normalizeAllowEntry: (entry) => entry.replace(/^(discord|user):/i, ""),
@@ -312,31 +306,6 @@ export const discordPlugin: ChannelPlugin<ResolvedDiscordAccount> = {
312306
);
313307
},
314308
},
315-
capabilities: {
316-
chatTypes: ["direct", "channel", "thread"],
317-
polls: true,
318-
reactions: true,
319-
threads: true,
320-
media: true,
321-
nativeCommands: true,
322-
},
323-
streaming: {
324-
blockStreamingCoalesceDefaults: { minChars: 1500, idleMs: 1000 },
325-
},
326-
reload: { configPrefixes: ["channels.discord"] },
327-
configSchema: buildChannelConfigSchema(DiscordConfigSchema),
328-
config: {
329-
...discordConfigBase,
330-
isConfigured: (account) => Boolean(account.token?.trim()),
331-
describeAccount: (account) => ({
332-
accountId: account.accountId,
333-
name: account.name,
334-
enabled: account.enabled,
335-
configured: Boolean(account.token?.trim()),
336-
tokenSource: account.tokenSource,
337-
}),
338-
...discordConfigAccessors,
339-
},
340309
allowlist: {
341310
supportsScope: ({ scope }) => scope === "dm",
342311
readConfig: ({ cfg, accountId }) =>

extensions/discord/src/shared.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { createScopedChannelConfigBase } from "openclaw/plugin-sdk/compat";
2+
import {
3+
createScopedAccountConfigAccessors,
4+
formatAllowFromLowercase,
5+
} from "openclaw/plugin-sdk/compat";
6+
import {
7+
buildChannelConfigSchema,
8+
DiscordConfigSchema,
9+
getChatChannelMeta,
10+
type ChannelPlugin,
11+
} from "openclaw/plugin-sdk/discord";
12+
import { inspectDiscordAccount } from "./account-inspect.js";
13+
import {
14+
listDiscordAccountIds,
15+
resolveDefaultDiscordAccountId,
16+
resolveDiscordAccount,
17+
type ResolvedDiscordAccount,
18+
} from "./accounts.js";
19+
import { createDiscordSetupWizardProxy } from "./setup-core.js";
20+
21+
export const DISCORD_CHANNEL = "discord" as const;
22+
23+
async function loadDiscordChannelRuntime() {
24+
return await import("./channel.runtime.js");
25+
}
26+
27+
export const discordSetupWizard = createDiscordSetupWizardProxy(async () => ({
28+
discordSetupWizard: (await loadDiscordChannelRuntime()).discordSetupWizard,
29+
}));
30+
31+
export const discordConfigAccessors = createScopedAccountConfigAccessors({
32+
resolveAccount: ({ cfg, accountId }) => resolveDiscordAccount({ cfg, accountId }),
33+
resolveAllowFrom: (account: ResolvedDiscordAccount) => account.config.dm?.allowFrom,
34+
formatAllowFrom: (allowFrom) => formatAllowFromLowercase({ allowFrom }),
35+
resolveDefaultTo: (account: ResolvedDiscordAccount) => account.config.defaultTo,
36+
});
37+
38+
export const discordConfigBase = createScopedChannelConfigBase<ResolvedDiscordAccount>({
39+
sectionKey: DISCORD_CHANNEL,
40+
listAccountIds: listDiscordAccountIds,
41+
resolveAccount: (cfg, accountId) => resolveDiscordAccount({ cfg, accountId }),
42+
inspectAccount: (cfg, accountId) => inspectDiscordAccount({ cfg, accountId }),
43+
defaultAccountId: resolveDefaultDiscordAccountId,
44+
clearBaseFields: ["token", "name"],
45+
});
46+
47+
export function createDiscordPluginBase(params: {
48+
setup: NonNullable<ChannelPlugin<ResolvedDiscordAccount>["setup"]>;
49+
}): Pick<
50+
ChannelPlugin<ResolvedDiscordAccount>,
51+
| "id"
52+
| "meta"
53+
| "setupWizard"
54+
| "capabilities"
55+
| "streaming"
56+
| "reload"
57+
| "configSchema"
58+
| "config"
59+
| "setup"
60+
> {
61+
return {
62+
id: DISCORD_CHANNEL,
63+
meta: {
64+
...getChatChannelMeta(DISCORD_CHANNEL),
65+
},
66+
setupWizard: discordSetupWizard,
67+
capabilities: {
68+
chatTypes: ["direct", "channel", "thread"],
69+
polls: true,
70+
reactions: true,
71+
threads: true,
72+
media: true,
73+
nativeCommands: true,
74+
},
75+
streaming: {
76+
blockStreamingCoalesceDefaults: { minChars: 1500, idleMs: 1000 },
77+
},
78+
reload: { configPrefixes: ["channels.discord"] },
79+
configSchema: buildChannelConfigSchema(DiscordConfigSchema),
80+
config: {
81+
...discordConfigBase,
82+
isConfigured: (account) => Boolean(account.token?.trim()),
83+
describeAccount: (account) => ({
84+
accountId: account.accountId,
85+
name: account.name,
86+
enabled: account.enabled,
87+
configured: Boolean(account.token?.trim()),
88+
tokenSource: account.tokenSource,
89+
}),
90+
...discordConfigAccessors,
91+
},
92+
setup: params.setup,
93+
};
94+
}

0 commit comments

Comments
 (0)