Discord: add fetch message action

This commit is contained in:
Shadow
2026-01-10 16:38:02 -06:00
parent 786eac1d6f
commit c731a87d07
5 changed files with 87 additions and 0 deletions

View File

@@ -5,6 +5,7 @@ import {
deleteMessageDiscord,
editMessageDiscord,
fetchChannelPermissionsDiscord,
fetchMessageDiscord,
fetchReactionsDiscord,
listPinsDiscord,
listThreadsDiscord,
@@ -53,6 +54,23 @@ function formatDiscordTimestamp(ts?: string | null): string | undefined {
return `${yyyy}-${mm}-${dd}T${hh}:${min}${sign}${offsetH}:${offsetM}${tzSuffix}`;
}
function parseDiscordMessageLink(link: string) {
const normalized = link.trim();
const match = normalized.match(
/^(?:https?:\/\/)?(?:ptb\.|canary\.)?discord(?:app)?\.com\/channels\/(\d+)\/(\d+)\/(\d+)(?:\/?|\?.*)$/i,
);
if (!match) {
throw new Error(
"Invalid Discord message link. Expected https://discord.com/channels/<guildId>/<channelId>/<messageId>.",
);
}
return {
guildId: match[1],
channelId: match[2],
messageId: match[3],
};
}
export async function handleDiscordMessagingAction(
action: string,
params: Record<string, unknown>,
@@ -157,6 +175,28 @@ export async function handleDiscordMessagingAction(
const permissions = await fetchChannelPermissionsDiscord(channelId);
return jsonResult({ ok: true, permissions });
}
case "fetchMessage": {
if (!isActionEnabled("messages")) {
throw new Error("Discord message reads are disabled.");
}
const messageLink = readStringParam(params, "messageLink");
let guildId = readStringParam(params, "guildId");
let channelId = readStringParam(params, "channelId");
let messageId = readStringParam(params, "messageId");
if (messageLink) {
const parsed = parseDiscordMessageLink(messageLink);
guildId = parsed.guildId;
channelId = parsed.channelId;
messageId = parsed.messageId;
}
if (!guildId || !channelId || !messageId) {
throw new Error(
"Discord message fetch requires guildId, channelId, and messageId (or a valid messageLink).",
);
}
const message = await fetchMessageDiscord(channelId, messageId);
return jsonResult({ ok: true, message, guildId, channelId, messageId });
}
case "readMessages": {
if (!isActionEnabled("messages")) {
throw new Error("Discord message reads are disabled.");

View File

@@ -11,6 +11,7 @@ const messagingActions = new Set([
"sticker",
"poll",
"permissions",
"fetchMessage",
"readMessages",
"sendMessage",
"editMessage",

View File

@@ -35,6 +35,21 @@ export const DiscordToolSchema = Type.Union([
action: Type.Literal("permissions"),
channelId: Type.String(),
}),
Type.Union([
Type.Object({
action: Type.Literal("fetchMessage"),
messageLink: Type.String(),
guildId: Type.Optional(Type.String()),
channelId: Type.Optional(Type.String()),
messageId: Type.Optional(Type.String()),
}),
Type.Object({
action: Type.Literal("fetchMessage"),
guildId: Type.String(),
channelId: Type.String(),
messageId: Type.String(),
}),
]),
Type.Object({
action: Type.Literal("readMessages"),
channelId: Type.String(),

View File

@@ -903,6 +903,17 @@ export async function readMessagesDiscord(
)) as APIMessage[];
}
export async function fetchMessageDiscord(
channelId: string,
messageId: string,
opts: DiscordReactOpts = {},
): Promise<APIMessage> {
const rest = resolveDiscordRest(opts);
return (await rest.get(
Routes.channelMessage(channelId, messageId),
)) as APIMessage;
}
export async function editMessageDiscord(
channelId: string,
messageId: string,