223 lines
6.5 KiB
TypeScript
223 lines
6.5 KiB
TypeScript
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
|
import {
|
|
readNumberParam,
|
|
readStringArrayParam,
|
|
readStringParam,
|
|
} from "../../../../agents/tools/common.js";
|
|
import { handleDiscordAction } from "../../../../agents/tools/discord-actions.js";
|
|
import type { ChannelMessageActionContext } from "../../types.js";
|
|
import { tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin.js";
|
|
import { resolveDiscordChannelId } from "../../../../discord/targets.js";
|
|
|
|
const providerId = "discord";
|
|
|
|
function readParentIdParam(params: Record<string, unknown>): string | null | undefined {
|
|
if (params.clearParent === true) return null;
|
|
if (params.parentId === null) return null;
|
|
return readStringParam(params, "parentId");
|
|
}
|
|
|
|
export async function handleDiscordMessageAction(
|
|
ctx: Pick<ChannelMessageActionContext, "action" | "params" | "cfg" | "accountId">,
|
|
): Promise<AgentToolResult<unknown>> {
|
|
const { action, params, cfg } = ctx;
|
|
const accountId = ctx.accountId ?? readStringParam(params, "accountId");
|
|
const accountIdParam = accountId ?? undefined;
|
|
|
|
const resolveChannelId = () =>
|
|
resolveDiscordChannelId(
|
|
readStringParam(params, "channelId") ?? readStringParam(params, "to", { required: true }),
|
|
);
|
|
|
|
if (action === "send") {
|
|
const to = readStringParam(params, "to", { required: true });
|
|
const content = readStringParam(params, "message", {
|
|
required: true,
|
|
allowEmpty: true,
|
|
});
|
|
const mediaUrl = readStringParam(params, "media", { trim: false });
|
|
const replyTo = readStringParam(params, "replyTo");
|
|
const embeds = Array.isArray(params.embeds) ? params.embeds : undefined;
|
|
return await handleDiscordAction(
|
|
{
|
|
action: "sendMessage",
|
|
accountId: accountIdParam,
|
|
to,
|
|
content,
|
|
mediaUrl: mediaUrl ?? undefined,
|
|
replyTo: replyTo ?? undefined,
|
|
embeds,
|
|
},
|
|
cfg,
|
|
);
|
|
}
|
|
|
|
if (action === "poll") {
|
|
const to = readStringParam(params, "to", { required: true });
|
|
const question = readStringParam(params, "pollQuestion", {
|
|
required: true,
|
|
});
|
|
const answers = readStringArrayParam(params, "pollOption", { required: true }) ?? [];
|
|
const allowMultiselect = typeof params.pollMulti === "boolean" ? params.pollMulti : undefined;
|
|
const durationHours = readNumberParam(params, "pollDurationHours", {
|
|
integer: true,
|
|
});
|
|
return await handleDiscordAction(
|
|
{
|
|
action: "poll",
|
|
accountId: accountIdParam,
|
|
to,
|
|
question,
|
|
answers,
|
|
allowMultiselect,
|
|
durationHours: durationHours ?? undefined,
|
|
content: readStringParam(params, "message"),
|
|
},
|
|
cfg,
|
|
);
|
|
}
|
|
|
|
if (action === "react") {
|
|
const messageId = readStringParam(params, "messageId", { required: true });
|
|
const emoji = readStringParam(params, "emoji", { allowEmpty: true });
|
|
const remove = typeof params.remove === "boolean" ? params.remove : undefined;
|
|
return await handleDiscordAction(
|
|
{
|
|
action: "react",
|
|
accountId: accountIdParam,
|
|
channelId: resolveChannelId(),
|
|
messageId,
|
|
emoji,
|
|
remove,
|
|
},
|
|
cfg,
|
|
);
|
|
}
|
|
|
|
if (action === "reactions") {
|
|
const messageId = readStringParam(params, "messageId", { required: true });
|
|
const limit = readNumberParam(params, "limit", { integer: true });
|
|
return await handleDiscordAction(
|
|
{
|
|
action: "reactions",
|
|
accountId: accountIdParam,
|
|
channelId: resolveChannelId(),
|
|
messageId,
|
|
limit,
|
|
},
|
|
cfg,
|
|
);
|
|
}
|
|
|
|
if (action === "read") {
|
|
const limit = readNumberParam(params, "limit", { integer: true });
|
|
return await handleDiscordAction(
|
|
{
|
|
action: "readMessages",
|
|
accountId: accountIdParam,
|
|
channelId: resolveChannelId(),
|
|
limit,
|
|
before: readStringParam(params, "before"),
|
|
after: readStringParam(params, "after"),
|
|
around: readStringParam(params, "around"),
|
|
},
|
|
cfg,
|
|
);
|
|
}
|
|
|
|
if (action === "edit") {
|
|
const messageId = readStringParam(params, "messageId", { required: true });
|
|
const content = readStringParam(params, "message", { required: true });
|
|
return await handleDiscordAction(
|
|
{
|
|
action: "editMessage",
|
|
accountId: accountIdParam,
|
|
channelId: resolveChannelId(),
|
|
messageId,
|
|
content,
|
|
},
|
|
cfg,
|
|
);
|
|
}
|
|
|
|
if (action === "delete") {
|
|
const messageId = readStringParam(params, "messageId", { required: true });
|
|
return await handleDiscordAction(
|
|
{
|
|
action: "deleteMessage",
|
|
accountId: accountIdParam,
|
|
channelId: resolveChannelId(),
|
|
messageId,
|
|
},
|
|
cfg,
|
|
);
|
|
}
|
|
|
|
if (action === "pin" || action === "unpin" || action === "list-pins") {
|
|
const messageId =
|
|
action === "list-pins" ? undefined : readStringParam(params, "messageId", { required: true });
|
|
return await handleDiscordAction(
|
|
{
|
|
action: action === "pin" ? "pinMessage" : action === "unpin" ? "unpinMessage" : "listPins",
|
|
accountId: accountIdParam,
|
|
channelId: resolveChannelId(),
|
|
messageId,
|
|
},
|
|
cfg,
|
|
);
|
|
}
|
|
|
|
if (action === "permissions") {
|
|
return await handleDiscordAction(
|
|
{ action: "permissions", accountId: accountIdParam, channelId: resolveChannelId() },
|
|
cfg,
|
|
);
|
|
}
|
|
|
|
if (action === "thread-create") {
|
|
const name = readStringParam(params, "threadName", { required: true });
|
|
const messageId = readStringParam(params, "messageId");
|
|
const autoArchiveMinutes = readNumberParam(params, "autoArchiveMin", {
|
|
integer: true,
|
|
});
|
|
return await handleDiscordAction(
|
|
{
|
|
action: "threadCreate",
|
|
accountId: accountIdParam,
|
|
channelId: resolveChannelId(),
|
|
name,
|
|
messageId,
|
|
autoArchiveMinutes,
|
|
},
|
|
cfg,
|
|
);
|
|
}
|
|
|
|
if (action === "sticker") {
|
|
const stickerIds =
|
|
readStringArrayParam(params, "stickerId", {
|
|
required: true,
|
|
label: "sticker-id",
|
|
}) ?? [];
|
|
return await handleDiscordAction(
|
|
{
|
|
action: "sticker",
|
|
accountId: accountIdParam,
|
|
to: readStringParam(params, "to", { required: true }),
|
|
stickerIds,
|
|
content: readStringParam(params, "message"),
|
|
},
|
|
cfg,
|
|
);
|
|
}
|
|
|
|
const adminResult = await tryHandleDiscordMessageActionGuildAdmin({
|
|
ctx,
|
|
resolveChannelId,
|
|
readParentIdParam,
|
|
});
|
|
if (adminResult !== undefined) return adminResult;
|
|
|
|
throw new Error(`Action ${String(action)} is not supported for provider ${providerId}.`);
|
|
}
|