From 7001a4c3829db3c1f91ab24635bedd671f301fd9 Mon Sep 17 00:00:00 2001 From: Rory& Date: Fri, 6 Mar 2026 22:50:26 +0100 Subject: [PATCH] [cherry/1518] Webhooks: respect thread_id parameter --- src/api/util/handlers/Webhook.ts | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/api/util/handlers/Webhook.ts b/src/api/util/handlers/Webhook.ts index fe1441716..439edbb23 100644 --- a/src/api/util/handlers/Webhook.ts +++ b/src/api/util/handlers/Webhook.ts @@ -1,5 +1,5 @@ import { handleMessage, postHandleMessage } from "@spacebar/api"; -import { Attachment, Config, DiscordApiErrors, emitEvent, FieldErrors, Message, MessageCreateEvent, uploadFile, ValidateName, Webhook } from "@spacebar/util"; +import { Attachment, Channel, Config, DiscordApiErrors, emitEvent, FieldErrors, Message, MessageCreateEvent, uploadFile, ValidateName, Webhook } from "@spacebar/util"; import { Request, Response } from "express"; import { HTTPError } from "lambert-server"; import { MoreThan } from "typeorm"; @@ -35,6 +35,7 @@ export const executeWebhook = async (req: Request, res: Response) => { } const wait = req.query.wait === "true"; + const thread_id = typeof req.query.thread_id === "string" ? req.query.thread_id : undefined; if (!wait) { res.status(204).send(); @@ -52,7 +53,7 @@ export const executeWebhook = async (req: Request, res: Response) => { // TODO: creating messages by users checks if the user can bypass rate limits, we cant do that on webhooks, but maybe we could check the application if there is one? const limits = Config.get().limits; - if (limits.absoluteRate.register.enabled) { + if (limits.absoluteRate.sendMessage.enabled) { const count = await Message.count({ where: { channel_id: webhook.channel_id, @@ -73,10 +74,20 @@ export const executeWebhook = async (req: Request, res: Response) => { } } + let sendChannel = webhook.channel; + if (thread_id) { + sendChannel = await Channel.findOneOrFail({ + where: { + id: thread_id, + parent_id: webhook.channel.id, + }, + }); + } + const files = (req.files as Express.Multer.File[]) ?? []; for (const currFile of files) { try { - const file = await uploadFile(`/attachments/${webhook.channel.id}`, currFile); + const file = await uploadFile(`/attachments/${sendChannel.id}`, currFile); attachments.push(Attachment.create({ ...file, proxy_url: file.url })); } catch (error) { if (wait) res.status(400).json({ message: error?.toString() }); @@ -95,7 +106,7 @@ export const executeWebhook = async (req: Request, res: Response) => { application_id: webhook.application?.id, embeds, // TODO: Support thread_id/thread_name once threads are implemented - channel_id: webhook.channel_id, + channel_id: sendChannel.id, attachments, timestamp: new Date(), }); @@ -104,14 +115,14 @@ export const executeWebhook = async (req: Request, res: Response) => { //@ts-ignore dont care2 message.edited_timestamp = null; - webhook.channel.last_message_id = message.id; + sendChannel.last_message_id = message.id; await Promise.all([ message.save(), - webhook.channel.save(), + sendChannel.save(), emitEvent({ event: "MESSAGE_CREATE", - channel_id: webhook.channel_id, + channel_id: sendChannel.id, data: message, } as MessageCreateEvent), ]);