refactor(discord): share channel action param parsing

This commit is contained in:
Peter Steinberger
2026-04-22 19:37:45 +01:00
parent 8bd387976d
commit ec5d403f5b
4 changed files with 76 additions and 117 deletions

View File

@@ -1,6 +1,5 @@
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import {
parseAvailableTags,
readNumberParam,
readStringArrayParam,
readStringParam,
@@ -12,6 +11,11 @@ import {
isDiscordModerationAction,
readDiscordModerationCommand,
} from "./runtime.moderation-shared.js";
import {
readDiscordChannelCreateParams,
readDiscordChannelEditParams,
readDiscordChannelMoveParams,
} from "./runtime.shared.js";
type Ctx = Pick<
ChannelMessageActionContext,
@@ -21,9 +25,8 @@ type Ctx = Pick<
export async function tryHandleDiscordMessageActionGuildAdmin(params: {
ctx: Ctx;
resolveChannelId: () => string;
readParentIdParam: (params: Record<string, unknown>) => string | null | undefined;
}): Promise<AgentToolResult<unknown> | undefined> {
const { ctx, resolveChannelId, readParentIdParam } = params;
const { ctx, resolveChannelId } = params;
const { action, params: actionParams, cfg } = ctx;
const accountId = ctx.accountId ?? readStringParam(actionParams, "accountId");
@@ -154,25 +157,11 @@ export async function tryHandleDiscordMessageActionGuildAdmin(params: {
const guildId = readStringParam(actionParams, "guildId", {
required: true,
});
const name = readStringParam(actionParams, "name", { required: true });
const type = readNumberParam(actionParams, "type", { integer: true });
const parentId = readParentIdParam(actionParams);
const topic = readStringParam(actionParams, "topic");
const position = readNumberParam(actionParams, "position", {
integer: true,
});
const nsfw = typeof actionParams.nsfw === "boolean" ? actionParams.nsfw : undefined;
return await handleDiscordAction(
{
action: "channelCreate",
accountId: accountId ?? undefined,
guildId,
name,
type: type ?? undefined,
parentId: parentId ?? undefined,
topic: topic ?? undefined,
position: position ?? undefined,
nsfw,
...readDiscordChannelCreateParams({ ...actionParams, guildId }),
},
cfg,
);
@@ -182,37 +171,11 @@ export async function tryHandleDiscordMessageActionGuildAdmin(params: {
const channelId = readStringParam(actionParams, "channelId", {
required: true,
});
const name = readStringParam(actionParams, "name");
const topic = readStringParam(actionParams, "topic");
const position = readNumberParam(actionParams, "position", {
integer: true,
});
const parentId = readParentIdParam(actionParams);
const nsfw = typeof actionParams.nsfw === "boolean" ? actionParams.nsfw : undefined;
const rateLimitPerUser = readNumberParam(actionParams, "rateLimitPerUser", {
integer: true,
});
const archived = typeof actionParams.archived === "boolean" ? actionParams.archived : undefined;
const locked = typeof actionParams.locked === "boolean" ? actionParams.locked : undefined;
const autoArchiveDuration = readNumberParam(actionParams, "autoArchiveDuration", {
integer: true,
});
const availableTags = parseAvailableTags(actionParams.availableTags);
return await handleDiscordAction(
{
action: "channelEdit",
accountId: accountId ?? undefined,
channelId,
name: name ?? undefined,
topic: topic ?? undefined,
position: position ?? undefined,
parentId: parentId === undefined ? undefined : parentId,
nsfw,
rateLimitPerUser: rateLimitPerUser ?? undefined,
archived,
locked,
autoArchiveDuration: autoArchiveDuration ?? undefined,
availableTags,
...readDiscordChannelEditParams({ ...actionParams, channelId }),
},
cfg,
);
@@ -235,18 +198,11 @@ export async function tryHandleDiscordMessageActionGuildAdmin(params: {
const channelId = readStringParam(actionParams, "channelId", {
required: true,
});
const parentId = readParentIdParam(actionParams);
const position = readNumberParam(actionParams, "position", {
integer: true,
});
return await handleDiscordAction(
{
action: "channelMove",
accountId: accountId ?? undefined,
guildId,
channelId,
parentId: parentId === undefined ? undefined : parentId,
position: position ?? undefined,
...readDiscordChannelMoveParams({ ...actionParams, guildId, channelId }),
},
cfg,
);

View File

@@ -19,7 +19,6 @@ import {
} from "../shared-interactive.js";
import { resolveDiscordChannelId } from "../targets.js";
import { tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin.js";
import { readDiscordParentIdParam } from "./runtime.shared.js";
const providerId = "discord";
@@ -300,7 +299,6 @@ export async function handleDiscordMessageAction(
const adminResult = await tryHandleDiscordMessageActionGuildAdmin({
ctx,
resolveChannelId,
readParentIdParam: readDiscordParentIdParam,
});
if (adminResult !== undefined) {
return adminResult;

View File

@@ -4,7 +4,6 @@ import { getPresence } from "../monitor/presence-cache.js";
import {
type ActionGate,
jsonResult,
parseAvailableTags,
readNumberParam,
readStringArrayParam,
readStringParam,
@@ -32,7 +31,11 @@ import {
uploadStickerDiscord,
resolveEventCoverImage,
} from "../send.js";
import { readDiscordParentIdParam } from "./runtime.shared.js";
import {
readDiscordChannelCreateParams,
readDiscordChannelEditParams,
readDiscordChannelMoveParams,
} from "./runtime.shared.js";
export const discordGuildActionRuntime = {
addRoleDiscord,
@@ -326,23 +329,8 @@ export async function handleDiscordGuildAction(
if (!isActionEnabled("channels")) {
throw new Error("Discord channel management is disabled.");
}
const guildId = readStringParam(params, "guildId", { required: true });
const name = readStringParam(params, "name", { required: true });
const type = readNumberParam(params, "type", { integer: true });
const parentId = readDiscordParentIdParam(params);
const topic = readStringParam(params, "topic");
const position = readNumberParam(params, "position", { integer: true });
const nsfw = params.nsfw as boolean | undefined;
const channel = await discordGuildActionRuntime.createChannelDiscord(
{
guildId,
name,
type: type ?? undefined,
parentId: parentId ?? undefined,
topic: topic ?? undefined,
position: position ?? undefined,
nsfw,
},
readDiscordChannelCreateParams(params),
withOpts(),
);
return jsonResult({ ok: true, channel });
@@ -351,37 +339,10 @@ export async function handleDiscordGuildAction(
if (!isActionEnabled("channels")) {
throw new Error("Discord channel management is disabled.");
}
const channelId = readStringParam(params, "channelId", {
required: true,
});
const name = readStringParam(params, "name");
const topic = readStringParam(params, "topic");
const position = readNumberParam(params, "position", { integer: true });
const parentId = readDiscordParentIdParam(params);
const nsfw = params.nsfw as boolean | undefined;
const rateLimitPerUser = readNumberParam(params, "rateLimitPerUser", {
integer: true,
});
const archived = typeof params.archived === "boolean" ? params.archived : undefined;
const locked = typeof params.locked === "boolean" ? params.locked : undefined;
const autoArchiveDuration = readNumberParam(params, "autoArchiveDuration", {
integer: true,
});
const availableTags = parseAvailableTags(params.availableTags);
const editPayload = {
channelId,
name: name ?? undefined,
topic: topic ?? undefined,
position: position ?? undefined,
parentId,
nsfw,
rateLimitPerUser: rateLimitPerUser ?? undefined,
archived,
locked,
autoArchiveDuration: autoArchiveDuration ?? undefined,
availableTags,
};
const channel = await discordGuildActionRuntime.editChannelDiscord(editPayload, withOpts());
const channel = await discordGuildActionRuntime.editChannelDiscord(
readDiscordChannelEditParams(params),
withOpts(),
);
return jsonResult({ ok: true, channel });
}
case "channelDelete": {
@@ -398,19 +359,8 @@ export async function handleDiscordGuildAction(
if (!isActionEnabled("channels")) {
throw new Error("Discord channel management is disabled.");
}
const guildId = readStringParam(params, "guildId", { required: true });
const channelId = readStringParam(params, "channelId", {
required: true,
});
const parentId = readDiscordParentIdParam(params);
const position = readNumberParam(params, "position", { integer: true });
await discordGuildActionRuntime.moveChannelDiscord(
{
guildId,
channelId,
parentId,
position: position ?? undefined,
},
readDiscordChannelMoveParams(params),
withOpts(),
);
return jsonResult({ ok: true });

View File

@@ -1,4 +1,9 @@
import { readStringParam } from "../runtime-api.js";
import { parseAvailableTags, readNumberParam, readStringParam } from "../runtime-api.js";
import type {
DiscordChannelCreate,
DiscordChannelEdit,
DiscordChannelMove,
} from "../send.types.js";
export function readDiscordParentIdParam(
params: Record<string, unknown>,
@@ -11,3 +16,53 @@ export function readDiscordParentIdParam(
}
return readStringParam(params, "parentId");
}
function readDiscordBooleanParam(
params: Record<string, unknown>,
key: string,
): boolean | undefined {
return typeof params[key] === "boolean" ? params[key] : undefined;
}
export function readDiscordChannelCreateParams(
params: Record<string, unknown>,
): DiscordChannelCreate {
const parentId = readDiscordParentIdParam(params);
return {
guildId: readStringParam(params, "guildId", { required: true }),
name: readStringParam(params, "name", { required: true }),
type: readNumberParam(params, "type", { integer: true }) ?? undefined,
parentId: parentId ?? undefined,
topic: readStringParam(params, "topic") ?? undefined,
position: readNumberParam(params, "position", { integer: true }) ?? undefined,
nsfw: readDiscordBooleanParam(params, "nsfw"),
};
}
export function readDiscordChannelEditParams(params: Record<string, unknown>): DiscordChannelEdit {
const parentId = readDiscordParentIdParam(params);
return {
channelId: readStringParam(params, "channelId", { required: true }),
name: readStringParam(params, "name") ?? undefined,
topic: readStringParam(params, "topic") ?? undefined,
position: readNumberParam(params, "position", { integer: true }) ?? undefined,
parentId: parentId === undefined ? undefined : parentId,
nsfw: readDiscordBooleanParam(params, "nsfw"),
rateLimitPerUser: readNumberParam(params, "rateLimitPerUser", { integer: true }) ?? undefined,
archived: readDiscordBooleanParam(params, "archived"),
locked: readDiscordBooleanParam(params, "locked"),
autoArchiveDuration:
readNumberParam(params, "autoArchiveDuration", { integer: true }) ?? undefined,
availableTags: parseAvailableTags(params.availableTags),
};
}
export function readDiscordChannelMoveParams(params: Record<string, unknown>): DiscordChannelMove {
const parentId = readDiscordParentIdParam(params);
return {
guildId: readStringParam(params, "guildId", { required: true }),
channelId: readStringParam(params, "channelId", { required: true }),
parentId: parentId === undefined ? undefined : parentId,
position: readNumberParam(params, "position", { integer: true }) ?? undefined,
};
}