From 75a7c81476953a948091e0f60f2f9ae4ee75c881 Mon Sep 17 00:00:00 2001 From: Abraham Doan Date: Thu, 29 Jan 2026 19:07:55 -0600 Subject: [PATCH] feat: Add Discord forum post support Add support for creating posts in Discord forum channels (type 15). Forum channels require a message object when creating threads, unlike regular threads that are created from existing messages. Changes: - Added 'message' parameter to DiscordThreadCreate type - Updated createThreadDiscord to handle forum posts with message body - Modified thread-create action to accept and pass message parameter - Forum posts use direct endpoint: /channels/{channelId}/threads Usage: message({ action: "thread-create", channelId: "", threadName: "Post Title", message: "Post content" }) Fixes: Forum posts previously failed with 'This field is required' error --- src/agents/tools/discord-actions-messaging.ts | 5 +++-- src/channels/plugins/actions/discord/handle-action.ts | 2 ++ src/discord/send.messages.ts | 8 ++++++++ src/discord/send.types.ts | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/agents/tools/discord-actions-messaging.ts b/src/agents/tools/discord-actions-messaging.ts index f90fb60de..3e81878c2 100644 --- a/src/agents/tools/discord-actions-messaging.ts +++ b/src/agents/tools/discord-actions-messaging.ts @@ -279,6 +279,7 @@ export async function handleDiscordMessagingAction( const channelId = resolveChannelId(); const name = readStringParam(params, "name", { required: true }); const messageId = readStringParam(params, "messageId"); + const message = readStringParam(params, "message"); const autoArchiveMinutesRaw = params.autoArchiveMinutes; const autoArchiveMinutes = typeof autoArchiveMinutesRaw === "number" && Number.isFinite(autoArchiveMinutesRaw) @@ -287,10 +288,10 @@ export async function handleDiscordMessagingAction( const thread = accountId ? await createThreadDiscord( channelId, - { name, messageId, autoArchiveMinutes }, + { name, messageId, message, autoArchiveMinutes }, { accountId }, ) - : await createThreadDiscord(channelId, { name, messageId, autoArchiveMinutes }); + : await createThreadDiscord(channelId, { name, messageId, message, autoArchiveMinutes }); return jsonResult({ ok: true, thread }); } case "threadList": { diff --git a/src/channels/plugins/actions/discord/handle-action.ts b/src/channels/plugins/actions/discord/handle-action.ts index 90e95d14d..a8f4f2deb 100644 --- a/src/channels/plugins/actions/discord/handle-action.ts +++ b/src/channels/plugins/actions/discord/handle-action.ts @@ -180,6 +180,7 @@ export async function handleDiscordMessageAction( if (action === "thread-create") { const name = readStringParam(params, "threadName", { required: true }); const messageId = readStringParam(params, "messageId"); + const message = readStringParam(params, "message"); const autoArchiveMinutes = readNumberParam(params, "autoArchiveMin", { integer: true, }); @@ -190,6 +191,7 @@ export async function handleDiscordMessageAction( channelId: resolveChannelId(), name, messageId, + message, autoArchiveMinutes, }, cfg, diff --git a/src/discord/send.messages.ts b/src/discord/send.messages.ts index 93bc378d7..11c3bc7b6 100644 --- a/src/discord/send.messages.ts +++ b/src/discord/send.messages.ts @@ -97,6 +97,14 @@ export async function createThreadDiscord( if (payload.autoArchiveMinutes) { body.auto_archive_duration = payload.autoArchiveMinutes; } + // Forum channels (type 15) require a message object for thread creation + if (payload.message) { + body.message = { content: payload.message }; + // For forum posts, POST directly to /channels/{channelId}/threads + const route = `/channels/${channelId}/threads`; + return await rest.post(route, { body }); + } + // Regular thread from an existing message const route = Routes.threads(channelId, payload.messageId); return await rest.post(route, { body }); } diff --git a/src/discord/send.types.ts b/src/discord/send.types.ts index 5ea63366a..933e2326b 100644 --- a/src/discord/send.types.ts +++ b/src/discord/send.types.ts @@ -68,6 +68,7 @@ export type DiscordMessageEdit = { export type DiscordThreadCreate = { messageId?: string; + message?: string; name: string; autoArchiveMinutes?: number; };