mirror of
https://github.com/discordeno/discordeno.git
synced 2026-06-16 11:28:15 +00:00
guild handlers
This commit is contained in:
+260
-28
@@ -45,7 +45,6 @@ import { identify } from "./ws/identify.ts";
|
|||||||
import { heartbeat } from "./ws/heartbeat.ts";
|
import { heartbeat } from "./ws/heartbeat.ts";
|
||||||
import { resharder } from "./ws/resharder.ts";
|
import { resharder } from "./ws/resharder.ts";
|
||||||
import { tellClusterToIdentify } from "./ws/tell_cluster_to_identify.ts";
|
import { tellClusterToIdentify } from "./ws/tell_cluster_to_identify.ts";
|
||||||
import { handleDiscordPayload } from "./ws/handle_discord_payload.ts";
|
|
||||||
import { log } from "./ws/events.ts";
|
import { log } from "./ws/events.ts";
|
||||||
import { handleOnMessage } from "./ws/handle_on_message.ts";
|
import { handleOnMessage } from "./ws/handle_on_message.ts";
|
||||||
import { closeWS } from "./ws/close_ws.ts";
|
import { closeWS } from "./ws/close_ws.ts";
|
||||||
@@ -62,12 +61,64 @@ import {
|
|||||||
SLASH_COMMANDS_NAME_REGEX,
|
SLASH_COMMANDS_NAME_REGEX,
|
||||||
USER_AGENT,
|
USER_AGENT,
|
||||||
} from "./util/constants.ts";
|
} from "./util/constants.ts";
|
||||||
import { GatewayPayload } from "./types/gateway/gateway_payload.ts";
|
import { GatewayDispatchEventNames, GatewayEventNames, GatewayPayload } from "./types/gateway/gateway_payload.ts";
|
||||||
import { delay, validateSlashOptionChoices, validateSlashOptions } from "./util/utils.ts";
|
import { delay, validateSlashOptionChoices, validateSlashOptions } from "./util/utils.ts";
|
||||||
import { iconBigintToHash, iconHashToBigInt } from "./util/hash.ts";
|
import { iconBigintToHash, iconHashToBigInt } from "./util/hash.ts";
|
||||||
import { validateLength } from "./util/validate_length.ts";
|
import { validateLength } from "./util/validate_length.ts";
|
||||||
import { processGlobalQueue } from "./rest/process_global_queue.ts";
|
import { processGlobalQueue } from "./rest/process_global_queue.ts";
|
||||||
import { ChannelPinsUpdate } from "./types/channels/channel_pins_update.ts";
|
import { ChannelPinsUpdate } from "./types/channels/channel_pins_update.ts";
|
||||||
|
import { ApplicationCommandTypes, Emoji } from "./types/mod.ts";
|
||||||
|
import { ApplicationCommandOption } from "./types/mod.ts";
|
||||||
|
import { handleGuildLoaded } from "./handlers/guilds/GUILD_LOADED_DD.ts";
|
||||||
|
import {
|
||||||
|
handleReady,
|
||||||
|
handleChannelCreate,
|
||||||
|
handleChannelDelete,
|
||||||
|
handleChannelPinsUpdate,
|
||||||
|
handleChannelUpdate,
|
||||||
|
handleThreadCreate,
|
||||||
|
handleThreadUpdate,
|
||||||
|
handleThreadDelete,
|
||||||
|
handleThreadListSync,
|
||||||
|
handleThreadMemberUpdate,
|
||||||
|
handleThreadMembersUpdate,
|
||||||
|
handleStageInstanceCreate,
|
||||||
|
handleStageInstanceUpdate,
|
||||||
|
handleStageInstanceDelete,
|
||||||
|
handleGuildBanAdd,
|
||||||
|
handleGuildBanRemove,
|
||||||
|
handleGuildCreate,
|
||||||
|
handleGuildDelete,
|
||||||
|
handleGuildEmojisUpdate,
|
||||||
|
handleGuildIntegrationsUpdate,
|
||||||
|
handleGuildMemberAdd,
|
||||||
|
handleGuildMemberRemove,
|
||||||
|
handleGuildMemberUpdate,
|
||||||
|
handleGuildMembersChunk,
|
||||||
|
handleGuildRoleCreate,
|
||||||
|
handleGuildRoleDelete,
|
||||||
|
handleGuildRoleUpdate,
|
||||||
|
handleGuildUpdate,
|
||||||
|
handleInteractionCreate,
|
||||||
|
handleInviteCreate,
|
||||||
|
handleMessageCreate,
|
||||||
|
handleMessageDeleteBulk,
|
||||||
|
handleMessageDelete,
|
||||||
|
handleMessageReactionAdd,
|
||||||
|
handleMessageReactionRemoveAll,
|
||||||
|
handleMessageReactionRemoveEmoji,
|
||||||
|
handleMessageReactionRemove,
|
||||||
|
handleMessageUpdate,
|
||||||
|
handlePresenceUpdate,
|
||||||
|
handleTypingStart,
|
||||||
|
handleUserUpdate,
|
||||||
|
handleVoiceServerUpdate,
|
||||||
|
handleVoiceStateUpdate,
|
||||||
|
handleWebhooksUpdate,
|
||||||
|
handleIntegrationCreate,
|
||||||
|
handleIntegrationUpdate,
|
||||||
|
handleIntegrationDelete,
|
||||||
|
} from "./handlers/mod.ts";
|
||||||
|
|
||||||
export async function createBot(options: CreateBotOptions) {
|
export async function createBot(options: CreateBotOptions) {
|
||||||
return {
|
return {
|
||||||
@@ -80,7 +131,12 @@ export async function createBot(options: CreateBotOptions) {
|
|||||||
isReady: false,
|
isReady: false,
|
||||||
activeGuildIds: new Set<bigint>(),
|
activeGuildIds: new Set<bigint>(),
|
||||||
constants: createBotConstants(),
|
constants: createBotConstants(),
|
||||||
|
handlers: createBotGatewayHandlers({}),
|
||||||
cache: {
|
cache: {
|
||||||
|
forEach: function (
|
||||||
|
type: "DELETE_MESSAGES_FROM_GUILD" | "DELETE_CHANNELS_FROM_GUILD" | "DELETE_GUILD_FROM_MEMBER",
|
||||||
|
options: Record<string, any>
|
||||||
|
) {},
|
||||||
guilds: {
|
guilds: {
|
||||||
get: async function (id: bigint): Promise<DiscordenoGuild | undefined> {
|
get: async function (id: bigint): Promise<DiscordenoGuild | undefined> {
|
||||||
return {} as any as DiscordenoGuild;
|
return {} as any as DiscordenoGuild;
|
||||||
@@ -91,6 +147,9 @@ export async function createBot(options: CreateBotOptions) {
|
|||||||
set: async function (id: bigint, guild: DiscordenoGuild): Promise<void> {
|
set: async function (id: bigint, guild: DiscordenoGuild): Promise<void> {
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
delete: async function (id: bigint): Promise<void> {
|
||||||
|
return;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
channels: {
|
channels: {
|
||||||
get: async function (id: bigint): Promise<DiscordenoChannel | undefined> {
|
get: async function (id: bigint): Promise<DiscordenoChannel | undefined> {
|
||||||
@@ -116,6 +175,9 @@ export async function createBot(options: CreateBotOptions) {
|
|||||||
set: async function (id: bigint, member: DiscordenoMember): Promise<void> {
|
set: async function (id: bigint, member: DiscordenoMember): Promise<void> {
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
delete: async function (id: bigint): Promise<void> {
|
||||||
|
return;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
users: {
|
users: {
|
||||||
get: async function (id: bigint): Promise<DiscordenoUser | undefined> {
|
get: async function (id: bigint): Promise<DiscordenoUser | undefined> {
|
||||||
@@ -172,6 +234,15 @@ export function createEventHandlers(events: Partial<EventHandlers>): EventHandle
|
|||||||
channelDelete: events.channelDelete ?? ignore,
|
channelDelete: events.channelDelete ?? ignore,
|
||||||
channelPinsUpdate: events.channelPinsUpdate ?? ignore,
|
channelPinsUpdate: events.channelPinsUpdate ?? ignore,
|
||||||
channelUpdate: events.channelUpdate ?? ignore,
|
channelUpdate: events.channelUpdate ?? ignore,
|
||||||
|
guildEmojisUpdate: events.guildEmojisUpdate ?? ignore,
|
||||||
|
guildBanAdd: events.guildBanAdd ?? ignore,
|
||||||
|
guildBanRemove: events.guildBanRemove ?? ignore,
|
||||||
|
guildLoaded: events.guildLoaded ?? ignore,
|
||||||
|
guildCreate: events.guildCreate ?? ignore,
|
||||||
|
guildDelete: events.guildDelete ?? ignore,
|
||||||
|
guildUpdate: events.guildUpdate ?? ignore,
|
||||||
|
integrationsUpdate: events.integrationsUpdate ?? ignore,
|
||||||
|
raw: events.raw ?? ignore,
|
||||||
stageInstanceCreate: events.stageInstanceCreate ?? ignore,
|
stageInstanceCreate: events.stageInstanceCreate ?? ignore,
|
||||||
stageInstanceDelete: events.stageInstanceDelete ?? ignore,
|
stageInstanceDelete: events.stageInstanceDelete ?? ignore,
|
||||||
stageInstanceUpdate: events.stageInstanceUpdate ?? ignore,
|
stageInstanceUpdate: events.stageInstanceUpdate ?? ignore,
|
||||||
@@ -303,6 +374,10 @@ export interface HelperUtils {
|
|||||||
|
|
||||||
export function createGatewayManager(options: Partial<GatewayManager>): GatewayManager {
|
export function createGatewayManager(options: Partial<GatewayManager>): GatewayManager {
|
||||||
return {
|
return {
|
||||||
|
cache: {
|
||||||
|
guildIds: new Set(),
|
||||||
|
loadingGuildIds: new Set(),
|
||||||
|
},
|
||||||
secretKey: options.secretKey ?? "",
|
secretKey: options.secretKey ?? "",
|
||||||
url: options.url ?? "",
|
url: options.url ?? "",
|
||||||
reshard: options.reshard ?? true,
|
reshard: options.reshard ?? true,
|
||||||
@@ -337,7 +412,6 @@ export function createGatewayManager(options: Partial<GatewayManager>): GatewayM
|
|||||||
createShard,
|
createShard,
|
||||||
identify,
|
identify,
|
||||||
heartbeat,
|
heartbeat,
|
||||||
handleDiscordPayload,
|
|
||||||
tellClusterToIdentify,
|
tellClusterToIdentify,
|
||||||
log,
|
log,
|
||||||
resharder,
|
resharder,
|
||||||
@@ -346,6 +420,18 @@ export function createGatewayManager(options: Partial<GatewayManager>): GatewayM
|
|||||||
closeWS,
|
closeWS,
|
||||||
sendShardMessage,
|
sendShardMessage,
|
||||||
resume,
|
resume,
|
||||||
|
handleDiscordPayload:
|
||||||
|
options.handleDiscordPayload ||
|
||||||
|
async function (_, data: GatewayPayload, shardId: number) {
|
||||||
|
// TRIGGER RAW EVENT
|
||||||
|
bot.events.raw(bot as Bot, data, shardId);
|
||||||
|
|
||||||
|
if (!data.t) return;
|
||||||
|
|
||||||
|
// RUN DISPATCH CHECK
|
||||||
|
await bot.events.dispatchRequirements(bot as Bot, data, shardId);
|
||||||
|
bot.handlers[data.t as GatewayDispatchEventNames]?.(bot, data, shardId);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,6 +552,11 @@ export interface GatewayManager {
|
|||||||
>;
|
>;
|
||||||
utf8decoder: TextDecoder;
|
utf8decoder: TextDecoder;
|
||||||
|
|
||||||
|
cache: {
|
||||||
|
guildIds: Set<bigint>;
|
||||||
|
loadingGuildIds: Set<bigint>;
|
||||||
|
};
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
|
|
||||||
/** The handler function that starts the gateway. */
|
/** The handler function that starts the gateway. */
|
||||||
@@ -479,7 +570,7 @@ export interface GatewayManager {
|
|||||||
/** Begins heartbeating of the shard to keep it alive. */
|
/** Begins heartbeating of the shard to keep it alive. */
|
||||||
heartbeat: typeof heartbeat;
|
heartbeat: typeof heartbeat;
|
||||||
/** Sends the discord payload to another server. */
|
/** Sends the discord payload to another server. */
|
||||||
handleDiscordPayload: typeof handleDiscordPayload;
|
handleDiscordPayload: (gateway: GatewayManager, data: GatewayPayload, shardId: number) => any;
|
||||||
/** Tell the cluster/worker to begin identifying this shard */
|
/** Tell the cluster/worker to begin identifying this shard */
|
||||||
tellClusterToIdentify: typeof tellClusterToIdentify;
|
tellClusterToIdentify: typeof tellClusterToIdentify;
|
||||||
/** Handle the different logs. Used for debugging. */
|
/** Handle the different logs. Used for debugging. */
|
||||||
@@ -506,30 +597,54 @@ export interface EventHandlers {
|
|||||||
channelDelete: (bot: Bot, channel: DiscordenoChannel) => any;
|
channelDelete: (bot: Bot, channel: DiscordenoChannel) => any;
|
||||||
channelPinsUpdate: (bot: Bot, data: { guildId?: bigint; channelId: bigint; lastPinTimestamp?: number }) => any;
|
channelPinsUpdate: (bot: Bot, data: { guildId?: bigint; channelId: bigint; lastPinTimestamp?: number }) => any;
|
||||||
channelUpdate: (bot: Bot, channel: DiscordenoChannel, oldChannel: DiscordenoChannel) => any;
|
channelUpdate: (bot: Bot, channel: DiscordenoChannel, oldChannel: DiscordenoChannel) => any;
|
||||||
stageInstanceCreate: (bot: Bot, data: {
|
stageInstanceCreate: (
|
||||||
id: bigint;
|
bot: Bot,
|
||||||
guildId: bigint;
|
data: {
|
||||||
channelId: bigint;
|
id: bigint;
|
||||||
topic: string;
|
guildId: bigint;
|
||||||
privacyLevel: number;
|
channelId: bigint;
|
||||||
discoverableDisabled: boolean;
|
topic: string;
|
||||||
}) => any;
|
privacyLevel: number;
|
||||||
stageInstanceDelete: (bot: Bot, data: {
|
discoverableDisabled: boolean;
|
||||||
id: bigint;
|
}
|
||||||
guildId: bigint;
|
) => any;
|
||||||
channelId: bigint;
|
stageInstanceDelete: (
|
||||||
topic: string;
|
bot: Bot,
|
||||||
privacyLevel: number;
|
data: {
|
||||||
discoverableDisabled: boolean;
|
id: bigint;
|
||||||
}) => any;
|
guildId: bigint;
|
||||||
stageInstanceUpdate: (bot: Bot, data: {
|
channelId: bigint;
|
||||||
id: bigint;
|
topic: string;
|
||||||
guildId: bigint;
|
privacyLevel: number;
|
||||||
channelId: bigint;
|
discoverableDisabled: boolean;
|
||||||
topic: string;
|
}
|
||||||
privacyLevel: number;
|
) => any;
|
||||||
discoverableDisabled: boolean;
|
stageInstanceUpdate: (
|
||||||
}) => any;
|
bot: Bot,
|
||||||
|
data: {
|
||||||
|
id: bigint;
|
||||||
|
guildId: bigint;
|
||||||
|
channelId: bigint;
|
||||||
|
topic: string;
|
||||||
|
privacyLevel: number;
|
||||||
|
discoverableDisabled: boolean;
|
||||||
|
}
|
||||||
|
) => any;
|
||||||
|
// TODO: THREADS
|
||||||
|
guildEmojisUpdate: (
|
||||||
|
bot: Bot,
|
||||||
|
guild: DiscordenoGuild,
|
||||||
|
emojis: Collection<bigint, Emoji>,
|
||||||
|
cachedEmojis: Collection<bigint, Emoji>
|
||||||
|
) => any;
|
||||||
|
guildBanAdd: (bot: Bot, user: DiscordenoUser, guildId: bigint) => any;
|
||||||
|
guildBanRemove: (bot: Bot, user: DiscordenoUser, guildId: bigint) => any;
|
||||||
|
guildLoaded: (bot: Bot, guild: DiscordenoGuild) => any;
|
||||||
|
guildCreate: (bot: Bot, guild: DiscordenoGuild) => any;
|
||||||
|
guildDelete: (bot: Bot, id: bigint, guild?: DiscordenoGuild) => any;
|
||||||
|
guildUpdate: (bot: Bot, guild: DiscordenoGuild, cachedGuild?: DiscordenoGuild) => any;
|
||||||
|
integrationsUpdate: (bot: Bot, data: { guildId: bigint }) => any;
|
||||||
|
raw: (bot: Bot, data: GatewayPayload, shardId: number) => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBotConstants() {
|
export function createBotConstants() {
|
||||||
@@ -547,3 +662,120 @@ export function createBotConstants() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BotGatewayHandlerOptions {
|
||||||
|
READY: typeof handleReady;
|
||||||
|
CHANNEL_CREATE: typeof handleChannelCreate;
|
||||||
|
CHANNEL_DELETE: typeof handleChannelDelete;
|
||||||
|
CHANNEL_PINS_UPDATE: typeof handleChannelPinsUpdate;
|
||||||
|
CHANNEL_UPDATE: typeof handleChannelUpdate;
|
||||||
|
THREAD_CREATE: typeof handleThreadCreate;
|
||||||
|
THREAD_UPDATE: typeof handleThreadUpdate;
|
||||||
|
THREAD_DELETE: typeof handleThreadDelete;
|
||||||
|
THREAD_LIST_SYNC: typeof handleThreadListSync;
|
||||||
|
THREAD_MEMBER_UPDATE: typeof handleThreadMemberUpdate;
|
||||||
|
THREAD_MEMBERS_UPDATE: typeof handleThreadMembersUpdate;
|
||||||
|
STAGE_INSTANCE_CREATE: typeof handleStageInstanceCreate;
|
||||||
|
STAGE_INSTANCE_UPDATE: typeof handleStageInstanceUpdate;
|
||||||
|
STAGE_INSTANCE_DELETE: typeof handleStageInstanceDelete;
|
||||||
|
GUILD_BAN_ADD: typeof handleGuildBanAdd;
|
||||||
|
GUILD_BAN_REMOVE: typeof handleGuildBanRemove;
|
||||||
|
GUILD_CREATE: typeof handleGuildCreate;
|
||||||
|
GUILD_LOADED_DD: typeof handleGuildLoaded;
|
||||||
|
GUILD_DELETE: typeof handleGuildDelete;
|
||||||
|
GUILD_EMOJIS_UPDATE: typeof handleGuildEmojisUpdate;
|
||||||
|
GUILD_INTEGRATIONS_UPDATE: typeof handleGuildIntegrationsUpdate;
|
||||||
|
GUILD_MEMBER_ADD: typeof handleGuildMemberAdd;
|
||||||
|
GUILD_MEMBER_REMOVE: typeof handleGuildMemberRemove;
|
||||||
|
GUILD_MEMBER_UPDATE: typeof handleGuildMemberUpdate;
|
||||||
|
GUILD_MEMBERS_CHUNK: typeof handleGuildMembersChunk;
|
||||||
|
GUILD_ROLE_CREATE: typeof handleGuildRoleCreate;
|
||||||
|
GUILD_ROLE_DELETE: typeof handleGuildRoleDelete;
|
||||||
|
GUILD_ROLE_UPDATE: typeof handleGuildRoleUpdate;
|
||||||
|
GUILD_UPDATE: typeof handleGuildUpdate;
|
||||||
|
INTERACTION_CREATE: typeof handleInteractionCreate;
|
||||||
|
INVITE_CREATE: typeof handleInviteCreate;
|
||||||
|
INVITE_DELETE: typeof handleInviteCreate;
|
||||||
|
MESSAGE_CREATE: typeof handleMessageCreate;
|
||||||
|
MESSAGE_DELETE_BULK: typeof handleMessageDeleteBulk;
|
||||||
|
MESSAGE_DELETE: typeof handleMessageDelete;
|
||||||
|
MESSAGE_REACTION_ADD: typeof handleMessageReactionAdd;
|
||||||
|
MESSAGE_REACTION_REMOVE_ALL: typeof handleMessageReactionRemoveAll;
|
||||||
|
MESSAGE_REACTION_REMOVE_EMOJI: typeof handleMessageReactionRemoveEmoji;
|
||||||
|
MESSAGE_REACTION_REMOVE: typeof handleMessageReactionRemove;
|
||||||
|
MESSAGE_UPDATE: typeof handleMessageUpdate;
|
||||||
|
PRESENCE_UPDATE: typeof handlePresenceUpdate;
|
||||||
|
TYPING_START: typeof handleTypingStart;
|
||||||
|
USER_UPDATE: typeof handleUserUpdate;
|
||||||
|
VOICE_SERVER_UPDATE: typeof handleVoiceServerUpdate;
|
||||||
|
VOICE_STATE_UPDATE: typeof handleVoiceStateUpdate;
|
||||||
|
WEBHOOKS_UPDATE: typeof handleWebhooksUpdate;
|
||||||
|
INTEGRATION_CREATE: typeof handleIntegrationCreate;
|
||||||
|
INTEGRATION_UPDATE: typeof handleIntegrationUpdate;
|
||||||
|
INTEGRATION_DELETE: typeof handleIntegrationDelete;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createBotGatewayHandlers(options: Partial<BotGatewayHandlerOptions>) {
|
||||||
|
return {
|
||||||
|
// misc
|
||||||
|
READY: options.READY ?? handleReady,
|
||||||
|
// channels
|
||||||
|
CHANNEL_CREATE: options.CHANNEL_CREATE ?? handleChannelCreate,
|
||||||
|
CHANNEL_DELETE: options.CHANNEL_DELETE ?? handleChannelDelete,
|
||||||
|
CHANNEL_PINS_UPDATE: options.CHANNEL_PINS_UPDATE ?? handleChannelPinsUpdate,
|
||||||
|
CHANNEL_UPDATE: options.CHANNEL_UPDATE ?? handleChannelUpdate,
|
||||||
|
THREAD_CREATE: options.THREAD_CREATE ?? handleThreadCreate,
|
||||||
|
THREAD_UPDATE: options.THREAD_UPDATE ?? handleThreadUpdate,
|
||||||
|
THREAD_DELETE: options.THREAD_DELETE ?? handleThreadDelete,
|
||||||
|
THREAD_LIST_SYNC: options.THREAD_LIST_SYNC ?? handleThreadListSync,
|
||||||
|
THREAD_MEMBER_UPDATE: options.THREAD_MEMBER_UPDATE ?? handleThreadMemberUpdate,
|
||||||
|
THREAD_MEMBERS_UPDATE: options.THREAD_MEMBERS_UPDATE ?? handleThreadMembersUpdate,
|
||||||
|
STAGE_INSTANCE_CREATE: options.STAGE_INSTANCE_CREATE ?? handleStageInstanceCreate,
|
||||||
|
STAGE_INSTANCE_UPDATE: options.STAGE_INSTANCE_UPDATE ?? handleStageInstanceUpdate,
|
||||||
|
STAGE_INSTANCE_DELETE: options.STAGE_INSTANCE_DELETE ?? handleStageInstanceDelete,
|
||||||
|
|
||||||
|
// guilds
|
||||||
|
GUILD_BAN_ADD: options.GUILD_BAN_ADD ?? handleGuildBanAdd,
|
||||||
|
GUILD_BAN_REMOVE: options.GUILD_BAN_REMOVE ?? handleGuildBanRemove,
|
||||||
|
GUILD_CREATE: options.GUILD_CREATE ?? handleGuildCreate,
|
||||||
|
GUILD_LOADED_DD: options.GUILD_LOADED_DD ?? handleGuildLoaded,
|
||||||
|
GUILD_DELETE: options.GUILD_DELETE ?? handleGuildDelete,
|
||||||
|
GUILD_EMOJIS_UPDATE: options.GUILD_EMOJIS_UPDATE ?? handleGuildEmojisUpdate,
|
||||||
|
GUILD_INTEGRATIONS_UPDATE: options.GUILD_INTEGRATIONS_UPDATE ?? handleGuildIntegrationsUpdate,
|
||||||
|
GUILD_MEMBER_ADD: options.GUILD_MEMBER_ADD ?? handleGuildMemberAdd,
|
||||||
|
GUILD_MEMBER_REMOVE: options.GUILD_MEMBER_REMOVE ?? handleGuildMemberRemove,
|
||||||
|
GUILD_MEMBER_UPDATE: options.GUILD_MEMBER_UPDATE ?? handleGuildMemberUpdate,
|
||||||
|
GUILD_MEMBERS_CHUNK: options.GUILD_MEMBERS_CHUNK ?? handleGuildMembersChunk,
|
||||||
|
GUILD_ROLE_CREATE: options.GUILD_ROLE_CREATE ?? handleGuildRoleCreate,
|
||||||
|
GUILD_ROLE_DELETE: options.GUILD_ROLE_DELETE ?? handleGuildRoleDelete,
|
||||||
|
GUILD_ROLE_UPDATE: options.GUILD_ROLE_UPDATE ?? handleGuildRoleUpdate,
|
||||||
|
GUILD_UPDATE: options.GUILD_UPDATE ?? handleGuildUpdate,
|
||||||
|
// interactions
|
||||||
|
INTERACTION_CREATE: options.INTERACTION_CREATE ?? handleInteractionCreate,
|
||||||
|
// invites
|
||||||
|
INVITE_CREATE: options.INVITE_CREATE ?? handleInviteCreate,
|
||||||
|
INVITE_DELETE: options.INVITE_DELETE ?? handleInviteCreate,
|
||||||
|
// messages
|
||||||
|
MESSAGE_CREATE: options.MESSAGE_CREATE ?? handleMessageCreate,
|
||||||
|
MESSAGE_DELETE_BULK: options.MESSAGE_DELETE_BULK ?? handleMessageDeleteBulk,
|
||||||
|
MESSAGE_DELETE: options.MESSAGE_DELETE ?? handleMessageDelete,
|
||||||
|
MESSAGE_REACTION_ADD: options.MESSAGE_REACTION_ADD ?? handleMessageReactionAdd,
|
||||||
|
MESSAGE_REACTION_REMOVE_ALL: options.MESSAGE_REACTION_REMOVE_ALL ?? handleMessageReactionRemoveAll,
|
||||||
|
MESSAGE_REACTION_REMOVE_EMOJI: options.MESSAGE_REACTION_REMOVE_EMOJI ?? handleMessageReactionRemoveEmoji,
|
||||||
|
MESSAGE_REACTION_REMOVE: options.MESSAGE_REACTION_REMOVE ?? handleMessageReactionRemove,
|
||||||
|
MESSAGE_UPDATE: options.MESSAGE_UPDATE ?? handleMessageUpdate,
|
||||||
|
// presence
|
||||||
|
PRESENCE_UPDATE: options.PRESENCE_UPDATE ?? handlePresenceUpdate,
|
||||||
|
TYPING_START: options.TYPING_START ?? handleTypingStart,
|
||||||
|
USER_UPDATE: options.USER_UPDATE ?? handleUserUpdate,
|
||||||
|
// voice
|
||||||
|
VOICE_SERVER_UPDATE: options.VOICE_SERVER_UPDATE ?? handleVoiceServerUpdate,
|
||||||
|
VOICE_STATE_UPDATE: options.VOICE_STATE_UPDATE ?? handleVoiceStateUpdate,
|
||||||
|
// webhooks
|
||||||
|
WEBHOOKS_UPDATE: options.WEBHOOKS_UPDATE ?? handleWebhooksUpdate,
|
||||||
|
// integrations
|
||||||
|
INTEGRATION_CREATE: options.INTEGRATION_CREATE ?? handleIntegrationCreate,
|
||||||
|
INTEGRATION_UPDATE: options.INTEGRATION_UPDATE ?? handleIntegrationUpdate,
|
||||||
|
INTEGRATION_DELETE: options.INTEGRATION_DELETE ?? handleIntegrationDelete,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
|
||||||
import type { ApplicationCommandCreateUpdateDelete } from "../../types/interactions/commands/application_command_create_update_delete.ts";
|
|
||||||
|
|
||||||
export function handleApplicationCommandCreate(data: DiscordGatewayPayload) {
|
|
||||||
eventHandlers.applicationCommandCreate?.(data.d as ApplicationCommandCreateUpdateDelete);
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
|
||||||
import type { ApplicationCommandCreateUpdateDelete } from "../../types/interactions/commands/application_command_create_update_delete.ts";
|
|
||||||
|
|
||||||
export function handleApplicationCommandDelete(data: DiscordGatewayPayload) {
|
|
||||||
eventHandlers.applicationCommandDelete?.(data.d as ApplicationCommandCreateUpdateDelete);
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
|
||||||
import type { ApplicationCommandCreateUpdateDelete } from "../../types/interactions/commands/application_command_create_update_delete.ts";
|
|
||||||
|
|
||||||
export function handleApplicationCommandUpdate(data: DiscordGatewayPayload) {
|
|
||||||
eventHandlers.applicationCommandUpdate?.(data.d as ApplicationCommandCreateUpdateDelete);
|
|
||||||
}
|
|
||||||
@@ -1,19 +1,18 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
import { Bot } from "../../bot.ts";
|
||||||
import { cacheHandlers } from "../../cache.ts";
|
|
||||||
import type { GuildEmojisUpdate } from "../../types/emojis/guild_emojis_update.ts";
|
import type { GuildEmojisUpdate } from "../../types/emojis/guild_emojis_update.ts";
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
||||||
import { snowflakeToBigint } from "../../util/bigint.ts";
|
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||||
import { Collection } from "../../util/collection.ts";
|
import { Collection } from "../../util/collection.ts";
|
||||||
|
|
||||||
export async function handleGuildEmojisUpdate(data: DiscordGatewayPayload) {
|
export async function handleGuildEmojisUpdate(bot: Bot, data: SnakeCasedPropertiesDeep<DiscordGatewayPayload>) {
|
||||||
const payload = data.d as GuildEmojisUpdate;
|
const payload = data.d as SnakeCasedPropertiesDeep<GuildEmojisUpdate>;
|
||||||
const guild = await cacheHandlers.get("guilds", snowflakeToBigint(payload.guildId));
|
const guild = await bot.cache.guilds.get(bot.transformers.snowflake(payload.guild_id));
|
||||||
if (!guild) return;
|
if (!guild) return;
|
||||||
|
|
||||||
const cachedEmojis = guild.emojis;
|
const cachedEmojis = guild.emojis;
|
||||||
guild.emojis = new Collection(payload.emojis.map((emoji) => [snowflakeToBigint(emoji.id!), emoji]));
|
guild.emojis = new Collection(payload.emojis.map((emoji) => [bot.transformers.snowflake(emoji.id!), emoji]));
|
||||||
|
|
||||||
await cacheHandlers.set("guilds", guild.id, guild);
|
await bot.cache.guilds.set(guild.id, guild);
|
||||||
|
|
||||||
eventHandlers.guildEmojisUpdate?.(guild, guild.emojis, cachedEmojis);
|
bot.events.guildEmojisUpdate(bot, guild, guild.emojis, cachedEmojis);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
import { Bot } from "../../bot.ts";
|
||||||
import { cacheHandlers } from "../../cache.ts";
|
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
||||||
import type { GuildBanAddRemove } from "../../types/guilds/guild_ban_add_remove.ts";
|
import type { GuildBanAddRemove } from "../../types/guilds/guild_ban_add_remove.ts";
|
||||||
import { snowflakeToBigint } from "../../util/bigint.ts";
|
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||||
|
|
||||||
export async function handleGuildBanAdd(data: DiscordGatewayPayload) {
|
export async function handleGuildBanAdd(bot: Bot, data: SnakeCasedPropertiesDeep<DiscordGatewayPayload>) {
|
||||||
const payload = data.d as GuildBanAddRemove;
|
const payload = data.d as SnakeCasedPropertiesDeep<GuildBanAddRemove>;
|
||||||
const guild = await cacheHandlers.get("guilds", snowflakeToBigint(payload.guildId));
|
// FIRST COMPLETE THE END USERS EVENT
|
||||||
if (!guild) return;
|
await bot.events.guildBanAdd(bot, bot.transformers.user(bot, payload.user), bot.transformers.snowflake(payload.guild_id));
|
||||||
|
// THEN DELETE THE MEMBER
|
||||||
const member = await cacheHandlers.get("members", snowflakeToBigint(payload.user.id));
|
await bot.cache.members.delete(bot.transformers.snowflake(payload.user.id));
|
||||||
eventHandlers.guildBanAdd?.(guild, payload.user, member);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
import { Bot } from "../../bot.ts";
|
||||||
import { cacheHandlers } from "../../cache.ts";
|
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
||||||
import type { GuildBanAddRemove } from "../../types/guilds/guild_ban_add_remove.ts";
|
import type { GuildBanAddRemove } from "../../types/guilds/guild_ban_add_remove.ts";
|
||||||
import { snowflakeToBigint } from "../../util/bigint.ts";
|
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||||
|
|
||||||
export async function handleGuildBanRemove(data: DiscordGatewayPayload) {
|
export async function handleGuildBanRemove(bot: Bot, data: SnakeCasedPropertiesDeep<DiscordGatewayPayload>) {
|
||||||
const payload = data.d as GuildBanAddRemove;
|
const payload = data.d as SnakeCasedPropertiesDeep<GuildBanAddRemove>;
|
||||||
const guild = await cacheHandlers.get("guilds", snowflakeToBigint(payload.guildId));
|
|
||||||
if (!guild) return;
|
|
||||||
|
|
||||||
const member = await cacheHandlers.get("members", snowflakeToBigint(payload.user.id));
|
await bot.events.guildBanRemove(
|
||||||
eventHandlers.guildBanRemove?.(guild, payload.user, member);
|
bot,
|
||||||
|
bot.transformers.user(bot, payload.user),
|
||||||
|
bot.transformers.snowflake(payload.guild_id)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,17 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
import { Bot } from "../../bot.ts";
|
||||||
import { cache, cacheHandlers } from "../../cache.ts";
|
|
||||||
import { structures } from "../../structures/mod.ts";
|
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
||||||
import type { Guild } from "../../types/guilds/guild.ts";
|
import type { Guild } from "../../types/guilds/guild.ts";
|
||||||
import { snowflakeToBigint } from "../../util/bigint.ts";
|
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||||
import { ws } from "../../ws/ws.ts";
|
|
||||||
import { guildAvailable } from "../misc/READY.ts";
|
|
||||||
|
|
||||||
export async function handleGuildCreate(data: DiscordGatewayPayload, shardId: number) {
|
export async function handleGuildCreate(
|
||||||
const payload = data.d as Guild;
|
bot: Bot,
|
||||||
// When shards resume they emit GUILD_CREATE again.
|
data: SnakeCasedPropertiesDeep<DiscordGatewayPayload>,
|
||||||
if (
|
shardId: number
|
||||||
(await cacheHandlers.has("guilds", snowflakeToBigint(payload.id))) ||
|
) {
|
||||||
cache.dispatchedGuildIds.has(snowflakeToBigint(payload.id))
|
const payload = data.d as SnakeCasedPropertiesDeep<Guild>;
|
||||||
)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const guild = await structures.createDiscordenoGuild(payload, shardId);
|
const guild = bot.transformers.guild(bot, { guild: payload, shardId });
|
||||||
await cacheHandlers.set("guilds", guild.id, guild);
|
await bot.cache.guilds.set(guild.id, guild);
|
||||||
|
|
||||||
const shard = ws.shards.get(shardId);
|
await bot.events.guildCreate(bot, guild);
|
||||||
|
|
||||||
if (shard?.unavailableGuildIds.has(guild.id)) {
|
|
||||||
await cacheHandlers.delete("unavailableGuilds", guild.id);
|
|
||||||
guildAvailable(shard, guild.id);
|
|
||||||
|
|
||||||
return eventHandlers.guildAvailable?.(guild);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cache.isReady) return eventHandlers.guildLoaded?.(guild);
|
|
||||||
eventHandlers.guildCreate?.(guild);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,22 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
import { Bot } from "../../bot.ts";
|
||||||
import { cacheHandlers } from "../../cache.ts";
|
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
||||||
import type { UnavailableGuild } from "../../types/guilds/unavailable_guild.ts";
|
import type { UnavailableGuild } from "../../types/guilds/unavailable_guild.ts";
|
||||||
import { snowflakeToBigint } from "../../util/bigint.ts";
|
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||||
import { ws } from "../../ws/ws.ts";
|
|
||||||
|
|
||||||
export async function handleGuildDelete(data: DiscordGatewayPayload, shardId: number) {
|
export async function handleGuildDelete(bot: Bot, data: DiscordGatewayPayload, shardId: number) {
|
||||||
const payload = data.d as UnavailableGuild;
|
const payload = data.d as SnakeCasedPropertiesDeep<UnavailableGuild>;
|
||||||
|
|
||||||
const guild = await cacheHandlers.get("guilds", snowflakeToBigint(payload.id));
|
const id = bot.transformers.snowflake(payload.id);
|
||||||
|
const guild = await bot.cache.guilds.get(id);
|
||||||
|
await bot.events.guildDelete(bot, id, guild);
|
||||||
if (!guild) return;
|
if (!guild) return;
|
||||||
|
|
||||||
await cacheHandlers.delete("guilds", guild.id);
|
await bot.cache.guilds.delete(id);
|
||||||
|
|
||||||
if (payload.unavailable) {
|
|
||||||
const shard = ws.shards.get(shardId);
|
|
||||||
if (shard) shard.unavailableGuildIds.add(guild.id);
|
|
||||||
await cacheHandlers.set("unavailableGuilds", guild.id, Date.now());
|
|
||||||
|
|
||||||
eventHandlers.guildUnavailable?.(guild);
|
|
||||||
} else {
|
|
||||||
eventHandlers.guildDelete?.(guild);
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
cacheHandlers.forEach("DELETE_MESSAGES_FROM_GUILD", { guildId: guild.id }),
|
bot.cache.forEach("DELETE_MESSAGES_FROM_GUILD", { guildId: guild.id }),
|
||||||
cacheHandlers.forEach("DELETE_CHANNELS_FROM_GUILD", { guildId: guild.id }),
|
bot.cache.forEach("DELETE_CHANNELS_FROM_GUILD", { guildId: guild.id }),
|
||||||
cacheHandlers.forEach("DELETE_GUILD_FROM_MEMBER", { guildId: guild.id }),
|
bot.cache.forEach("DELETE_GUILD_FROM_MEMBER", { guildId: guild.id }),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
import { Bot } from "../../bot.ts";
|
||||||
import { cacheHandlers } from "../../cache.ts";
|
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
||||||
import type { GuildIntegrationsUpdate } from "../../types/integrations/guild_integrations_update.ts";
|
import type { GuildIntegrationsUpdate } from "../../types/integrations/guild_integrations_update.ts";
|
||||||
import { snowflakeToBigint } from "../../util/bigint.ts";
|
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||||
|
|
||||||
export async function handleGuildIntegrationsUpdate(data: DiscordGatewayPayload) {
|
export async function handleGuildIntegrationsUpdate(bot: Bot, data: DiscordGatewayPayload) {
|
||||||
const payload = data.d as GuildIntegrationsUpdate;
|
const payload = data.d as SnakeCasedPropertiesDeep<GuildIntegrationsUpdate>;
|
||||||
|
|
||||||
const guild = await cacheHandlers.get("guilds", snowflakeToBigint(payload.guildId));
|
bot.events.integrationsUpdate(bot, { guildId: bot.transformers.snowflake(payload.guild_id) });
|
||||||
if (!guild) return;
|
|
||||||
|
|
||||||
eventHandlers.guildIntegrationsUpdate?.(guild);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { Bot } from "../../bot.ts";
|
||||||
|
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
||||||
|
import type { Guild } from "../../types/guilds/guild.ts";
|
||||||
|
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||||
|
|
||||||
|
export async function handleGuildLoaded(
|
||||||
|
bot: Bot,
|
||||||
|
data: SnakeCasedPropertiesDeep<DiscordGatewayPayload>,
|
||||||
|
shardId: number
|
||||||
|
) {
|
||||||
|
const payload = data.d as SnakeCasedPropertiesDeep<Guild>;
|
||||||
|
|
||||||
|
const guild = bot.transformers.guild(bot, { guild: payload, shardId });
|
||||||
|
await bot.cache.guilds.set(guild.id, guild);
|
||||||
|
|
||||||
|
await bot.events.guildLoaded(bot, guild);
|
||||||
|
}
|
||||||
@@ -1,44 +1,14 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
import { Bot } from "../../bot.ts";
|
||||||
import { cacheHandlers } from "../../cache.ts";
|
|
||||||
import { structures } from "../../structures/mod.ts";
|
|
||||||
import type { GuildUpdateChange } from "../../types/discordeno/guild_update_change.ts";
|
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
||||||
import type { Guild } from "../../types/guilds/guild.ts";
|
import type { Guild } from "../../types/guilds/guild.ts";
|
||||||
import { snowflakeToBigint } from "../../util/bigint.ts";
|
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||||
|
|
||||||
export async function handleGuildUpdate(data: DiscordGatewayPayload, shardId: number) {
|
export async function handleGuildUpdate(bot: Bot, data: DiscordGatewayPayload, shardId: number) {
|
||||||
const payload = data.d as Guild;
|
const payload = data.d as SnakeCasedPropertiesDeep<Guild>;
|
||||||
const oldGuild = await cacheHandlers.get("guilds", snowflakeToBigint(payload.id));
|
|
||||||
if (!oldGuild) return;
|
|
||||||
|
|
||||||
const keysToSkip = ["id", "roles", "guildHashes", "guildId", "maxMembers", "emojis"];
|
const guild = bot.transformers.guild(bot, { guild: payload, shardId });
|
||||||
|
const cached = await bot.cache.guilds.get(guild.id);
|
||||||
|
await bot.cache.guilds.set(guild.id, guild);
|
||||||
|
|
||||||
const newGuild = await structures.createDiscordenoGuild(payload, shardId);
|
bot.events.guildUpdate(bot, guild, cached);
|
||||||
|
|
||||||
const changes = Object.entries(newGuild)
|
|
||||||
.map(([key, value]) => {
|
|
||||||
if (keysToSkip.includes(key)) return;
|
|
||||||
|
|
||||||
// @ts-ignore index signature
|
|
||||||
const cachedValue = oldGuild[key];
|
|
||||||
|
|
||||||
if (cachedValue === value) return;
|
|
||||||
// Guild create sends undefined and update sends false.
|
|
||||||
if (!cachedValue && !value) return;
|
|
||||||
|
|
||||||
if (Array.isArray(cachedValue) && Array.isArray(value)) {
|
|
||||||
const different =
|
|
||||||
cachedValue.length !== value.length ||
|
|
||||||
cachedValue.find((val) => !value.includes(val)) ||
|
|
||||||
value.find((val) => !cachedValue.includes(val));
|
|
||||||
if (!different) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { key, oldValue: cachedValue, value };
|
|
||||||
})
|
|
||||||
.filter((change) => change) as GuildUpdateChange[];
|
|
||||||
|
|
||||||
await cacheHandlers.set("guilds", newGuild.id, newGuild);
|
|
||||||
|
|
||||||
eventHandlers.guildUpdate?.(newGuild, changes);
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-78
@@ -11,9 +11,6 @@ import { handleThreadListSync } from "./channels/THREAD_LIST_SYNC.ts";
|
|||||||
import { handleThreadMembersUpdate } from "./channels/THREAD_MEMBERS_UPDATE.ts";
|
import { handleThreadMembersUpdate } from "./channels/THREAD_MEMBERS_UPDATE.ts";
|
||||||
import { handleThreadMemberUpdate } from "./channels/THREAD_MEMBER_UPDATE.ts";
|
import { handleThreadMemberUpdate } from "./channels/THREAD_MEMBER_UPDATE.ts";
|
||||||
import { handleThreadUpdate } from "./channels/THREAD_UPDATE.ts";
|
import { handleThreadUpdate } from "./channels/THREAD_UPDATE.ts";
|
||||||
import { handleApplicationCommandCreate } from "./commands/APPLICATION_COMMAND_CREATE.ts";
|
|
||||||
import { handleApplicationCommandDelete } from "./commands/APPLICATION_COMMAND_DELETE.ts";
|
|
||||||
import { handleApplicationCommandUpdate } from "./commands/APPLICATION_COMMAND_UPDATE.ts";
|
|
||||||
import { handleGuildEmojisUpdate } from "./emojis/GUILD_EMOJIS_UPDATE.ts";
|
import { handleGuildEmojisUpdate } from "./emojis/GUILD_EMOJIS_UPDATE.ts";
|
||||||
import { handleGuildBanAdd } from "./guilds/GUILD_BAN_ADD.ts";
|
import { handleGuildBanAdd } from "./guilds/GUILD_BAN_ADD.ts";
|
||||||
import { handleGuildBanRemove } from "./guilds/GUILD_BAN_REMOVE.ts";
|
import { handleGuildBanRemove } from "./guilds/GUILD_BAN_REMOVE.ts";
|
||||||
@@ -48,11 +45,9 @@ import { handleGuildRoleUpdate } from "./roles/GUILD_ROLE_UPDATE.ts";
|
|||||||
import { handleVoiceServerUpdate } from "./voice/VOICE_SERVER_UPDATE.ts";
|
import { handleVoiceServerUpdate } from "./voice/VOICE_SERVER_UPDATE.ts";
|
||||||
import { handleVoiceStateUpdate } from "./voice/VOICE_STATE_UPDATE.ts";
|
import { handleVoiceStateUpdate } from "./voice/VOICE_STATE_UPDATE.ts";
|
||||||
import { handleWebhooksUpdate } from "./webhooks/WEBHOOKS_UPDATE.ts";
|
import { handleWebhooksUpdate } from "./webhooks/WEBHOOKS_UPDATE.ts";
|
||||||
|
import { handleGuildLoaded } from "./guilds/GUILD_LOADED_DD.ts";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
handleApplicationCommandCreate,
|
|
||||||
handleApplicationCommandDelete,
|
|
||||||
handleApplicationCommandUpdate,
|
|
||||||
handleChannelCreate,
|
handleChannelCreate,
|
||||||
handleChannelDelete,
|
handleChannelDelete,
|
||||||
handleChannelPinsUpdate,
|
handleChannelPinsUpdate,
|
||||||
@@ -102,77 +97,6 @@ export {
|
|||||||
handleWebhooksUpdate,
|
handleWebhooksUpdate,
|
||||||
};
|
};
|
||||||
|
|
||||||
export let handlers = {
|
export const handlers = {
|
||||||
// misc
|
|
||||||
READY: handleReady,
|
|
||||||
// channels
|
|
||||||
CHANNEL_CREATE: handleChannelCreate,
|
|
||||||
CHANNEL_DELETE: handleChannelDelete,
|
|
||||||
CHANNEL_PINS_UPDATE: handleChannelPinsUpdate,
|
|
||||||
CHANNEL_UPDATE: handleChannelUpdate,
|
|
||||||
THREAD_CREATE: handleThreadCreate,
|
|
||||||
THREAD_UPDATE: handleThreadUpdate,
|
|
||||||
THREAD_DELETE: handleThreadDelete,
|
|
||||||
THREAD_LIST_SYNC: handleThreadListSync,
|
|
||||||
THREAD_MEMBER_UPDATE: handleThreadMemberUpdate,
|
|
||||||
THREAD_MEMBERS_UPDATE: handleThreadMembersUpdate,
|
|
||||||
STAGE_INSTANCE_CREATE: handleStageInstanceCreate,
|
|
||||||
STAGE_INSTANCE_UPDATE: handleStageInstanceUpdate,
|
|
||||||
STAGE_INSTANCE_DELETE: handleStageInstanceDelete,
|
|
||||||
|
|
||||||
// commands
|
|
||||||
APPLICATION_COMMAND_CREATE: handleApplicationCommandCreate,
|
|
||||||
APPLICATION_COMMAND_DELETE: handleApplicationCommandDelete,
|
|
||||||
APPLICATION_COMMAND_UPDATE: handleApplicationCommandUpdate,
|
|
||||||
// guilds
|
|
||||||
GUILD_BAN_ADD: handleGuildBanAdd,
|
|
||||||
GUILD_BAN_REMOVE: handleGuildBanRemove,
|
|
||||||
GUILD_CREATE: handleGuildCreate,
|
|
||||||
GUILD_DELETE: handleGuildDelete,
|
|
||||||
GUILD_EMOJIS_UPDATE: handleGuildEmojisUpdate,
|
|
||||||
GUILD_INTEGRATIONS_UPDATE: handleGuildIntegrationsUpdate,
|
|
||||||
GUILD_MEMBER_ADD: handleGuildMemberAdd,
|
|
||||||
GUILD_MEMBER_REMOVE: handleGuildMemberRemove,
|
|
||||||
GUILD_MEMBER_UPDATE: handleGuildMemberUpdate,
|
|
||||||
GUILD_MEMBERS_CHUNK: handleGuildMembersChunk,
|
|
||||||
GUILD_ROLE_CREATE: handleGuildRoleCreate,
|
|
||||||
GUILD_ROLE_DELETE: handleGuildRoleDelete,
|
|
||||||
GUILD_ROLE_UPDATE: handleGuildRoleUpdate,
|
|
||||||
GUILD_UPDATE: handleGuildUpdate,
|
|
||||||
// interactions
|
|
||||||
INTERACTION_CREATE: handleInteractionCreate,
|
|
||||||
// invites
|
|
||||||
INVITE_CREATE: handleInviteCreate,
|
|
||||||
INVITE_DELETE: handleInviteCreate,
|
|
||||||
// messages
|
|
||||||
MESSAGE_CREATE: handleMessageCreate,
|
|
||||||
MESSAGE_DELETE_BULK: handleMessageDeleteBulk,
|
|
||||||
MESSAGE_DELETE: handleMessageDelete,
|
|
||||||
MESSAGE_REACTION_ADD: handleMessageReactionAdd,
|
|
||||||
MESSAGE_REACTION_REMOVE_ALL: handleMessageReactionRemoveAll,
|
|
||||||
MESSAGE_REACTION_REMOVE_EMOJI: handleMessageReactionRemoveEmoji,
|
|
||||||
MESSAGE_REACTION_REMOVE: handleMessageReactionRemove,
|
|
||||||
MESSAGE_UPDATE: handleMessageUpdate,
|
|
||||||
// presence
|
|
||||||
PRESENCE_UPDATE: handlePresenceUpdate,
|
|
||||||
TYPING_START: handleTypingStart,
|
|
||||||
USER_UPDATE: handleUserUpdate,
|
|
||||||
// voice
|
|
||||||
VOICE_SERVER_UPDATE: handleVoiceServerUpdate,
|
|
||||||
VOICE_STATE_UPDATE: handleVoiceStateUpdate,
|
|
||||||
// webhooks
|
|
||||||
WEBHOOKS_UPDATE: handleWebhooksUpdate,
|
|
||||||
// integrations
|
|
||||||
INTEGRATION_CREATE: handleIntegrationCreate,
|
|
||||||
INTEGRATION_UPDATE: handleIntegrationUpdate,
|
|
||||||
INTEGRATION_DELETE: handleIntegrationDelete,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Handlers = typeof handlers;
|
|
||||||
|
|
||||||
export function updateHandlers(newHandlers: Handlers) {
|
|
||||||
handlers = {
|
|
||||||
...handlers,
|
|
||||||
...newHandlers,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
import type { DiscordenoChannel } from "../../structures/channel.ts";
|
|
||||||
import type { DiscordenoGuild } from "../../structures/guild.ts";
|
|
||||||
import type { DiscordenoMember } from "../../structures/member.ts";
|
|
||||||
import type { DiscordenoMessage } from "../../structures/message.ts";
|
|
||||||
import type { DiscordenoRole } from "../../structures/role.ts";
|
|
||||||
import { DiscordenoThread } from "../../util/transformers/channel_to_thread.ts";
|
import { DiscordenoThread } from "../../util/transformers/channel_to_thread.ts";
|
||||||
import type { Collection } from "../../util/collection.ts";
|
import type { Collection } from "../../util/collection.ts";
|
||||||
import type { PresenceUpdate } from "../activity/presence_update.ts";
|
import type { PresenceUpdate } from "../activity/presence_update.ts";
|
||||||
@@ -29,12 +24,6 @@ import type { DebugArg } from "./debug_arg.ts";
|
|||||||
import type { GuildUpdateChange } from "./guild_update_change.ts";
|
import type { GuildUpdateChange } from "./guild_update_change.ts";
|
||||||
|
|
||||||
export type EventHandlersDefinitions = {
|
export type EventHandlersDefinitions = {
|
||||||
/** Sent when a new Slash Command is created, relevant to the current user. */
|
|
||||||
applicationCommandCreate: [data: ApplicationCommandCreateUpdateDelete];
|
|
||||||
/** Sent when a Slash Command relevant to the current user is updated. */
|
|
||||||
applicationCommandUpdate: [data: ApplicationCommandCreateUpdateDelete];
|
|
||||||
/** Sent when a Slash Command relevant to the current user is deleted. */
|
|
||||||
applicationCommandDelete: [data: ApplicationCommandCreateUpdateDelete];
|
|
||||||
/** Sent when properties about the user change. */
|
/** Sent when properties about the user change. */
|
||||||
botUpdate: [user: User];
|
botUpdate: [user: User];
|
||||||
/** Sent when a new guild channel is created, relevant to the current user. */
|
/** Sent when a new guild channel is created, relevant to the current user. */
|
||||||
|
|||||||
@@ -6,55 +6,53 @@ export interface GatewayPayload {
|
|||||||
/** Sequence number, used for resuming sessions and heartbeats */
|
/** Sequence number, used for resuming sessions and heartbeats */
|
||||||
s: number | null;
|
s: number | null;
|
||||||
/** The event name for this payload */
|
/** The event name for this payload */
|
||||||
t:
|
t: GatewayEventNames | null;
|
||||||
| "READY"
|
|
||||||
| "RESUMED"
|
|
||||||
| "CHANNEL_CREATE"
|
|
||||||
| "CHANNEL_DELETE"
|
|
||||||
| "CHANNEL_PINS_UPDATE"
|
|
||||||
| "CHANNEL_UPDATE"
|
|
||||||
| "APPLICATION_COMMAND_CREATE"
|
|
||||||
| "APPLICATION_COMMAND_DELETE"
|
|
||||||
| "APPLICATION_COMMAND_UPDATE"
|
|
||||||
| "GUILD_BAN_ADD"
|
|
||||||
| "GUILD_BAN_REMOVE"
|
|
||||||
| "GUILD_CREATE"
|
|
||||||
| "GUILD_DELETE"
|
|
||||||
| "GUILD_EMOJIS_UPDATE"
|
|
||||||
| "GUILD_INTEGRATIONS_UPDATE"
|
|
||||||
| "GUILD_MEMBER_ADD"
|
|
||||||
| "GUILD_MEMBER_REMOVE"
|
|
||||||
| "GUILD_MEMBER_UPDATE"
|
|
||||||
| "GUILD_MEMBERS_CHUNK"
|
|
||||||
| "GUILD_ROLE_CREATE"
|
|
||||||
| "GUILD_ROLE_DELETE"
|
|
||||||
| "GUILD_ROLE_UPDATE"
|
|
||||||
| "GUILD_UPDATE"
|
|
||||||
| "INTERACTION_CREATE"
|
|
||||||
| "INVITE_CREATE"
|
|
||||||
| "INVITE_DELETE"
|
|
||||||
| "MESSAGE_CREATE"
|
|
||||||
| "MESSAGE_DELETE_BULK"
|
|
||||||
| "MESSAGE_DELETE"
|
|
||||||
| "MESSAGE_REACTION_ADD"
|
|
||||||
| "MESSAGE_REACTION_REMOVE_ALL"
|
|
||||||
| "MESSAGE_REACTION_REMOVE_EMOJI"
|
|
||||||
| "MESSAGE_REACTION_REMOVE"
|
|
||||||
| "MESSAGE_UPDATE"
|
|
||||||
| "PRESENCE_UPDATE"
|
|
||||||
| "TYPING_START"
|
|
||||||
| "USER_UPDATE"
|
|
||||||
| "VOICE_SERVER_UPDATE"
|
|
||||||
| "VOICE_STATE_UPDATE"
|
|
||||||
| "WEBHOOKS_UPDATE"
|
|
||||||
| "INTEGRATION_CREATE"
|
|
||||||
| "INTEGRATION_UPDATE"
|
|
||||||
| "INTEGRATION_DELETE"
|
|
||||||
| "STAGE_INSTANCE_CREATE"
|
|
||||||
| "STAGE_INSTANCE_UPDATE"
|
|
||||||
| "STAGE_INSTANCE_DELETE"
|
|
||||||
| null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** https://discord.com/developers/docs/topics/gateway#payloads-gateway-payload-structure */
|
/** https://discord.com/developers/docs/topics/gateway#payloads-gateway-payload-structure */
|
||||||
export type DiscordGatewayPayload = GatewayPayload;
|
export type DiscordGatewayPayload = GatewayPayload;
|
||||||
|
export type GatewayDispatchEventNames =
|
||||||
|
| "READY"
|
||||||
|
| "CHANNEL_CREATE"
|
||||||
|
| "CHANNEL_DELETE"
|
||||||
|
| "CHANNEL_PINS_UPDATE"
|
||||||
|
| "CHANNEL_UPDATE"
|
||||||
|
| "GUILD_BAN_ADD"
|
||||||
|
| "GUILD_BAN_REMOVE"
|
||||||
|
| "GUILD_CREATE"
|
||||||
|
| "GUILD_DELETE"
|
||||||
|
| "GUILD_EMOJIS_UPDATE"
|
||||||
|
| "GUILD_INTEGRATIONS_UPDATE"
|
||||||
|
| "GUILD_MEMBER_ADD"
|
||||||
|
| "GUILD_MEMBER_REMOVE"
|
||||||
|
| "GUILD_MEMBER_UPDATE"
|
||||||
|
| "GUILD_MEMBERS_CHUNK"
|
||||||
|
| "GUILD_ROLE_CREATE"
|
||||||
|
| "GUILD_ROLE_DELETE"
|
||||||
|
| "GUILD_ROLE_UPDATE"
|
||||||
|
| "GUILD_UPDATE"
|
||||||
|
| "INTERACTION_CREATE"
|
||||||
|
| "INVITE_CREATE"
|
||||||
|
| "INVITE_DELETE"
|
||||||
|
| "MESSAGE_CREATE"
|
||||||
|
| "MESSAGE_DELETE_BULK"
|
||||||
|
| "MESSAGE_DELETE"
|
||||||
|
| "MESSAGE_REACTION_ADD"
|
||||||
|
| "MESSAGE_REACTION_REMOVE_ALL"
|
||||||
|
| "MESSAGE_REACTION_REMOVE_EMOJI"
|
||||||
|
| "MESSAGE_REACTION_REMOVE"
|
||||||
|
| "MESSAGE_UPDATE"
|
||||||
|
| "PRESENCE_UPDATE"
|
||||||
|
| "TYPING_START"
|
||||||
|
| "USER_UPDATE"
|
||||||
|
| "VOICE_SERVER_UPDATE"
|
||||||
|
| "VOICE_STATE_UPDATE"
|
||||||
|
| "WEBHOOKS_UPDATE"
|
||||||
|
| "INTEGRATION_CREATE"
|
||||||
|
| "INTEGRATION_UPDATE"
|
||||||
|
| "INTEGRATION_DELETE"
|
||||||
|
| "STAGE_INSTANCE_CREATE"
|
||||||
|
| "STAGE_INSTANCE_UPDATE"
|
||||||
|
| "STAGE_INSTANCE_DELETE";
|
||||||
|
|
||||||
|
export type GatewayEventNames = GatewayDispatchEventNames | "READY" | "RESUMED";
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
import type { DiscordGatewayPayload } from "../types/gateway/gateway_payload.ts";
|
|
||||||
import { GatewayManager } from "../bot.ts";
|
|
||||||
|
|
||||||
/** Handler for processing all dispatch payloads that should be sent/forwarded to another server/vps/process. */
|
|
||||||
export async function handleDiscordPayload(gateway: GatewayManager, data: DiscordGatewayPayload, shardId: number) {
|
|
||||||
await fetch(gateway.url, {
|
|
||||||
headers: {
|
|
||||||
authorization: gateway.secretKey,
|
|
||||||
},
|
|
||||||
method: "post",
|
|
||||||
body: JSON.stringify({
|
|
||||||
shardId,
|
|
||||||
data,
|
|
||||||
}),
|
|
||||||
}).catch(console.error);
|
|
||||||
}
|
|
||||||
+34
-13
@@ -1,10 +1,13 @@
|
|||||||
import { eventHandlers, GatewayManager } from "../bot.ts";
|
import { GatewayManager } from "../bot.ts";
|
||||||
import { handlers } from "../handlers/mod.ts";
|
|
||||||
import { DiscordGatewayOpcodes } from "../types/codes/gateway_opcodes.ts";
|
import { DiscordGatewayOpcodes } from "../types/codes/gateway_opcodes.ts";
|
||||||
import type { DiscordGatewayPayload } from "../types/gateway/gateway_payload.ts";
|
import type { DiscordGatewayPayload } from "../types/gateway/gateway_payload.ts";
|
||||||
import type { DiscordHello } from "../types/gateway/hello.ts";
|
import type { DiscordHello } from "../types/gateway/hello.ts";
|
||||||
import type { DiscordReady } from "../types/gateway/ready.ts";
|
import type { DiscordReady } from "../types/gateway/ready.ts";
|
||||||
import { camelize, delay } from "../util/utils.ts";
|
import { Guild } from "../types/guilds/guild.ts";
|
||||||
|
import { UnavailableGuild } from "../types/guilds/unavailable_guild.ts";
|
||||||
|
import { SnakeCasedPropertiesDeep } from "../types/util.ts";
|
||||||
|
import { snowflakeToBigint } from "../util/bigint.ts";
|
||||||
|
import { delay } from "../util/utils.ts";
|
||||||
import { decompressWith } from "./deps.ts";
|
import { decompressWith } from "./deps.ts";
|
||||||
|
|
||||||
/** Handler for handling every message event from websocket. */
|
/** Handler for handling every message event from websocket. */
|
||||||
@@ -27,7 +30,7 @@ export async function handleOnMessage(gateway: GatewayManager, message: any, sha
|
|||||||
|
|
||||||
switch (messageData.op) {
|
switch (messageData.op) {
|
||||||
case DiscordGatewayOpcodes.Heartbeat:
|
case DiscordGatewayOpcodes.Heartbeat:
|
||||||
if (shard?.gateway.readyState !== WebSocket.OPEN) return;
|
if (shard?.ws.readyState !== WebSocket.OPEN) return;
|
||||||
|
|
||||||
shard.heartbeat.lastSentAt = Date.now();
|
shard.heartbeat.lastSentAt = Date.now();
|
||||||
// Discord randomly sends this requiring an immediate heartbeat back
|
// Discord randomly sends this requiring an immediate heartbeat back
|
||||||
@@ -91,15 +94,18 @@ export async function handleOnMessage(gateway: GatewayManager, message: any, sha
|
|||||||
// Important for RESUME
|
// Important for RESUME
|
||||||
if (messageData.t === "READY") {
|
if (messageData.t === "READY") {
|
||||||
const shard = gateway.shards.get(shardId);
|
const shard = gateway.shards.get(shardId);
|
||||||
|
const payload = messageData.d as DiscordReady;
|
||||||
if (shard) {
|
if (shard) {
|
||||||
shard.sessionId = (messageData.d as DiscordReady).session_id;
|
shard.sessionId = payload.session_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
payload.guilds.forEach((g) => gateway.cache.loadingGuildIds.add(snowflakeToBigint(g.id)));
|
||||||
|
|
||||||
gateway.loadingShards.get(shardId)?.resolve(true);
|
gateway.loadingShards.get(shardId)?.resolve(true);
|
||||||
gateway.loadingShards.delete(shardId);
|
gateway.loadingShards.delete(shardId);
|
||||||
// Wait few seconds to spawn next shard
|
// Wait few seconds to spawn next shard
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const bucket = gateway.buckets.get(shardId % gateway.botGatewayData.sessionStartLimit.maxConcurrency);
|
const bucket = gateway.buckets.get(shardId % gateway.maxConcurrency);
|
||||||
if (bucket) bucket.createNextShard.shift()?.();
|
if (bucket) bucket.createNextShard.shift()?.();
|
||||||
}, gateway.spawnShardDelay);
|
}, gateway.spawnShardDelay);
|
||||||
}
|
}
|
||||||
@@ -112,18 +118,33 @@ export async function handleOnMessage(gateway: GatewayManager, message: any, sha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gateway.url) await gateway.handleDiscordPayload(gateway, messageData, shardId);
|
// MUST HANDLE GUILD_CREATE EVENTS AS THEY ARE EXPENSIVE WITHOUT GATEWAY CACHE
|
||||||
else {
|
if (messageData.t === "GUILD_CREATE") {
|
||||||
eventHandlers.raw?.(messageData);
|
const id = snowflakeToBigint((messageData.d as SnakeCasedPropertiesDeep<Guild>).id);
|
||||||
await eventHandlers.dispatchRequirements?.(messageData, shardId);
|
|
||||||
|
|
||||||
if (messageData.op !== DiscordGatewayOpcodes.Dispatch) return;
|
// SHARD RESUMED MOST LIKELY, THEY EMIT GUILD CREATES. OR GUILD BECAME AVAILABLE AGAIN
|
||||||
|
if (gateway.cache.guildIds.has(id)) return;
|
||||||
|
|
||||||
if (!messageData.t) return;
|
// GUILD WAS MARKED LOADING IN READY EVENT, THIS WAS THE FIRST GUILD_CREATE TO ARRIVE
|
||||||
|
if (gateway.cache.loadingGuildIds.has(id)) {
|
||||||
|
// @ts-ignore override with a custom event
|
||||||
|
messageData.t = "GUILD_LOADED_DD";
|
||||||
|
gateway.cache.loadingGuildIds.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
return handlers[messageData.t]?.(camelize(messageData), shardId);
|
gateway.cache.guildIds.add(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MUST HANDLE GUILD_DELETE EVENTS FOR UNAVAILABLE
|
||||||
|
if (messageData.t === "GUILD_DELETE") {
|
||||||
|
if ((messageData.d as UnavailableGuild).unavailable) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IF NO TYPE THEN THIS SHOULD NOT BE SENT FORWARD
|
||||||
|
if (!messageData.t) return;
|
||||||
|
|
||||||
|
await gateway.handleDiscordPayload(gateway, messageData, shardId);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
export * from "./create_shard.ts";
|
export * from "./create_shard.ts";
|
||||||
export * from "./events.ts";
|
export * from "./events.ts";
|
||||||
export * from "./handle_discord_payload.ts";
|
|
||||||
export * from "./handle_on_message.ts";
|
export * from "./handle_on_message.ts";
|
||||||
export * from "./heartbeat.ts";
|
export * from "./heartbeat.ts";
|
||||||
export * from "./identify.ts";
|
export * from "./identify.ts";
|
||||||
|
|||||||
Reference in New Issue
Block a user