diff --git a/src/util/entities/Message.ts b/src/util/entities/Message.ts
index 05e7dea5..cd89c6e2 100644
--- a/src/util/entities/Message.ts
+++ b/src/util/entities/Message.ts
@@ -29,7 +29,18 @@ import { Webhook } from "./Webhook";
import { Sticker } from "./Sticker";
import { Attachment } from "./Attachment";
import { NewUrlUserSignatureData } from "../Signing";
-import { ApplicationCommandType, BaseMessageComponents, Embed, MessageSnapshot, MessageType, PartialMessage, Poll, Reaction } from "@spacebar/schemas";
+import {
+ ApplicationCommandType,
+ BaseMessageComponents,
+ Embed,
+ MessageComponentType,
+ MessageSnapshot,
+ MessageType,
+ PartialMessage,
+ Poll,
+ Reaction,
+ UnfurledMediaItem,
+} from "@spacebar/schemas";
import { MessageFlags } from "@spacebar/util";
import { JsonRemoveEmpty } from "../util/Decorators";
@@ -304,6 +315,55 @@ export class Message extends BaseClass {
attachments: this.attachments?.map((attachment: Attachment) => Attachment.prototype.signUrls.call(attachment, data)),
};
}
+ async withSignedComponents(data: NewUrlUserSignatureData) {
+ if (!this.components || !(this.flags & Number(MessageFlags.FLAGS.IS_COMPONENTS_V2))) return { ...this };
+ function signMedia(media: UnfurledMediaItem) {
+ Object.assign(media, Attachment.prototype.signUrls.call(media, data));
+ }
+ return {
+ ...this,
+ components: this.components.map((comp) => {
+ comp = structuredClone(comp);
+ if (comp.type === MessageComponentType.Section) {
+ const accessory = comp.accessory;
+ if (accessory.type === MessageComponentType.Thumbnail) {
+ signMedia(accessory.media);
+ }
+ } else if (comp.type === MessageComponentType.MediaGallery) {
+ comp.items.forEach(({ media }) => signMedia(media));
+ } else if (comp.type === MessageComponentType.File) {
+ signMedia(comp.file);
+ } else if (comp.type === MessageComponentType.Container) {
+ for (const elm of comp.components) {
+ switch (elm.type) {
+ case MessageComponentType.Separator:
+ case MessageComponentType.TextDisplay:
+ case MessageComponentType.ActionRow:
+ break;
+ case MessageComponentType.Section: {
+ const accessory = elm.accessory;
+ if (accessory.type === MessageComponentType.Thumbnail) {
+ signMedia(accessory.media);
+ }
+ break;
+ }
+ case MessageComponentType.MediaGallery:
+ elm.items.forEach(({ media }) => signMedia(media));
+ break;
+ case MessageComponentType.File: {
+ signMedia(elm.file);
+ break;
+ }
+
+ default:
+ elm satisfies never;
+ }
+ }
+ }
+ return comp;
+ }),
+ };
+ }
static async createWithDefaults(opts: Partial<Message>): Promise<Message> {
const message = Message.create();
|