Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,18 @@
import { BaseMessageComponents, InteractionCallbackSchema, InteractionCallbacksSchema, InteractionCallbackType, InteractionFailureReason, MessageType } from "@spacebar/schemas";
import { handleComps, route, sendMessage } from "@spacebar/api";
import { Request, Response, Router } from "express";
import { Config, emitEvent, InteractionSuccessEvent, Message, MessageUpdateEvent, pendingInteractions, User, InteractionFailureEvent } from "@spacebar/util";
import {
Config,
emitEvent,
InteractionSuccessEvent,
Message,
MessageUpdateEvent,
pendingInteractions,
User,
InteractionFailureEvent,
InteractionModalCreateEvent,
Application,
} from "@spacebar/util";
import { HTTPError } from "#util/util/lambert-server";

const router = Router({ mergeParams: true });
Expand Down Expand Up @@ -47,9 +58,9 @@ router.post(
user_id: interaction?.userId,
data: {
id: interactionId,
nonce: interaction.nonce ?? "", // TODO: did i do this right?
nonce: interaction.nonce ?? "", // TODO: did i do this right?
},
} satisfies InteractionSuccessEvent);
} satisfies InteractionSuccessEvent);

switch (body.type) {
case InteractionCallbackType.PONG:
Expand Down Expand Up @@ -172,13 +183,25 @@ router.post(
}
// TODO
break;
case InteractionCallbackType.MODAL:
emitEvent({
event: "INTERACTION_MODAL_CREATE",
user_id: interaction.userId,
data: {
...body.data,
id: interaction.interactionId,
application: await Application.findOneOrFail({ where: { id: interaction.applicationId } }),
channel_id: interaction.channelId as string,
nonce: interaction.nonce,
},
} satisfies InteractionModalCreateEvent);
console.log(body);
break;
/*
case InteractionCallbackType.APPLICATION_COMMAND_AUTOCOMPLETE_RESULT:
// TODO
break;
case InteractionCallbackType.MODAL:
// TODO
break;

case InteractionCallbackType.PREMIUM_REQUIRED:
// Deprecated
break;
Expand Down
35 changes: 19 additions & 16 deletions src/api/routes/interactions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,24 +91,26 @@ router.post("/", route({}), async (req: Request, res: Response) => {
}

if (body.type === InteractionType.MessageComponent || body.data.type === InteractionType.ModalSubmit) {
interactionData.message = await Message.findOneOrFail({
where: { id: body.message_id, flags: undefined },
relations: {
author: true,
webhook: true,
application: true,
mentions: true,
mention_roles: true,
mention_channels: true,
sticker_items: true,
attachments: true,
thread: {
recipients: {
user: true,
interactionData.message = (
await Message.findOneOrFail({
where: { id: body.message_id, flags: undefined },
relations: {
author: true,
webhook: true,
application: true,
mentions: true,
mention_roles: true,
mention_channels: true,
sticker_items: true,
attachments: true,
thread: {
recipients: {
user: true,
},
},
},
},
});
})
).toJSON();
}

await emitEvent({
Expand Down Expand Up @@ -144,6 +146,7 @@ router.post("/", route({}), async (req: Request, res: Response) => {
commandType: body.data.type,
commandName: body.data.name,
messageId: body.message_id,
interactionId,
});

res.sendStatus(204);
Expand Down
1 change: 1 addition & 0 deletions src/api/util/handlers/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ export function route(opts: RouteOptions) {

const valid = validate(req.body);
if (!valid) {
console.log(JSON.stringify(req.body));
const fields: Record<string, { code?: string; message: string }> = {};
validate.errors?.forEach(
(x) =>
Expand Down
11 changes: 8 additions & 3 deletions src/schemas/api/bots/InteractionCallbackSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import { Message } from "@spacebar/util";
import { InteractionCallbackType } from "./InteractionCallbackType";
import { AllowedMentions, BaseMessageComponents, Embed, MessageComponentType } from "../messages";
import { AllowedMentions, BaseMessageComponents, Embed, ModalCallback } from "../messages";
import { MessageCreateAttachment, MessageCreateCloudAttachment, PollCreationSchema } from "#schemas/uncategorised";

export interface InteractionCallbackSchema {
Expand Down Expand Up @@ -50,14 +49,19 @@ export interface MessageDUpdateCallback extends InteractionCallbackSchema {
type: InteractionCallbackType.DEFERRED_UPDATE_MESSAGE;
data: InteractionMessage;
}
export interface ModalCallbackSchema extends InteractionCallbackSchema {
type: InteractionCallbackType.MODAL;
data: ModalCallback;
}
export type InteractionCallbacksSchema =
| PongCallback
| AckCallback
| MessageCallback
| MessageWSourceCallback
| MessageDWSourceCallback
| MessageUpdateCallback
| MessageDUpdateCallback;
| MessageDUpdateCallback
| ModalCallbackSchema;

export interface InteractionMessage {
content?: string;
Expand All @@ -68,4 +72,5 @@ export interface InteractionMessage {
flags?: number;
attachments?: (MessageCreateAttachment | MessageCreateCloudAttachment)[];
poll?: PollCreationSchema;
enforce_nonce?: boolean;
}
6 changes: 3 additions & 3 deletions src/schemas/api/bots/InteractionCreateSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import { PublicMember, PublicUser, Snowflake } from "@spacebar/schemas";
import { Channel, InteractionType, Message } from "@spacebar/util";
import { PublicMember, PublicMessage, PublicUser, Snowflake } from "@spacebar/schemas";
import { Channel, InteractionType } from "@spacebar/util";

export interface InteractionCreateSchema {
version: number; // TODO: types?
Expand All @@ -34,7 +34,7 @@ export interface InteractionCreateSchema {
member?: PublicMember;
user?: PublicUser;
locale?: string;
message?: Message;
message?: PublicMessage;
app_permissions: string;
entitlements?: object[]; // TODO: types?
entitlement_sku_ids?: Snowflake[]; // DEPRECATED
Expand Down
48 changes: 48 additions & 0 deletions src/schemas/api/messages/Components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,54 @@ export interface ActionRowComponent extends MessageComponent {
components: (ButtonComponent | StringSelectMenuComponent | SelectMenuComponent | TextInputComponent)[];
}

export interface FileUploadComponent extends MessageComponent {
type: MessageComponentType.FileUpload;
custom_id: string;
min_values?: number;
max_values?: number;
required?: boolean;
}

export interface CheckboxGroupComponent extends MessageComponent {
type: MessageComponentType.CheckboxGroup;
custom_id: string;
options: {
value: string;
label: string;
description?: string;
default?: boolean;
}[];
required: boolean;
}
export interface CheckboxComponent extends MessageComponent {
type: MessageComponentType.Checkbox;
custom_id: string;
required: boolean;
}
export interface LabelComponent extends MessageComponent {
type: MessageComponentType.Label;
label: string;
description?: string;
component: StringSelectMenuComponent | TextInputComponent | SelectMenuComponent | FileUploadComponent | RadioGroupComponent | CheckboxGroupComponent | CheckboxComponent;
}
export interface ModalCallback {
custom_id: string;
title: string;
components: (LabelComponent | ActionRowComponent | TextDisplayComponent)[];
}

export interface RadioGroupComponent extends MessageComponent {
type: MessageComponentType.RadioGroup;
custom_id: string;
options: {
value: string;
label: string;
description?: string;
default?: boolean;
}[];
required: boolean;
}

export interface ContainerComponent extends MessageComponent {
type: MessageComponentType.Container;
components: (ActionRowComponent | TextDisplayComponent | SectionComponent | MediaGalleryComponent | SeperatorComponent | FileComponent)[];
Expand Down
2 changes: 2 additions & 0 deletions src/util/entities/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { BaseClass } from "./BaseClass";
import { Team } from "./Team";
import { User } from "./User";
import { Guild } from "./Guild";
import { JsonRemoveEmpty } from "../util/Decorators";

@Entity({
name: "applications",
Expand Down Expand Up @@ -99,6 +100,7 @@ export class Application extends BaseClass {
cover_image?: string; // the application's default rich presence invite cover image hash

@Column({ type: "simple-json", nullable: true })
@JsonRemoveEmpty
install_params?: { scopes: string[]; permissions: string };

@Column({ nullable: true })
Expand Down
11 changes: 9 additions & 2 deletions src/util/entities/Message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ import {
ApplicationCommandType,
BaseMessageComponents,
Embed,
MessageComponentType, MessageSnapshot, MessageType, PartialMessage, Poll, PublicMessage, Reaction,
MessageComponentType,
MessageSnapshot,
MessageType,
PartialMessage,
Poll,
PublicMessage,
Reaction,
UnfurledMediaItem,
} from "@spacebar/schemas";
import { PartialUser } from "@spacebar/schemas";
Expand Down Expand Up @@ -291,8 +297,9 @@ export class Message extends BaseClass {
poll: this.poll ?? undefined,
content: this.content ?? "",
pinned: this.pinned,
thread: this.thread ? this.thread.toJSON() : this.thread,
thread: this.thread ? this.thread.toJSON() : undefined,
referenced_message: this.referenced_message && !shallow ? this.referenced_message.toJSON(true) : undefined,
message_snapshots: (typeof this.message_snapshots === "string" ? JSON.parse(this.message_snapshots) : this.message_snapshots) ?? undefined,
};
}

Expand Down
1 change: 1 addition & 0 deletions src/util/imports/Interactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface PendingInteraction {
type: InteractionType;
commandType: ApplicationCommandType;
commandName: string;
interactionId: string;
}

export const pendingInteractions = new Map<Snowflake, PendingInteraction>();
17 changes: 17 additions & 0 deletions src/util/interfaces/Event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
GuildOrUnavailable,
Snowflake,
ThreadMember,
Application,
} from "@spacebar/util";
import { JsonValue } from "@protobuf-ts/runtime";
import {
Expand Down Expand Up @@ -337,6 +338,7 @@ export interface GuildRoleDeleteEvent extends Event {
role_id: string;
};
}
import { ModalCallback } from "@spacebar/schemas";

export interface InviteCreateEvent extends Event {
event: "INVITE_CREATE";
Expand Down Expand Up @@ -543,6 +545,19 @@ export interface InteractionCreateEvent extends Event {
nonce?: string;
};
}
export interface InteractionModalCreateEvent extends Event {
event: "INTERACTION_MODAL_CREATE";
data: {
id: Snowflake;
channel_id: Snowflake;
custom_id: string; //TODO this needs to be corrected
application: Application;
title: string;
components: ModalCallback["components"];
nonce?: string;
//TODO resolved
};
}

export interface InteractionSuccessEvent extends Event {
event: "INTERACTION_SUCCESS";
Expand Down Expand Up @@ -719,6 +734,7 @@ export type EventData =
| InteractionCreateEvent
| InteractionSuccessEvent
| InteractionFailureEvent
| InteractionModalCreateEvent
| MessageAckEvent
| RelationshipAddEvent
| RelationshipRemoveEvent
Expand Down Expand Up @@ -856,6 +872,7 @@ export type EVENT =
| "THREAD_LIST_SYNC"
| "THREAD_MEMBER_UPDATE"
| "THREAD_MEMBERS_UPDATE"
| "INTERACTION_MODAL_CREATE"
| CUSTOMEVENTS;

export type CUSTOMEVENTS = "INVALIDATED" | "RATELIMIT" | "SB_SESSION_REMOVE" | "SB_SESSION_CLOSE";
Loading