mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 18:10:45 +00:00
refactor(discord): share native interaction channel context
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
Button,
|
||||
ChannelType,
|
||||
Container,
|
||||
Row,
|
||||
StringSelectMenu,
|
||||
@@ -34,12 +33,7 @@ import {
|
||||
normalizeOptionalString,
|
||||
withTimeout,
|
||||
} from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
resolveDiscordChannelNameSafe,
|
||||
resolveDiscordChannelParentIdSafe,
|
||||
} from "./channel-access.js";
|
||||
import { resolveDiscordSlashCommandConfig } from "./commands.js";
|
||||
import { resolveDiscordChannelInfo } from "./message-utils.js";
|
||||
import {
|
||||
readDiscordModelPickerRecentModels,
|
||||
recordDiscordModelPickerRecentModel,
|
||||
@@ -56,8 +50,8 @@ import {
|
||||
type DiscordModelPickerCommandContext,
|
||||
} from "./model-picker.js";
|
||||
import { resolveDiscordNativeInteractionRouteState } from "./native-command-route.js";
|
||||
import { resolveDiscordNativeInteractionChannelContext } from "./native-interaction-channel-context.js";
|
||||
import type { ThreadBindingManager } from "./thread-bindings.js";
|
||||
import { resolveDiscordThreadParentInfo } from "./threading.js";
|
||||
|
||||
type DiscordConfig = NonNullable<OpenClawConfig["channels"]>["discord"];
|
||||
|
||||
@@ -241,33 +235,16 @@ async function resolveDiscordModelPickerRouteState(params: {
|
||||
enforceConfiguredBindingReadiness?: boolean;
|
||||
}) {
|
||||
const { interaction, cfg, accountId } = params;
|
||||
const channel = interaction.channel;
|
||||
const channelType = channel?.type;
|
||||
const isDirectMessage = channelType === ChannelType.DM;
|
||||
const isGroupDm = channelType === ChannelType.GroupDM;
|
||||
const isThreadChannel =
|
||||
channelType === ChannelType.PublicThread ||
|
||||
channelType === ChannelType.PrivateThread ||
|
||||
channelType === ChannelType.AnnouncementThread;
|
||||
const rawChannelId = channel?.id ?? "unknown";
|
||||
const { isDirectMessage, isGroupDm, isThreadChannel, rawChannelId, threadParentId } =
|
||||
await resolveDiscordNativeInteractionChannelContext({
|
||||
channel: interaction.channel,
|
||||
client: interaction.client,
|
||||
hasGuild: Boolean(interaction.guild),
|
||||
channelIdFallback: "unknown",
|
||||
});
|
||||
const memberRoleIds = Array.isArray(interaction.rawData.member?.roles)
|
||||
? interaction.rawData.member.roles.map((roleId: string) => roleId)
|
||||
: [];
|
||||
let threadParentId: string | undefined;
|
||||
if (interaction.guild && channel && isThreadChannel && rawChannelId) {
|
||||
const channelInfo = await resolveDiscordChannelInfo(interaction.client, rawChannelId);
|
||||
const parentInfo = await resolveDiscordThreadParentInfo({
|
||||
client: interaction.client,
|
||||
threadChannel: {
|
||||
id: rawChannelId,
|
||||
name: resolveDiscordChannelNameSafe(channel),
|
||||
parentId: resolveDiscordChannelParentIdSafe(channel),
|
||||
parent: undefined,
|
||||
},
|
||||
channelInfo,
|
||||
});
|
||||
threadParentId = parentInfo.id;
|
||||
}
|
||||
|
||||
const threadBinding = isThreadChannel
|
||||
? params.threadBindings.getByThreadId(rawChannelId)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
Button,
|
||||
ChannelType,
|
||||
Command,
|
||||
StringSelectMenu,
|
||||
type AutocompleteInteraction,
|
||||
@@ -56,7 +55,6 @@ import { resolveDiscordMaxLinesPerMessage } from "../accounts.js";
|
||||
import { chunkDiscordTextWithMode } from "../chunk.js";
|
||||
import {
|
||||
normalizeDiscordAllowList,
|
||||
normalizeDiscordSlug,
|
||||
resolveDiscordAllowListMatch,
|
||||
resolveDiscordChannelConfigWithFallback,
|
||||
resolveDiscordChannelPolicyCommandAuthorizer,
|
||||
@@ -65,14 +63,9 @@ import {
|
||||
resolveDiscordOwnerAccess,
|
||||
resolveGroupDmAllow,
|
||||
} from "./allow-list.js";
|
||||
import {
|
||||
resolveDiscordChannelNameSafe,
|
||||
resolveDiscordChannelParentIdSafe,
|
||||
resolveDiscordChannelTopicSafe,
|
||||
} from "./channel-access.js";
|
||||
import { resolveDiscordChannelTopicSafe } from "./channel-access.js";
|
||||
import { resolveDiscordDmCommandAccess } from "./dm-command-auth.js";
|
||||
import { handleDiscordDmCommandDecision } from "./dm-command-decision.js";
|
||||
import { resolveDiscordChannelInfo } from "./message-utils.js";
|
||||
import { buildDiscordNativeCommandContext } from "./native-command-context.js";
|
||||
import { resolveDiscordNativeInteractionRouteState } from "./native-command-route.js";
|
||||
import {
|
||||
@@ -86,9 +79,9 @@ import {
|
||||
type DiscordCommandArgContext,
|
||||
type DiscordModelPickerContext,
|
||||
} from "./native-command-ui.js";
|
||||
import { resolveDiscordNativeInteractionChannelContext } from "./native-interaction-channel-context.js";
|
||||
import { resolveDiscordSenderIdentity } from "./sender-identity.js";
|
||||
import type { ThreadBindingManager } from "./thread-bindings.js";
|
||||
import { resolveDiscordThreadParentInfo } from "./threading.js";
|
||||
|
||||
type DiscordConfig = NonNullable<OpenClawConfig["channels"]>["discord"];
|
||||
type DiscordCommandArgs = {
|
||||
@@ -412,17 +405,22 @@ async function resolveDiscordNativeAutocompleteAuthorized(params: {
|
||||
return false;
|
||||
}
|
||||
const sender = resolveDiscordSenderIdentity({ author: user, pluralkitInfo: null });
|
||||
const channel = interaction.channel;
|
||||
const channelType = channel?.type;
|
||||
const isDirectMessage = channelType === ChannelType.DM;
|
||||
const isGroupDm = channelType === ChannelType.GroupDM;
|
||||
const isThreadChannel =
|
||||
channelType === ChannelType.PublicThread ||
|
||||
channelType === ChannelType.PrivateThread ||
|
||||
channelType === ChannelType.AnnouncementThread;
|
||||
const channelName = resolveDiscordChannelNameSafe(channel);
|
||||
const channelSlug = channelName ? normalizeDiscordSlug(channelName) : "";
|
||||
const rawChannelId = channel?.id ?? "";
|
||||
const {
|
||||
isDirectMessage,
|
||||
isGroupDm,
|
||||
isThreadChannel,
|
||||
channelName,
|
||||
channelSlug,
|
||||
rawChannelId,
|
||||
threadParentId,
|
||||
threadParentName,
|
||||
threadParentSlug,
|
||||
} = await resolveDiscordNativeInteractionChannelContext({
|
||||
channel: interaction.channel,
|
||||
client: interaction.client,
|
||||
hasGuild: Boolean(interaction.guild),
|
||||
channelIdFallback: "",
|
||||
});
|
||||
const memberRoleIds = Array.isArray(interaction.rawData.member?.roles)
|
||||
? interaction.rawData.member.roles.map((roleId: string) => roleId)
|
||||
: [];
|
||||
@@ -460,25 +458,6 @@ async function resolveDiscordNativeAutocompleteAuthorized(params: {
|
||||
guildId: interaction.guild?.id ?? undefined,
|
||||
guildEntries: discordConfig?.guilds,
|
||||
});
|
||||
let threadParentId: string | undefined;
|
||||
let threadParentName: string | undefined;
|
||||
let threadParentSlug = "";
|
||||
if (interaction.guild && channel && isThreadChannel && rawChannelId) {
|
||||
const channelInfo = await resolveDiscordChannelInfo(interaction.client, rawChannelId);
|
||||
const parentInfo = await resolveDiscordThreadParentInfo({
|
||||
client: interaction.client,
|
||||
threadChannel: {
|
||||
id: rawChannelId,
|
||||
name: channelName,
|
||||
parentId: resolveDiscordChannelParentIdSafe(channel),
|
||||
parent: undefined,
|
||||
},
|
||||
channelInfo,
|
||||
});
|
||||
threadParentId = parentInfo.id;
|
||||
threadParentName = parentInfo.name;
|
||||
threadParentSlug = threadParentName ? normalizeDiscordSlug(threadParentName) : "";
|
||||
}
|
||||
const channelConfig = interaction.guild
|
||||
? resolveDiscordChannelConfigWithFallback({
|
||||
guildInfo,
|
||||
@@ -806,16 +785,22 @@ async function dispatchDiscordCommandInteraction(params: {
|
||||
}
|
||||
const sender = resolveDiscordSenderIdentity({ author: user, pluralkitInfo: null });
|
||||
const channel = interaction.channel;
|
||||
const channelType = channel?.type;
|
||||
const isDirectMessage = channelType === ChannelType.DM;
|
||||
const isGroupDm = channelType === ChannelType.GroupDM;
|
||||
const isThreadChannel =
|
||||
channelType === ChannelType.PublicThread ||
|
||||
channelType === ChannelType.PrivateThread ||
|
||||
channelType === ChannelType.AnnouncementThread;
|
||||
const channelName = resolveDiscordChannelNameSafe(channel);
|
||||
const channelSlug = channelName ? normalizeDiscordSlug(channelName) : "";
|
||||
const rawChannelId = channel?.id ?? "";
|
||||
const {
|
||||
isDirectMessage,
|
||||
isGroupDm,
|
||||
isThreadChannel,
|
||||
channelName,
|
||||
channelSlug,
|
||||
rawChannelId,
|
||||
threadParentId,
|
||||
threadParentName,
|
||||
threadParentSlug,
|
||||
} = await resolveDiscordNativeInteractionChannelContext({
|
||||
channel,
|
||||
client: interaction.client,
|
||||
hasGuild: Boolean(interaction.guild),
|
||||
channelIdFallback: "",
|
||||
});
|
||||
const memberRoleIds = Array.isArray(interaction.rawData.member?.roles)
|
||||
? interaction.rawData.member.roles.map((roleId: string) => roleId)
|
||||
: [];
|
||||
@@ -852,26 +837,6 @@ async function dispatchDiscordCommandInteraction(params: {
|
||||
guildId: interaction.guild?.id ?? undefined,
|
||||
guildEntries: discordConfig?.guilds,
|
||||
});
|
||||
let threadParentId: string | undefined;
|
||||
let threadParentName: string | undefined;
|
||||
let threadParentSlug = "";
|
||||
if (interaction.guild && channel && isThreadChannel && rawChannelId) {
|
||||
// Threads inherit parent channel config unless explicitly overridden.
|
||||
const channelInfo = await resolveDiscordChannelInfo(interaction.client, rawChannelId);
|
||||
const parentInfo = await resolveDiscordThreadParentInfo({
|
||||
client: interaction.client,
|
||||
threadChannel: {
|
||||
id: rawChannelId,
|
||||
name: channelName,
|
||||
parentId: resolveDiscordChannelParentIdSafe(channel),
|
||||
parent: undefined,
|
||||
},
|
||||
channelInfo,
|
||||
});
|
||||
threadParentId = parentInfo.id;
|
||||
threadParentName = parentInfo.name;
|
||||
threadParentSlug = threadParentName ? normalizeDiscordSlug(threadParentName) : "";
|
||||
}
|
||||
const channelConfig = interaction.guild
|
||||
? resolveDiscordChannelConfigWithFallback({
|
||||
guildInfo,
|
||||
@@ -1070,10 +1035,6 @@ async function dispatchDiscordCommandInteraction(params: {
|
||||
return;
|
||||
}
|
||||
const channelId = rawChannelId || "unknown";
|
||||
const isThreadChannel =
|
||||
interaction.channel?.type === ChannelType.PublicThread ||
|
||||
interaction.channel?.type === ChannelType.PrivateThread ||
|
||||
interaction.channel?.type === ChannelType.AnnouncementThread;
|
||||
const messageThreadId = !isDirectMessage && isThreadChannel ? channelId : undefined;
|
||||
const pluginThreadParentId = !isDirectMessage && isThreadChannel ? threadParentId : undefined;
|
||||
const { effectiveRoute } = await getNativeRouteState();
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import { ChannelType, type Client } from "@buape/carbon";
|
||||
import { normalizeDiscordSlug } from "./allow-list.js";
|
||||
import {
|
||||
resolveDiscordChannelNameSafe,
|
||||
resolveDiscordChannelParentIdSafe,
|
||||
} from "./channel-access.js";
|
||||
import { resolveDiscordChannelInfo } from "./message-utils.js";
|
||||
import { resolveDiscordThreadParentInfo } from "./threading.js";
|
||||
|
||||
type DiscordInteractionChannel = {
|
||||
id?: string;
|
||||
type?: ChannelType;
|
||||
};
|
||||
|
||||
export type DiscordNativeInteractionChannelContext = {
|
||||
channelType?: ChannelType;
|
||||
isDirectMessage: boolean;
|
||||
isGroupDm: boolean;
|
||||
isThreadChannel: boolean;
|
||||
channelName?: string;
|
||||
channelSlug: string;
|
||||
rawChannelId: string;
|
||||
threadParentId?: string;
|
||||
threadParentName?: string;
|
||||
threadParentSlug: string;
|
||||
};
|
||||
|
||||
export async function resolveDiscordNativeInteractionChannelContext(params: {
|
||||
channel: DiscordInteractionChannel | null | undefined;
|
||||
client: Client;
|
||||
hasGuild: boolean;
|
||||
channelIdFallback: string;
|
||||
}): Promise<DiscordNativeInteractionChannelContext> {
|
||||
const { channel } = params;
|
||||
const channelType = channel?.type;
|
||||
const isDirectMessage = channelType === ChannelType.DM;
|
||||
const isGroupDm = channelType === ChannelType.GroupDM;
|
||||
const isThreadChannel =
|
||||
channelType === ChannelType.PublicThread ||
|
||||
channelType === ChannelType.PrivateThread ||
|
||||
channelType === ChannelType.AnnouncementThread;
|
||||
const channelName = resolveDiscordChannelNameSafe(channel);
|
||||
const channelSlug = channelName ? normalizeDiscordSlug(channelName) : "";
|
||||
const rawChannelId = channel?.id ?? params.channelIdFallback;
|
||||
|
||||
let threadParentId: string | undefined;
|
||||
let threadParentName: string | undefined;
|
||||
let threadParentSlug = "";
|
||||
if (params.hasGuild && channel && isThreadChannel && rawChannelId) {
|
||||
const channelInfo = await resolveDiscordChannelInfo(params.client, rawChannelId);
|
||||
const parentInfo = await resolveDiscordThreadParentInfo({
|
||||
client: params.client,
|
||||
threadChannel: {
|
||||
id: rawChannelId,
|
||||
name: channelName,
|
||||
parentId: resolveDiscordChannelParentIdSafe(channel),
|
||||
parent: undefined,
|
||||
},
|
||||
channelInfo,
|
||||
});
|
||||
threadParentId = parentInfo.id;
|
||||
threadParentName = parentInfo.name;
|
||||
threadParentSlug = threadParentName ? normalizeDiscordSlug(threadParentName) : "";
|
||||
}
|
||||
|
||||
return {
|
||||
channelType,
|
||||
isDirectMessage,
|
||||
isGroupDm,
|
||||
isThreadChannel,
|
||||
channelName,
|
||||
channelSlug,
|
||||
rawChannelId,
|
||||
threadParentId,
|
||||
threadParentName,
|
||||
threadParentSlug,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user