discord: support forum post creation via thread-create

Allow thread-create to create Discord forum posts by accepting initial content and appliedTagIds, and using POST /channels/{id}/threads.
This commit is contained in:
Solvely-Colin 2026-01-27 23:08:59 +00:00
parent 0b1c8db0ca
commit 37ffd3463b
4 changed files with 49 additions and 3 deletions

View File

@ -279,18 +279,31 @@ export async function handleDiscordMessagingAction(
const channelId = resolveChannelId();
const name = readStringParam(params, "name", { required: true });
const messageId = readStringParam(params, "messageId");
// Optional initial content (required for forum posts).
const content = readStringParam(params, "content") ?? undefined;
// Optional applied tag ids (forum posts).
const appliedTagIds = Array.isArray(params.appliedTagIds)
? params.appliedTagIds.filter((x) => typeof x === "string" && x.trim())
: undefined;
const autoArchiveMinutesRaw = params.autoArchiveMinutes;
const autoArchiveMinutes =
typeof autoArchiveMinutesRaw === "number" && Number.isFinite(autoArchiveMinutesRaw)
? autoArchiveMinutesRaw
: undefined;
const thread = accountId
? await createThreadDiscord(
channelId,
{ name, messageId, autoArchiveMinutes },
{ name, messageId, autoArchiveMinutes, content, appliedTagIds },
{ accountId },
)
: await createThreadDiscord(channelId, { name, messageId, autoArchiveMinutes });
: await createThreadDiscord(channelId, {
name,
messageId,
autoArchiveMinutes,
content,
appliedTagIds,
});
return jsonResult({ ok: true, thread });
}
case "threadList": {

View File

@ -180,6 +180,10 @@ export async function handleDiscordMessageAction(
if (action === "thread-create") {
const name = readStringParam(params, "threadName", { required: true });
const messageId = readStringParam(params, "messageId");
// Optional initial post content (required for forum post creation).
const content = readStringParam(params, "message");
// Optional forum tag ids.
const appliedTagIds = readStringArrayParam(params, "appliedTagIds");
const autoArchiveMinutes = readNumberParam(params, "autoArchiveMin", {
integer: true,
});
@ -190,6 +194,8 @@ export async function handleDiscordMessageAction(
channelId: resolveChannelId(),
name,
messageId,
content,
appliedTagIds,
autoArchiveMinutes,
},
cfg,

View File

@ -94,10 +94,30 @@ export async function createThreadDiscord(
) {
const rest = resolveDiscordRest(opts);
const body: Record<string, unknown> = { name: payload.name };
if (payload.autoArchiveMinutes) {
body.auto_archive_duration = payload.autoArchiveMinutes;
}
const route = Routes.threads(channelId, payload.messageId);
// Forum posts (channel type 15) require an initial message payload.
// If content is provided, create the thread with an initial post.
if (payload.content) {
body.message = { content: payload.content };
if (Array.isArray(payload.appliedTagIds) && payload.appliedTagIds.length) {
body.applied_tags = payload.appliedTagIds;
}
// NOTE: discord-api-types Routes doesn't currently expose a helper for
// POST /channels/{channel.id}/threads (it only exposes listing archived threads),
// so use the raw route string.
const route = `/channels/${channelId}/threads`;
return await rest.post(route, { body });
}
// Regular threads: create from an existing message when messageId is provided,
// otherwise create a standard thread in the channel.
const route = payload.messageId
? Routes.threads(channelId, payload.messageId)
: `/channels/${channelId}/threads`;
return await rest.post(route, { body });
}

View File

@ -67,9 +67,16 @@ export type DiscordMessageEdit = {
};
export type DiscordThreadCreate = {
/** Optional message id to start a thread from (for classic threads). */
messageId?: string;
/** Thread / forum post title. */
name: string;
/** Auto-archive duration in minutes. */
autoArchiveMinutes?: number;
/** Optional initial post content (required for forum post creation). */
content?: string;
/** Optional forum tag ids (applied tags). */
appliedTagIds?: string[];
};
export type DiscordThreadList = {