diff --git a/.vscode/settings.json b/.vscode/settings.json index 492b7791a..18bff7280 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "deno.enable": true, - "deno.lint": true, + "deno.lint": false, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, "editor.codeActionsOnSave": { diff --git a/src/handlers/interactions/INTERACTION_CREATE.ts b/src/handlers/interactions/INTERACTION_CREATE.ts index 6d7da483c..4188056bd 100644 --- a/src/handlers/interactions/INTERACTION_CREATE.ts +++ b/src/handlers/interactions/INTERACTION_CREATE.ts @@ -1,15 +1,44 @@ import { eventHandlers } from "../../bot.ts"; import { cacheHandlers } from "../../cache.ts"; +import { createDiscordenoMessage, DiscordenoMessage } from "../../structures/message.ts"; import { structures } from "../../structures/mod.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; -import type { Interaction } from "../../types/interactions/interaction.ts"; +import type { BigInteraction, Interaction } from "../../types/interactions/interaction.ts"; import type { GuildMemberWithUser } from "../../types/members/guild_member.ts"; import { snowflakeToBigint } from "../../util/bigint.ts"; export async function handleInteractionCreate(data: DiscordGatewayPayload) { - const payload = data.d as Interaction; + const basePayload = data.d as Interaction; + + const payload = { + ...basePayload, + id: snowflakeToBigint(basePayload.id), + applicationId: snowflakeToBigint(basePayload.applicationId), + guildId: basePayload.guildId ? snowflakeToBigint(basePayload.guildId) : undefined, + channelId: basePayload.channelId ? snowflakeToBigint(basePayload.channelId) : undefined, + member: basePayload.member + ? { + ...basePayload.member, + roles: basePayload.member.roles.map((id) => snowflakeToBigint(id)), + user: { + ...basePayload.member.user, + id: snowflakeToBigint(basePayload.member.user.id), + }, + } + : undefined, + user: basePayload.user + ? { + ...basePayload.user, + id: snowflakeToBigint(basePayload.user.id), + } + : undefined, + message: basePayload.message ? createDiscordenoMessage(basePayload.message) : undefined, + } as BigInteraction; + + if (payload.member) payload.user = payload.member.user; + const discordenoMember = payload.guildId - ? await structures.createDiscordenoMember(payload.member as GuildMemberWithUser, snowflakeToBigint(payload.guildId)) + ? await structures.createDiscordenoMember(payload.member as GuildMemberWithUser, payload.guildId) : undefined; if (discordenoMember) { diff --git a/src/types/discordeno/event_handlers.ts b/src/types/discordeno/event_handlers.ts index 3562b1c7b..7834cfc86 100644 --- a/src/types/discordeno/event_handlers.ts +++ b/src/types/discordeno/event_handlers.ts @@ -15,7 +15,7 @@ import type { DiscordGatewayPayload } from "../gateway/gateway_payload.ts"; import type { IntegrationCreateUpdate } from "../integrations/integration_create_update.ts"; import type { IntegrationDelete } from "../integrations/integration_delete.ts"; import type { ApplicationCommandCreateUpdateDelete } from "../interactions/commands/application_command_create_update_delete.ts"; -import type { Interaction } from "../interactions/interaction.ts"; +import type { BigInteraction, Interaction } from "../interactions/interaction.ts"; import type { InviteCreate } from "../invites/invite_create.ts"; import type { InviteDelete } from "../invites/invite_delete.ts"; import type { MessageReactionAdd } from "../messages/message_reaction_add.ts"; @@ -82,11 +82,11 @@ export type EventHandlersDefinitions = { /** Sent when a guild member is updated. This will also fire when the user object of a guild member changes. */ guildMemberUpdate: [guild: DiscordenoGuild, member: DiscordenoMember, oldMember?: DiscordenoMember]; /** Sent when a user uses a Slash Command (type 2) or clicks a button (type 3). */ - interactionCreate: [data: Interaction, member?: DiscordenoMember]; + interactionCreate: [data: BigInteraction, member?: DiscordenoMember]; /** Sent when a user uses a Slash Command in a guild (type 2) or clicks a button (type 3). */ - interactionGuildCreate: [data: Interaction, member: DiscordenoMember]; + interactionGuildCreate: [data: BigInteraction, member: DiscordenoMember]; /** Sent when a user uses a Slash Command in a dm (type 2) or clicks a button (type 3). */ - interactionDMCreate: [data: Omit]; + interactionDMCreate: [data: Omit]; /** Sent when a lurker joins/leaves/moves stage channels. */ lurkerVoiceStateUpdate: [member: DiscordenoMember, voiceState: VoiceState]; /** Sent when a message is created. */ diff --git a/src/types/interactions/interaction.ts b/src/types/interactions/interaction.ts index 0ef8bafe4..8e408d2ef 100644 --- a/src/types/interactions/interaction.ts +++ b/src/types/interactions/interaction.ts @@ -5,6 +5,7 @@ import { InteractionGuildMember } from "./interaction_guild_member.ts"; import { DiscordInteractionTypes } from "./interaction_types.ts"; import { SelectMenuData } from "../messages/components/select_data.ts"; import { ButtonData } from "../messages/components/button_data.ts"; +import { DiscordenoMessage } from "../../structures/message.ts"; /** https://discord.com/developers/docs/interactions/slash-commands#interaction */ export type Interaction = PingInteraction | SlashCommandInteraction | ComponentInteraction; @@ -48,3 +49,29 @@ export interface BaseInteraction< data?: D; } + +export interface BigInteraction + extends Omit { + /** Id of the interaction */ + id: bigint; + /** Id of the application this interaction is for */ + applicationId: bigint; + /** The guild it was sent from */ + guildId?: bigint; + /** The channel it was sent from */ + channelId?: bigint; + /** Guild member data for the invoking user, including permissions */ + member?: Omit & { + /** Array of role object ids */ + roles: bigint[]; + /** The user this guild member represents */ + user: Omit & { + /** The user's id */ + id: bigint; + }; + }; + /** User object for the invoking user, if invoked in a DM */ + user: Omit & { id: bigint }; + /** For the message the button was attached to */ + message?: DiscordenoMessage; +} diff --git a/src/util/constants.ts b/src/util/constants.ts index 4f4c69794..8305e79de 100644 --- a/src/util/constants.ts +++ b/src/util/constants.ts @@ -170,3 +170,4 @@ export const endpoints = { export const SLASH_COMMANDS_NAME_REGEX = /^[\w-]{1,32}$/; export const CONTEXT_MENU_COMMANDS_NAME_REGEX = /^[\w-\s]{1,32}$/; export const CHANNEL_MENTION_REGEX = /<#[0-9]+>/g; +export const DISCORD_SNOWFLAKE_REGEX = /^(?\d{17,19})$/; diff --git a/src/util/loop_object.ts b/src/util/loop_object.ts index e91ddcbf7..c3d45c004 100644 --- a/src/util/loop_object.ts +++ b/src/util/loop_object.ts @@ -1,10 +1,6 @@ import { eventHandlers } from "../bot.ts"; -export function loopObject>( - obj: Record, - handler: (value: unknown, key: string) => unknown, - log: string -) { +export function loopObject(obj: {}, handler: (value: unknown, key: string) => unknown, log: string) { let res: Record | unknown[] = {}; if (Array.isArray(obj)) { @@ -13,7 +9,7 @@ export function loopObject>( for (const o of obj) { if (typeof o === "object" && !Array.isArray(o) && o !== null) { // A nested object - res.push(loopObject(o as Record, handler, log)); + res.push(loopObject(o as {}, handler, log)); } else { res.push(handler(o, "array")); } @@ -24,7 +20,7 @@ export function loopObject>( if (typeof value === "object" && !Array.isArray(value) && value !== null && !(value instanceof Blob)) { // A nested object - res[key] = loopObject(value as Record, handler, log); + res[key] = loopObject(value as {}, handler, log); } else { res[key] = handler(value, key); }