diff --git a/src/bot.ts b/src/bot.ts index 96be5beea..a2643204b 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -78,10 +78,20 @@ import { delay, validateComponents, validateSlashOptionChoices, validateSlashOpt import { iconBigintToHash, iconHashToBigInt } from "./util/hash.ts"; import { calculateShardId } from "./util/calculate_shard_id.ts"; import { + handleReady, handleChannelCreate, handleChannelDelete, handleChannelPinsUpdate, handleChannelUpdate, + handleThreadCreate, + handleThreadUpdate, + handleThreadDelete, + handleThreadListSync, + handleThreadMemberUpdate, + handleThreadMembersUpdate, + handleStageInstanceCreate, + handleStageInstanceUpdate, + handleStageInstanceDelete, handleGuildBanAdd, handleGuildBanRemove, handleGuildCreate, @@ -90,44 +100,34 @@ import { handleGuildIntegrationsUpdate, handleGuildMemberAdd, handleGuildMemberRemove, - handleGuildMembersChunk, handleGuildMemberUpdate, + handleGuildMembersChunk, handleGuildRoleCreate, handleGuildRoleDelete, handleGuildRoleUpdate, handleGuildUpdate, - handleIntegrationCreate, - handleIntegrationDelete, - handleIntegrationUpdate, handleInteractionCreate, handleInviteCreate, handleMessageCreate, - handleMessageDelete, handleMessageDeleteBulk, + handleMessageDelete, handleMessageReactionAdd, - handleMessageReactionRemove, handleMessageReactionRemoveAll, handleMessageReactionRemoveEmoji, + handleMessageReactionRemove, handleMessageUpdate, handlePresenceUpdate, - handleReady, - handleStageInstanceCreate, - handleStageInstanceDelete, - handleStageInstanceUpdate, - handleThreadCreate, - handleThreadDelete, - handleThreadListSync, - handleThreadMembersUpdate, - handleThreadMemberUpdate, - handleThreadUpdate, handleTypingStart, handleUserUpdate, handleVoiceServerUpdate, handleVoiceStateUpdate, handleWebhooksUpdate, + handleIntegrationCreate, + handleIntegrationUpdate, + handleIntegrationDelete, } from "./handlers/mod.ts"; -import { handleGuildLoaded } from "./handlers/guilds/GUILD_LOADED_DD.ts"; -import { Emoji } from "./types/emojis/emoji.ts"; +import {Emoji} from "./types/emojis/emoji.ts"; +import {handleGuildLoaded} from "./handlers/guilds/GUILD_LOADED_DD.ts"; export async function createBot(options: CreateBotOptions) { return { diff --git a/src/handlers/integrations/INTEGRATION_CREATE.ts b/src/handlers/integrations/INTEGRATION_CREATE.ts index 47776f8c8..c298ddf46 100644 --- a/src/handlers/integrations/INTEGRATION_CREATE.ts +++ b/src/handlers/integrations/INTEGRATION_CREATE.ts @@ -1,7 +1,11 @@ -import { eventHandlers } from "../../bot.ts"; +import { Bot } from "../../bot.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import type { IntegrationCreateUpdate } from "../../types/integrations/integration_create_update.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -export function handleIntegrationCreate(data: DiscordGatewayPayload) { - eventHandlers.integrationCreate?.(data.d as IntegrationCreateUpdate); +export function handleIntegrationCreate(bot: Bot, data: DiscordGatewayPayload) { + bot.events.integrationCreate( + bot, + bot.transformers.integration(bot, data.d as SnakeCasedPropertiesDeep) + ); } diff --git a/src/handlers/integrations/INTEGRATION_DELETE.ts b/src/handlers/integrations/INTEGRATION_DELETE.ts index 6fc85523e..aaf3f93ab 100644 --- a/src/handlers/integrations/INTEGRATION_DELETE.ts +++ b/src/handlers/integrations/INTEGRATION_DELETE.ts @@ -1,7 +1,14 @@ -import { eventHandlers } from "../../bot.ts"; +import { Bot } from "../../bot.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import type { IntegrationDelete } from "../../types/integrations/integration_delete.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -export function handleIntegrationDelete(data: DiscordGatewayPayload) { - eventHandlers.integrationDelete?.(data.d as IntegrationDelete); +export function handleIntegrationDelete(bot: Bot, data: DiscordGatewayPayload) { + const payload = data.d as SnakeCasedPropertiesDeep; + + bot.events.integrationDelete(bot, { + id: bot.transformers.snowflake(payload.id), + guildId: bot.transformers.snowflake(payload.guild_id), + applicationId: payload.application_id ? bot.transformers.snowflake(payload.application_id) : undefined, + }); } diff --git a/src/handlers/integrations/INTEGRATION_UPDATE.ts b/src/handlers/integrations/INTEGRATION_UPDATE.ts index 1680110be..a4391cb8b 100644 --- a/src/handlers/integrations/INTEGRATION_UPDATE.ts +++ b/src/handlers/integrations/INTEGRATION_UPDATE.ts @@ -1,7 +1,11 @@ -import { eventHandlers } from "../../bot.ts"; +import { Bot } from "../../bot.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import type { IntegrationCreateUpdate } from "../../types/integrations/integration_create_update.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -export function handleIntegrationUpdate(data: DiscordGatewayPayload) { - eventHandlers.integrationUpdate?.(data.d as IntegrationCreateUpdate); +export function handleIntegrationUpdate(bot: Bot, data: DiscordGatewayPayload) { + bot.events.integrationsUpdate( + bot, + bot.transformers.integration(bot, data.d as SnakeCasedPropertiesDeep) + ); } diff --git a/src/handlers/interactions/INTERACTION_CREATE.ts b/src/handlers/interactions/INTERACTION_CREATE.ts index bead22709..56aac522b 100644 --- a/src/handlers/interactions/INTERACTION_CREATE.ts +++ b/src/handlers/interactions/INTERACTION_CREATE.ts @@ -1,52 +1,8 @@ -import { eventHandlers } from "../../bot.ts"; -import { cacheHandlers } from "../../cache.ts"; -import { createDiscordenoMessage, DiscordenoMessage } from "../../structures/message.ts"; -import { structures } from "../../structures/mod.ts"; +import { Bot } from "../../bot.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.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"; +import type { Interaction } from "../../types/interactions/interaction.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -export async function handleInteractionCreate(data: DiscordGatewayPayload) { - 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 && basePayload.member - ? await structures.createDiscordenoMember(basePayload.member, payload.guildId) - : undefined; - - if (discordenoMember) { - await cacheHandlers.set("members", discordenoMember.id, discordenoMember); - eventHandlers.interactionGuildCreate?.(payload, discordenoMember); - } else { - eventHandlers.interactionDMCreate?.(payload); - } - - eventHandlers.interactionCreate?.(payload, discordenoMember); +export async function handleInteractionCreate(bot: Bot, data: DiscordGatewayPayload) { + bot.events.interactionCreate(bot, bot.transformers.interaction(bot, data.d as SnakeCasedPropertiesDeep)); } diff --git a/src/transformers/integration.ts b/src/transformers/integration.ts new file mode 100644 index 000000000..654903767 --- /dev/null +++ b/src/transformers/integration.ts @@ -0,0 +1,91 @@ +import { Bot } from "../bot.ts"; +import { IntegrationCreateUpdate } from "../types/integrations/integration_create_update.ts"; +import { DiscordIntegrationExpireBehaviors } from "../types/mod.ts"; +import { SnakeCasedPropertiesDeep } from "../types/util.ts"; +import { DiscordenoUser } from "./member.ts"; + +export function transformIntegration(bot: Bot, payload: SnakeCasedPropertiesDeep) { + return { + guildId: bot.transformers.snowflake(payload.guild_id), + id: bot.transformers.snowflake(payload.id), + name: payload.name, + type: payload.type, + enabled: payload.enabled, + syncing: payload.syncing, + roleId: payload.role_id ? bot.transformers.snowflake(payload.role_id) : undefined, + enableEmoticons: payload.enable_emoticons, + expireBehavior: payload.expire_behavior, + expireGracePeriod: payload.expire_grace_period, + user: payload.user ? bot.transformers.user(bot, payload.user) : undefined, + account: { + id: bot.transformers.snowflake(payload.account.id), + name: payload.account.name, + }, + syncedAt: payload.synced_at ? Date.parse(payload.synced_at) : undefined, + subscriberCount: payload.subscriber_count, + revoked: payload.revoked, + application: payload.application + ? { + id: bot.transformers.snowflake(payload.application.id), + name: payload.application.name, + icon: payload.application.icon ? bot.utils.iconHashToBigInt(payload.application.icon) : undefined, + description: payload.application.description, + summary: payload.application.summary, + bot: payload.application.bot ? bot.transformers.user(bot, payload.application.bot) : undefined, + } + : undefined, + }; +} + +export interface DiscordenoIntegration { + /** The guild id for where this integration is location. */ + guildId: bigint; + /** Integration Id */ + id: bigint; + /** Integration name */ + name: string; + /** Integration type (twitch, youtube or discord) */ + type: "twitch" | "youtube" | "discord"; + /** Is this integration enabled */ + enabled: boolean; + /** Is this integration syncing */ + syncing?: boolean; + /** Role Id that this integration uses for "subscribers" */ + roleId?: bigint; + /** Whether emoticons should be synced for this integration (twitch only currently) */ + enableEmoticons?: boolean; + /** The behavior of expiring subscribers */ + expireBehavior?: DiscordIntegrationExpireBehaviors; + /** The grace period (in days) before expiring subscribers */ + expireGracePeriod?: number; + /** User for this integration */ + user?: DiscordenoUser; + /** Integration account information */ + account: { + /** Id of the account */ + id: bigint; + /** Name of the account */ + name: string; + }; + /** When this integration was last synced */ + syncedAt?: number; + /** How many subscribers this integration has */ + subscriberCount?: number; + /** Has this integration been revoked */ + revoked?: boolean; + /** The bot/OAuth2 application for discord integrations */ + application?: { + /** The id of the app */ + id: bigint; + /** The name of the app */ + name: string; + /** the icon hash of the app */ + icon?: bigint; + /** The description of the app */ + description: string; + /** The summary of the app */ + summary: string; + /** The bot associated with this application */ + bot?: DiscordenoUser; + }; +} diff --git a/src/transformers/interaction.ts b/src/transformers/interaction.ts new file mode 100644 index 000000000..5a1b29263 --- /dev/null +++ b/src/transformers/interaction.ts @@ -0,0 +1,43 @@ +import { Bot } from "../bot.ts"; +import { Interaction, Role } from "../types/mod.ts"; +import { SnakeCasedPropertiesDeep } from "../types/util.ts"; +import { DiscordenoMember, DiscordenoUser } from "./member.ts"; +import { DiscordenoMessage } from "./message.ts"; + +export function transformInteraction(bot: Bot, payload: SnakeCasedPropertiesDeep): DiscordenoInteraction { + const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined; + + return { + // UNTRANSFORMED STUFF HERE + type: payload.type, + token: payload.token, + version: payload.version, + + // TRANSFORMED STUFF BELOW + guildId, + id: bot.transformers.snowflake(payload.id), + applicationId: bot.transformers.snowflake(payload.application_id), + user: bot.transformers.user(bot, payload.member?.user || payload.user!), + message: payload.message ? bot.transformers.message(bot, payload.message) : undefined, + channelId: payload.channel_id ? bot.transformers.snowflake(payload.channel_id) : undefined, + member: payload.member && guildId ? bot.transformers.member(bot, payload.member, guildId) : undefined, + }; +} + +export interface DiscordenoInteraction + 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?: DiscordenoMember; + /** User object for the invoking user, if invoked in a DM */ + user: DiscordenoUser; + /** For the message the button was attached to */ + message?: DiscordenoMessage; +} diff --git a/src/transformers/message.ts b/src/transformers/message.ts index e441ab264..90ad8dc36 100644 --- a/src/transformers/message.ts +++ b/src/transformers/message.ts @@ -3,7 +3,7 @@ import { Message } from "../types/messages/message.ts"; import { CHANNEL_MENTION_REGEX } from "../util/constants.ts"; import { SnakeCasedPropertiesDeep } from "../types/util.ts"; -export function transformMessage(bot: Bot, data: SnakeCasedPropertiesDeep) { +export function transformMessage(bot: Bot, data: SnakeCasedPropertiesDeep): DiscordenoMessage { return { // UNTRANSFORMED STUFF HERE content: data.content || "", @@ -71,6 +71,9 @@ export interface DiscordenoMessage | "author" | "applicationId" | "thread" + | "tts" + | "pinned" + | "mentionEveryone" > { id: bigint; /** Whether or not this message was sent by a bot */ @@ -83,7 +86,7 @@ export interface DiscordenoMessage // For better user experience /** Id of the guild which the massage has been send in. "0n" if it a DM */ - guildId: bigint; + guildId?: bigint; /** id of the channel the message was sent in */ channelId: bigint; /** If the message is generated by a webhook, this is the webhook's id */