From a5395b010927f8edfda4ab10f097fd7b7e7fd97f Mon Sep 17 00:00:00 2001 From: Hampus Date: Mon, 31 Aug 2026 18:54:25 +0200 Subject: [PATCH] fix(api): support presigned webhook attachments (#2264) --- fluxer_api/src/api/openapi/openapi.json | 62 ++++++++++++------- .../domains/webhook/WebhookRequestSchemas.ts | 8 ++- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/fluxer_api/src/api/openapi/openapi.json b/fluxer_api/src/api/openapi/openapi.json index 1fe96f8f0..c64592b7f 100644 --- a/fluxer_api/src/api/openapi/openapi.json +++ b/fluxer_api/src/api/openapi/openapi.json @@ -34718,28 +34718,46 @@ "attachments": { "type": "array", "items": { - "type": "object", - "properties": { - "id": { - "oneOf": [{"$ref": "#/components/schemas/SnowflakeType"}, {"$ref": "#/components/schemas/Int32Type"}], - "description": "Attachment ID for referencing uploaded files" - }, - "filename": {"type": "string", "description": "Name of the file (1-1024 characters)"}, - "description": { - "type": "string", - "description": "Description for the attachment (max 4096 characters)" - }, - "content_type": {"type": "string", "description": "MIME type of the file"}, - "size": {"$ref": "#/components/schemas/NonNegativeSafeIntegerType"}, - "url": {"type": "string", "description": "URL of the attachment"}, - "proxy_url": {"type": "string", "description": "Proxied URL of the attachment"}, - "height": {"type": "integer", "format": "int53", "description": "Height of the image/video in pixels"}, - "width": {"type": "integer", "format": "int53", "description": "Width of the image/video in pixels"}, - "ephemeral": {"type": "boolean", "description": "Whether this attachment is ephemeral"}, - "duration": {"type": "number", "description": "Duration of audio file in seconds"}, - "waveform": {"type": "string", "description": "Base64-encoded bytearray of audio waveform"}, - "flags": {"$ref": "#/components/schemas/MessageAttachmentFlags"} - } + "oneOf": [ + {"$ref": "#/components/schemas/ClientUploadedAttachmentRequest"}, + { + "type": "object", + "properties": { + "id": { + "oneOf": [ + {"$ref": "#/components/schemas/SnowflakeType"}, + {"$ref": "#/components/schemas/Int32Type"} + ], + "description": "Attachment ID for referencing uploaded files" + }, + "filename": {"type": "string", "description": "Name of the file (1-1024 characters)"}, + "description": { + "type": "string", + "description": "Description for the attachment (max 4096 characters)" + }, + "content_type": {"type": "string", "description": "MIME type of the file"}, + "upload_filename": {"not": {}}, + "file_size": {"not": {}}, + "size": {"$ref": "#/components/schemas/NonNegativeSafeIntegerType"}, + "url": {"type": "string", "description": "URL of the attachment"}, + "proxy_url": {"type": "string", "description": "Proxied URL of the attachment"}, + "height": { + "type": "integer", + "format": "int53", + "description": "Height of the image/video in pixels" + }, + "width": { + "type": "integer", + "format": "int53", + "description": "Width of the image/video in pixels" + }, + "ephemeral": {"type": "boolean", "description": "Whether this attachment is ephemeral"}, + "duration": {"type": "number", "description": "Duration of audio file in seconds"}, + "waveform": {"type": "string", "description": "Base64-encoded bytearray of audio waveform"}, + "flags": {"$ref": "#/components/schemas/MessageAttachmentFlags"} + } + } + ] }, "description": "Array of attachment objects" }, diff --git a/packages/schema/src/domains/webhook/WebhookRequestSchemas.ts b/packages/schema/src/domains/webhook/WebhookRequestSchemas.ts index 77183c454..3aadc7d70 100644 --- a/packages/schema/src/domains/webhook/WebhookRequestSchemas.ts +++ b/packages/schema/src/domains/webhook/WebhookRequestSchemas.ts @@ -7,6 +7,7 @@ import { MessageFlagsDescriptions, } from '@fluxer/constants/src/ChannelConstants'; import {AVATAR_MAX_SIZE, MAX_MESSAGE_LENGTH_PREMIUM} from '@fluxer/constants/src/LimitConstants'; +import {ClientUploadedAttachmentRequest} from '@fluxer/schema/src/domains/message/AttachmentSchemas'; import { MessageContentRequest, MessageNonceRequest, @@ -69,6 +70,8 @@ const WebhookAttachmentRequest = z.object({ filename: createStringType(1, 1024).optional().describe('Name of the file (1-1024 characters)'), description: createStringType(1, 4096).optional().describe('Description for the attachment (max 4096 characters)'), content_type: createStringType(1, 256).optional().describe('MIME type of the file'), + upload_filename: z.never().optional(), + file_size: z.never().optional(), size: NonNegativeSafeIntegerType.optional().describe('Size of the file in bytes'), url: URLType.optional().describe('URL of the attachment'), proxy_url: URLType.optional().describe('Proxied URL of the attachment'), @@ -89,7 +92,10 @@ export const WebhookMessageRequest = z .object({ content: MessageContentRequest.nullish(), embeds: z.array(RichEmbedRequest).optional().describe('Array of embed objects to include in the message'), - attachments: z.array(WebhookAttachmentRequest).optional().describe('Array of attachment objects'), + attachments: z + .array(z.union([ClientUploadedAttachmentRequest, WebhookAttachmentRequest])) + .optional() + .describe('Array of attachment objects'), message_reference: MessageReferenceRequest.nullish().describe( 'Reference to another message (for replies or forwards)', ),