diff --git a/src/api/routes/interactions/#interaction_id/#interaction_token/callback.ts b/src/api/routes/interactions/#interaction_id/#interaction_token/callback.ts
index 3734a12e..6cb7f027 100644
--- a/src/api/routes/interactions/#interaction_id/#interaction_token/callback.ts
+++ b/src/api/routes/interactions/#interaction_id/#interaction_token/callback.ts
@@ -28,46 +28,6 @@ const router = Router({ mergeParams: true });
router.post("/", route({}), async (req: Request, res: Response) => {
const body = req.body as InteractionCallbackSchema;
- const errors: Record<string, { code?: string; message: string }> = {};
- const knownComponentIds: string[] = [];
-
- for (const row of body.data.components || []) {
- if (!row.components) {
- continue;
- }
-
- if (row.components.length < 1 || row.components.length > 5) {
- errors[`data.components[${body.data.components!.indexOf(row)}].components`] = {
- code: "BASE_TYPE_BAD_LENGTH",
- message: `Must be between 1 and 5 in length.`,
- };
- }
-
- for (const component of row.components) {
- if (component.type == MessageComponentType.Button && component.style != ButtonStyle.Link) {
- if (component.custom_id?.trim() === "") {
- errors[`data.components[${body.data.components!.indexOf(row)}].components[${row.components.indexOf(component)}].custom_id`] = {
- code: "BUTTON_COMPONENT_CUSTOM_ID_REQUIRED",
- message: "A custom id required",
- };
- }
-
- if (knownComponentIds.includes(component.custom_id!)) {
- errors[`data.components[${body.data.components!.indexOf(row)}].components[${row.components.indexOf(component)}].custom_id`] = {
- code: "COMPONENT_CUSTOM_ID_DUPLICATED",
- message: "Component custom id cannot be duplicated",
- };
- } else {
- knownComponentIds.push(component.custom_id!);
- }
- }
- }
- }
-
- if (Object.keys(errors).length > 0) {
- throw FieldErrors(errors);
- }
-
const interactionId = req.params.interaction_id as string;
const interaction = pendingInteractions.get(req.params.interaction_id);
diff --git a/src/api/util/handlers/Message.ts b/src/api/util/handlers/Message.ts
index c0d26dc5..78dbe47e 100644
--- a/src/api/util/handlers/Message.ts
+++ b/src/api/util/handlers/Message.ts
@@ -48,10 +48,23 @@ import {
Member,
Session,
MessageFlags,
+ FieldErrors,
} from "@spacebar/util";
import { HTTPError } from "lambert-server";
import { In, Or, Equal, IsNull } from "typeorm";
-import { ChannelType, Embed, EmbedType, MessageCreateAttachment, MessageCreateCloudAttachment, MessageCreateSchema, MessageType, Reaction, ReadStateType } from "@spacebar/schemas";
+import {
+ ButtonStyle,
+ ChannelType,
+ Embed,
+ EmbedType,
+ MessageComponentType,
+ MessageCreateAttachment,
+ MessageCreateCloudAttachment,
+ MessageCreateSchema,
+ MessageType,
+ Reaction,
+ ReadStateType,
+} from "@spacebar/schemas";
const allow_empty = false;
// TODO: check webhook, application, system author, stickers
// TODO: embed gifs/videos/images
@@ -59,6 +72,45 @@ const allow_empty = false;
const LINK_REGEX = /<?https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)>?/g;
export async function handleMessage(opts: MessageOptions): Promise<Message> {
+ const errors: Record<string, { code?: string; message: string }> = {};
+ const knownComponentIds: string[] = [];
+
+ for (const row of opts.components || []) {
+ if (!row.components) {
+ continue;
+ }
+
+ if (row.components.length < 1 || row.components.length > 5) {
+ errors[`data.components[${opts.components!.indexOf(row)}].components`] = {
+ code: "BASE_TYPE_BAD_LENGTH",
+ message: `Must be between 1 and 5 in length.`,
+ };
+ }
+
+ for (const component of row.components) {
+ if (component.type == MessageComponentType.Button && component.style != ButtonStyle.Link) {
+ if (component.custom_id?.trim() === "") {
+ errors[`data.components[${opts.components!.indexOf(row)}].components[${row.components.indexOf(component)}].custom_id`] = {
+ code: "BUTTON_COMPONENT_CUSTOM_ID_REQUIRED",
+ message: "A custom id required",
+ };
+ }
+
+ if (knownComponentIds.includes(component.custom_id!)) {
+ errors[`data.components[${opts.components!.indexOf(row)}].components[${row.components.indexOf(component)}].custom_id`] = {
+ code: "COMPONENT_CUSTOM_ID_DUPLICATED",
+ message: "Component custom id cannot be duplicated",
+ };
+ } else {
+ knownComponentIds.push(component.custom_id!);
+ }
+ }
+ }
+ }
+
+ if (Object.keys(errors).length > 0) {
+ throw FieldErrors(errors);
+ }
const channel = await Channel.findOneOrFail({
where: { id: opts.channel_id },
relations: { recipients: true },
|