refactor(discord): share component route + ack

This commit is contained in:
Peter Steinberger
2026-02-15 17:23:56 +00:00
parent b74c3d80cc
commit 63ab5bfddc

View File

@@ -49,6 +49,44 @@ type DiscordChannelContext = {
parentSlug: string;
};
function resolveAgentComponentRoute(params: {
ctx: AgentComponentContext;
rawGuildId: string | undefined;
memberRoleIds: string[];
isDirectMessage: boolean;
userId: string;
channelId: string;
parentId: string | undefined;
}) {
return resolveAgentRoute({
cfg: params.ctx.cfg,
channel: "discord",
accountId: params.ctx.accountId,
guildId: params.rawGuildId,
memberRoleIds: params.memberRoleIds,
peer: {
kind: params.isDirectMessage ? "direct" : "channel",
id: params.isDirectMessage ? params.userId : params.channelId,
},
parentPeer: params.parentId ? { kind: "channel", id: params.parentId } : undefined,
});
}
async function ackComponentInteraction(params: {
interaction: AgentComponentInteraction;
replyOpts: { ephemeral?: boolean };
label: string;
}) {
try {
await params.interaction.reply({
content: "✓",
...params.replyOpts,
});
} catch (err) {
logError(`${params.label}: failed to acknowledge interaction: ${String(err)}`);
}
}
function resolveDiscordChannelContext(
interaction: AgentComponentInteraction,
): DiscordChannelContext {
@@ -482,18 +520,14 @@ export class AgentComponentButton extends Button {
}
const { parentId } = allowed;
// Resolve route with full context (guildId, proper peer kind, parentPeer)
const route = resolveAgentRoute({
cfg: this.ctx.cfg,
channel: "discord",
accountId: this.ctx.accountId,
guildId: rawGuildId,
const route = resolveAgentComponentRoute({
ctx: this.ctx,
rawGuildId,
memberRoleIds,
peer: {
kind: isDirectMessage ? "direct" : "channel",
id: isDirectMessage ? userId : channelId,
},
parentPeer: parentId ? { kind: "channel", id: parentId } : undefined,
isDirectMessage,
userId,
channelId,
parentId,
});
const eventText = `[Discord component: ${componentId} clicked by ${username} (${userId})]`;
@@ -505,15 +539,7 @@ export class AgentComponentButton extends Button {
contextKey: `discord:agent-button:${channelId}:${componentId}:${userId}`,
});
// Acknowledge the interaction
try {
await interaction.reply({
content: "✓",
...replyOpts,
});
} catch (err) {
logError(`agent button: failed to acknowledge interaction: ${String(err)}`);
}
await ackComponentInteraction({ interaction, replyOpts, label: "agent button" });
}
}
@@ -586,18 +612,14 @@ export class AgentSelectMenu extends StringSelectMenu {
const values = interaction.values ?? [];
const valuesText = values.length > 0 ? ` (selected: ${values.join(", ")})` : "";
// Resolve route with full context (guildId, proper peer kind, parentPeer)
const route = resolveAgentRoute({
cfg: this.ctx.cfg,
channel: "discord",
accountId: this.ctx.accountId,
guildId: rawGuildId,
const route = resolveAgentComponentRoute({
ctx: this.ctx,
rawGuildId,
memberRoleIds,
peer: {
kind: isDirectMessage ? "direct" : "channel",
id: isDirectMessage ? userId : channelId,
},
parentPeer: parentId ? { kind: "channel", id: parentId } : undefined,
isDirectMessage,
userId,
channelId,
parentId,
});
const eventText = `[Discord select menu: ${componentId} interacted by ${username} (${userId})${valuesText}]`;
@@ -609,15 +631,7 @@ export class AgentSelectMenu extends StringSelectMenu {
contextKey: `discord:agent-select:${channelId}:${componentId}:${userId}`,
});
// Acknowledge the interaction
try {
await interaction.reply({
content: "✓",
...replyOpts,
});
} catch (err) {
logError(`agent select: failed to acknowledge interaction: ${String(err)}`);
}
await ackComponentInteraction({ interaction, replyOpts, label: "agent select" });
}
}