mirror of
https://github.com/discordeno/discordeno.git
synced 2026-06-16 03:18:17 +00:00
refactor: rename controllers to handlers and handlers to helpers (#660)
* refactor: rename controllers to handlers and handlers to helpers * fmt
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import {
|
||||
eventHandlers,
|
||||
lastShardID,
|
||||
setApplicationID,
|
||||
setBotID,
|
||||
} from "../bot.ts";
|
||||
import { DiscordPayload, ReadyPayload } from "../types/discord.ts";
|
||||
import { cache } from "../util/cache.ts";
|
||||
import { delay } from "../util/utils.ts";
|
||||
import { allowNextShard, basicShards } from "../ws/mod.ts";
|
||||
import { initialMemberLoadQueue } from "../structures/guild.ts";
|
||||
import { structures } from "../structures/mod.ts";
|
||||
import { cacheHandlers } from "../cache.ts";
|
||||
|
||||
export async function handleReady(
|
||||
data: DiscordPayload,
|
||||
shardID: number,
|
||||
) {
|
||||
// The bot has already started, the last shard is resumed, however.
|
||||
if (cache.isReady) return;
|
||||
|
||||
const payload = data.d as ReadyPayload;
|
||||
setBotID(payload.user.id);
|
||||
setApplicationID(payload.application.id);
|
||||
|
||||
// Triggered on each shard
|
||||
eventHandlers.shardReady?.(shardID);
|
||||
// Save when the READY event was received to prevent infinite load loops
|
||||
const now = Date.now();
|
||||
|
||||
const shard = basicShards.get(shardID);
|
||||
if (!shard) return;
|
||||
|
||||
// Set ready to false just to go sure
|
||||
shard.ready = false;
|
||||
// All guilds are unavailable at first
|
||||
shard.unavailableGuildIDs = new Set(payload.guilds.map((g) => g.id));
|
||||
|
||||
// Start ready check in 2 seconds
|
||||
setTimeout(() => checkReady(payload, shardID, now), 2000);
|
||||
|
||||
// Wait 5 seconds to spawn next shard
|
||||
await delay(5000);
|
||||
allowNextShard();
|
||||
}
|
||||
|
||||
// Don't pass the shard itself because unavailableGuilds won't be updated by the GUILD_CREATE event
|
||||
/** This function checks if the shard is fully loaded */
|
||||
function checkReady(payload: ReadyPayload, shardID: number, now: number) {
|
||||
const shard = basicShards.get(shardID);
|
||||
if (!shard) return;
|
||||
|
||||
// Check if all guilds were loaded
|
||||
if (shard.unavailableGuildIDs.size) {
|
||||
if (Date.now() - now > 10000) {
|
||||
eventHandlers.shardFailedToLoad?.(shardID, shard.unavailableGuildIDs);
|
||||
// Force execute the loaded function to prevent infinite loop
|
||||
loaded(shardID);
|
||||
} else {
|
||||
// Not all guilds were loaded but 10 seconds haven't passed so check again
|
||||
setTimeout(() => checkReady(payload, shardID, now), 2000);
|
||||
}
|
||||
} else {
|
||||
// All guilds were loaded
|
||||
loaded(shardID);
|
||||
}
|
||||
}
|
||||
|
||||
async function loaded(shardID: number) {
|
||||
const shard = basicShards.get(shardID);
|
||||
if (!shard) return;
|
||||
|
||||
shard.ready = true;
|
||||
|
||||
// If it is the last shard we can go full ready
|
||||
if (shardID === lastShardID - 1) {
|
||||
// Still some shards are loading so wait another 2 seconds for them
|
||||
if (basicShards.some((shard) => !shard.ready)) {
|
||||
setTimeout(() => loaded(shardID), 2000);
|
||||
} else {
|
||||
cache.isReady = true;
|
||||
eventHandlers.ready?.();
|
||||
|
||||
// All the members that came in on guild creates should now be processed 1 by 1
|
||||
for (const [guildID, members] of initialMemberLoadQueue.entries()) {
|
||||
await Promise.allSettled(
|
||||
members.map(async (member) => {
|
||||
const memberStruct = await structures.createMemberStruct(
|
||||
member,
|
||||
guildID,
|
||||
);
|
||||
|
||||
return cacheHandlers.set(
|
||||
"members",
|
||||
memberStruct.id,
|
||||
memberStruct,
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { ChannelCreatePayload, DiscordPayload } from "../../types/mod.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleChannelCreate(data: DiscordPayload) {
|
||||
const payload = data.d as ChannelCreatePayload;
|
||||
|
||||
const channelStruct = await structures.createChannelStruct(payload);
|
||||
await cacheHandlers.set("channels", channelStruct.id, channelStruct);
|
||||
|
||||
eventHandlers.channelCreate?.(channelStruct);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import {
|
||||
ChannelCreatePayload,
|
||||
ChannelTypes,
|
||||
DiscordPayload,
|
||||
} from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleChannelDelete(data: DiscordPayload) {
|
||||
const payload = data.d as ChannelCreatePayload;
|
||||
|
||||
const cachedChannel = await cacheHandlers.get("channels", payload.id);
|
||||
if (!cachedChannel) return;
|
||||
|
||||
if (cachedChannel.type === ChannelTypes.GUILD_VOICE && payload.guild_id) {
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
|
||||
if (guild) {
|
||||
return Promise.all(guild.voiceStates.map(async (vs, key) => {
|
||||
if (vs.channelID !== payload.id) return;
|
||||
|
||||
// Since this channel was deleted all voice states for this channel should be deleted
|
||||
guild.voiceStates.delete(key);
|
||||
|
||||
const member = await cacheHandlers.get("members", vs.userID);
|
||||
if (!member) return;
|
||||
|
||||
eventHandlers.voiceChannelLeave?.(member, vs.channelID);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
await cacheHandlers.delete("channels", payload.id);
|
||||
cacheHandlers.forEach("messages", (message) => {
|
||||
if (message.channelID === payload.id) {
|
||||
cacheHandlers.delete("messages", message.id);
|
||||
}
|
||||
});
|
||||
eventHandlers.channelDelete?.(cachedChannel);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import {
|
||||
DiscordChannelPinsUpdateEvent,
|
||||
DiscordPayload,
|
||||
} from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleChannelPinsUpdate(data: DiscordPayload) {
|
||||
const payload = data.d as DiscordChannelPinsUpdateEvent;
|
||||
|
||||
const channel = await cacheHandlers.get("channels", payload.channel_id);
|
||||
if (!channel) return;
|
||||
|
||||
const guild = payload.guild_id
|
||||
? await cacheHandlers.get("guilds", payload.guild_id)
|
||||
: undefined;
|
||||
|
||||
eventHandlers.channelPinsUpdate?.(channel, guild, payload.last_pin_timestamp);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { ChannelCreatePayload, DiscordPayload } from "../../types/mod.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleChannelUpdate(data: DiscordPayload) {
|
||||
const payload = data.d as ChannelCreatePayload;
|
||||
const cachedChannel = await cacheHandlers.get("channels", payload.id);
|
||||
|
||||
const channelStruct = await structures.createChannelStruct(payload);
|
||||
await cacheHandlers.set("channels", channelStruct.id, channelStruct);
|
||||
|
||||
if (!cachedChannel) return;
|
||||
|
||||
eventHandlers.channelUpdate?.(channelStruct, cachedChannel);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { ApplicationCommandEvent, DiscordPayload } from "../../types/mod.ts";
|
||||
|
||||
export function handleApplicationCommandCreate(
|
||||
data: DiscordPayload,
|
||||
) {
|
||||
const {
|
||||
guild_id: guildID,
|
||||
application_id: applicationID,
|
||||
...rest
|
||||
} = data.d as ApplicationCommandEvent;
|
||||
|
||||
eventHandlers.applicationCommandCreate?.({
|
||||
...rest,
|
||||
guildID,
|
||||
applicationID,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { ApplicationCommandEvent, DiscordPayload } from "../../types/mod.ts";
|
||||
|
||||
export function handleApplicationCommandDelete(data: DiscordPayload) {
|
||||
const {
|
||||
application_id: applicationID,
|
||||
guild_id: guildID,
|
||||
...rest
|
||||
} = data.d as ApplicationCommandEvent;
|
||||
|
||||
eventHandlers.applicationCommandDelete?.({
|
||||
...rest,
|
||||
guildID,
|
||||
applicationID,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { ApplicationCommandEvent, DiscordPayload } from "../../types/mod.ts";
|
||||
|
||||
export function handleApplicationCommandUpdate(data: DiscordPayload) {
|
||||
const {
|
||||
application_id: applicationID,
|
||||
guild_id: guildID,
|
||||
...rest
|
||||
} = data.d as ApplicationCommandEvent;
|
||||
|
||||
eventHandlers.applicationCommandUpdate?.({
|
||||
...rest,
|
||||
guildID,
|
||||
applicationID,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, GuildBanPayload } from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildBanAdd(data: DiscordPayload) {
|
||||
const payload = data.d as GuildBanPayload;
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
const member = await cacheHandlers.get("members", payload.user.id);
|
||||
eventHandlers.guildBanAdd?.(guild, payload.user, member);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, GuildBanPayload } from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildBanRemove(data: DiscordPayload) {
|
||||
const payload = data.d as GuildBanPayload;
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
const member = await cacheHandlers.get("members", payload.user.id);
|
||||
eventHandlers.guildBanRemove?.(guild, payload.user, member);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { CreateGuildPayload, DiscordPayload } from "../../types/mod.ts";
|
||||
import { cache } from "../../util/cache.ts";
|
||||
import { basicShards } from "../../ws/shard.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildCreate(
|
||||
data: DiscordPayload,
|
||||
shardID: number,
|
||||
) {
|
||||
const payload = data.d as CreateGuildPayload;
|
||||
// When shards resume they emit GUILD_CREATE again.
|
||||
if (await cacheHandlers.has("guilds", payload.id)) return;
|
||||
|
||||
const guildStruct = await structures.createGuildStruct(
|
||||
data.d as CreateGuildPayload,
|
||||
shardID,
|
||||
);
|
||||
await cacheHandlers.set("guilds", guildStruct.id, guildStruct);
|
||||
|
||||
const shard = basicShards.get(shardID);
|
||||
|
||||
if (shard?.unavailableGuildIDs.has(payload.id)) {
|
||||
await cacheHandlers.delete("unavailableGuilds", payload.id);
|
||||
|
||||
shard.unavailableGuildIDs.delete(payload.id);
|
||||
}
|
||||
|
||||
if (!cache.isReady) return eventHandlers.guildLoaded?.(guildStruct);
|
||||
eventHandlers.guildCreate?.(guildStruct);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, GuildDeletePayload } from "../../types/mod.ts";
|
||||
import { basicShards } from "../../ws/shard.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildDelete(
|
||||
data: DiscordPayload,
|
||||
shardID: number,
|
||||
) {
|
||||
const payload = data.d as GuildDeletePayload;
|
||||
cacheHandlers.forEach("messages", (message) => {
|
||||
if (message.guildID === payload.id) {
|
||||
cacheHandlers.delete("messages", message.id);
|
||||
}
|
||||
});
|
||||
|
||||
cacheHandlers.forEach("channels", (channel) => {
|
||||
if (channel.guildID === payload.id) {
|
||||
cacheHandlers.delete("channels", channel.id);
|
||||
}
|
||||
});
|
||||
|
||||
cacheHandlers.forEach("members", async (member) => {
|
||||
if (!member.guilds.has(payload.id)) return;
|
||||
|
||||
member.guilds.delete(payload.id);
|
||||
|
||||
if (!member.guilds.size) {
|
||||
await cacheHandlers.delete("members", member.id);
|
||||
return;
|
||||
}
|
||||
|
||||
await cacheHandlers.set("members", member.id, member);
|
||||
});
|
||||
|
||||
if (payload.unavailable) {
|
||||
const shard = basicShards.get(shardID);
|
||||
if (shard) shard.unavailableGuildIDs.add(payload.id);
|
||||
|
||||
return cacheHandlers.set("unavailableGuilds", payload.id, Date.now());
|
||||
}
|
||||
|
||||
const guild = await cacheHandlers.get("guilds", payload.id);
|
||||
if (!guild) return;
|
||||
|
||||
await cacheHandlers.delete("guilds", payload.id);
|
||||
|
||||
eventHandlers.guildDelete?.(guild);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, GuildEmojisUpdatePayload } from "../../types/mod.ts";
|
||||
import { Collection } from "../../util/collection.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildEmojisUpdate(data: DiscordPayload) {
|
||||
const payload = data.d as GuildEmojisUpdatePayload;
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
const cachedEmojis = guild.emojis;
|
||||
guild.emojis = new Collection(
|
||||
payload.emojis.map((emoji) => [emoji.id ?? emoji.name, emoji]),
|
||||
);
|
||||
|
||||
cacheHandlers.set("guilds", payload.guild_id, guild);
|
||||
|
||||
eventHandlers.guildEmojisUpdate?.(
|
||||
guild,
|
||||
guild.emojis,
|
||||
cachedEmojis,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import {
|
||||
DiscordGuildIntegrationsUpdateEvent,
|
||||
DiscordPayload,
|
||||
} from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildIntegrationsUpdate(
|
||||
data: DiscordPayload,
|
||||
) {
|
||||
const payload = data.d as DiscordGuildIntegrationsUpdateEvent;
|
||||
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
eventHandlers.guildIntegrationsUpdate?.(guild);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { DiscordPayload, GuildMemberChunkPayload } from "../../types/mod.ts";
|
||||
import { cache } from "../../util/cache.ts";
|
||||
import { Collection } from "../../util/collection.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildMembersChunk(data: DiscordPayload) {
|
||||
const payload = data.d as GuildMemberChunkPayload;
|
||||
|
||||
const members = await Promise.all(
|
||||
payload.members.map(async (member) => {
|
||||
const memberStruct = await structures.createMemberStruct(
|
||||
member,
|
||||
payload.guild_id,
|
||||
);
|
||||
await cacheHandlers.set("members", memberStruct.id, memberStruct);
|
||||
|
||||
return memberStruct;
|
||||
}),
|
||||
);
|
||||
|
||||
// Check if its necessary to resolve the fetchmembers promise for this chunk or if more chunks will be coming
|
||||
if (
|
||||
payload.nonce
|
||||
) {
|
||||
const resolve = cache.fetchAllMembersProcessingRequests.get(payload.nonce);
|
||||
if (!resolve) return;
|
||||
|
||||
if (payload.chunk_index + 1 === payload.chunk_count) {
|
||||
cache.fetchAllMembersProcessingRequests.delete(payload.nonce);
|
||||
// Only 1 chunk most likely is all members or users only request a small amount of users
|
||||
if (payload.chunk_count === 1) {
|
||||
return resolve(new Collection(members.map((m) => [m.id, m])));
|
||||
}
|
||||
|
||||
return resolve(
|
||||
await cacheHandlers.filter(
|
||||
"members",
|
||||
(m) => m.guilds.has(payload.guild_id),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, GuildMemberAddPayload } from "../../types/mod.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildMemberAdd(data: DiscordPayload) {
|
||||
const payload = data.d as GuildMemberAddPayload;
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
guild.memberCount++;
|
||||
const memberStruct = await structures.createMemberStruct(
|
||||
payload,
|
||||
payload.guild_id,
|
||||
);
|
||||
await cacheHandlers.set("members", memberStruct.id, memberStruct);
|
||||
|
||||
eventHandlers.guildMemberAdd?.(guild, memberStruct);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, GuildBanPayload } from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildMemberRemove(data: DiscordPayload) {
|
||||
const payload = data.d as GuildBanPayload;
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
guild.memberCount--;
|
||||
const member = await cacheHandlers.get("members", payload.user.id);
|
||||
eventHandlers.guildMemberRemove?.(guild, payload.user, member);
|
||||
|
||||
member?.guilds.delete(guild.id);
|
||||
if (member && !member.guilds.size) {
|
||||
await cacheHandlers.delete("members", member.id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, GuildMemberUpdatePayload } from "../../types/mod.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildMemberUpdate(data: DiscordPayload) {
|
||||
const payload = data.d as GuildMemberUpdatePayload;
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
const cachedMember = await cacheHandlers.get("members", payload.user.id);
|
||||
const guildMember = cachedMember?.guilds.get(payload.guild_id);
|
||||
|
||||
const newMemberData = {
|
||||
...payload,
|
||||
// deno-lint-ignore camelcase
|
||||
premium_since: payload.premium_since || undefined,
|
||||
// deno-lint-ignore camelcase
|
||||
joined_at: new Date(guildMember?.joinedAt || Date.now())
|
||||
.toISOString(),
|
||||
deaf: guildMember?.deaf || false,
|
||||
mute: guildMember?.mute || false,
|
||||
roles: payload.roles,
|
||||
};
|
||||
const memberStruct = await structures.createMemberStruct(
|
||||
newMemberData,
|
||||
payload.guild_id,
|
||||
);
|
||||
await cacheHandlers.set("members", memberStruct.id, memberStruct);
|
||||
|
||||
if (guildMember?.nick !== payload.nick) {
|
||||
eventHandlers.nicknameUpdate?.(
|
||||
guild,
|
||||
memberStruct,
|
||||
payload.nick,
|
||||
guildMember?.nick,
|
||||
);
|
||||
}
|
||||
|
||||
if (payload.pending === false && guildMember?.pending === true) {
|
||||
eventHandlers.membershipScreeningPassed?.(guild, memberStruct);
|
||||
}
|
||||
|
||||
const roleIDs = guildMember?.roles || [];
|
||||
|
||||
roleIDs.forEach((id) => {
|
||||
if (!payload.roles.includes(id)) {
|
||||
eventHandlers.roleLost?.(guild, memberStruct, id);
|
||||
}
|
||||
});
|
||||
|
||||
payload.roles.forEach((id) => {
|
||||
if (!roleIDs.includes(id)) {
|
||||
eventHandlers.roleGained?.(guild, memberStruct, id);
|
||||
}
|
||||
});
|
||||
|
||||
eventHandlers.guildMemberUpdate?.(guild, memberStruct, cachedMember);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import {
|
||||
DiscordPayload,
|
||||
GuildRoleDeletePayload,
|
||||
GuildRolePayload,
|
||||
} from "../../types/mod.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildRoleCreate(data: DiscordPayload) {
|
||||
const payload = data.d as GuildRolePayload;
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
const role = await structures.createRoleStruct(payload.role);
|
||||
guild.roles = guild.roles.set(payload.role.id, role);
|
||||
await cacheHandlers.set("guilds", payload.guild_id, guild);
|
||||
|
||||
eventHandlers.roleCreate?.(guild, role);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, GuildRoleDeletePayload } from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildRoleDelete(data: DiscordPayload) {
|
||||
const payload = data.d as GuildRoleDeletePayload;
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
const cachedRole = guild.roles.get(payload.role_id)!;
|
||||
guild.roles.delete(payload.role_id);
|
||||
|
||||
if (cachedRole) eventHandlers.roleDelete?.(guild, cachedRole);
|
||||
|
||||
// For bots without GUILD_MEMBERS member.roles is never updated breaking permissions checking.
|
||||
cacheHandlers.forEach("members", (member) => {
|
||||
// Not in the relevant guild so just skip.
|
||||
if (!member.guilds.has(guild.id)) return;
|
||||
|
||||
member.guilds.forEach((g) => {
|
||||
// Member does not have this role
|
||||
if (!g.roles.includes(payload.role_id)) return;
|
||||
// Remove this role from the members cache
|
||||
g.roles = g.roles.filter((id) => id !== payload.role_id);
|
||||
cacheHandlers.set("members", member.id, member);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import {
|
||||
DiscordPayload,
|
||||
GuildRoleDeletePayload,
|
||||
GuildRolePayload,
|
||||
} from "../../types/mod.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildRoleUpdate(data: DiscordPayload) {
|
||||
const payload = data.d as GuildRolePayload;
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
const cachedRole = guild.roles.get(payload.role.id);
|
||||
if (!cachedRole) return;
|
||||
|
||||
const role = await structures.createRoleStruct(payload.role);
|
||||
guild.roles.set(payload.role.id, role);
|
||||
await cacheHandlers.set("guilds", guild.id, guild);
|
||||
|
||||
eventHandlers.roleUpdate?.(guild, role, cachedRole);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import {
|
||||
DiscordPayload,
|
||||
GuildUpdateChange,
|
||||
UpdateGuildPayload,
|
||||
} from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleGuildUpdate(data: DiscordPayload) {
|
||||
const payload = data.d as UpdateGuildPayload;
|
||||
const cachedGuild = await cacheHandlers.get("guilds", payload.id);
|
||||
if (!cachedGuild) return;
|
||||
|
||||
const keysToSkip = [
|
||||
"roles",
|
||||
"guild_hashes",
|
||||
"guild_id",
|
||||
"max_members",
|
||||
"emojis",
|
||||
];
|
||||
|
||||
const changes = Object.entries(payload)
|
||||
.map(([key, value]) => {
|
||||
if (keysToSkip.includes(key)) return;
|
||||
|
||||
// @ts-ignore index signature
|
||||
const cachedValue = cachedGuild[key];
|
||||
if (cachedValue !== value) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
// @ts-ignore index signature
|
||||
cachedGuild[key] = value;
|
||||
return { key, oldValue: cachedValue, value };
|
||||
}
|
||||
}).filter((change) => change) as GuildUpdateChange[];
|
||||
|
||||
await cacheHandlers.set("guilds", payload.id, cachedGuild);
|
||||
|
||||
eventHandlers.guildUpdate?.(cachedGuild, changes);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import {
|
||||
DiscordPayload,
|
||||
IntegrationCreateUpdateEvent,
|
||||
} from "../../types/mod.ts";
|
||||
|
||||
export function handleIntegrationCreate(
|
||||
data: DiscordPayload,
|
||||
) {
|
||||
const {
|
||||
guild_id: guildID,
|
||||
enable_emoticons: enableEmoticons,
|
||||
expire_behavior: expireBehavior,
|
||||
expire_grace_period: expireGracePeriod,
|
||||
subscriber_count: subscriberCount,
|
||||
role_id: roleID,
|
||||
synced_at: syncedAt,
|
||||
...rest
|
||||
} = data.d as IntegrationCreateUpdateEvent;
|
||||
|
||||
eventHandlers.integrationCreate?.({
|
||||
...rest,
|
||||
guildID,
|
||||
enableEmoticons,
|
||||
expireBehavior,
|
||||
expireGracePeriod,
|
||||
syncedAt,
|
||||
subscriberCount,
|
||||
roleID,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, IntegrationDeleteEvent } from "../../types/mod.ts";
|
||||
|
||||
export function handleIntegrationDelete(data: DiscordPayload) {
|
||||
const {
|
||||
guild_id: guildID,
|
||||
application_id: applicationID,
|
||||
...rest
|
||||
} = data.d as IntegrationDeleteEvent;
|
||||
|
||||
eventHandlers.integrationDelete?.({
|
||||
...rest,
|
||||
applicationID,
|
||||
guildID,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import {
|
||||
DiscordPayload,
|
||||
IntegrationCreateUpdateEvent,
|
||||
} from "../../types/mod.ts";
|
||||
|
||||
export function handleIntegrationUpdate(data: DiscordPayload) {
|
||||
const {
|
||||
enable_emoticons: enableEmoticons,
|
||||
expire_behavior: expireBehavior,
|
||||
expire_grace_period: expireGracePeriod,
|
||||
role_id: roleID,
|
||||
subscriber_count: subscriberCount,
|
||||
synced_at: syncedAt,
|
||||
guild_id: guildID,
|
||||
...rest
|
||||
} = data.d as IntegrationCreateUpdateEvent;
|
||||
|
||||
eventHandlers.integrationUpdate?.({
|
||||
...rest,
|
||||
guildID,
|
||||
subscriberCount,
|
||||
enableEmoticons,
|
||||
expireGracePeriod,
|
||||
roleID,
|
||||
expireBehavior,
|
||||
syncedAt,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, InteractionCommandPayload } from "../../types/mod.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleInteractionCreate(data: DiscordPayload) {
|
||||
const payload = data.d as InteractionCommandPayload;
|
||||
const memberStruct = await structures.createMemberStruct(
|
||||
payload.member,
|
||||
payload.guild_id,
|
||||
);
|
||||
await cacheHandlers.set("members", memberStruct.id, memberStruct);
|
||||
|
||||
eventHandlers.interactionCreate?.(
|
||||
{
|
||||
...payload,
|
||||
member: memberStruct,
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, InviteCreateEvent } from "../../types/mod.ts";
|
||||
|
||||
export function handleInviteCreate(payload: DiscordPayload) {
|
||||
if (payload.t !== "INVITE_CREATE") return;
|
||||
//TODO: replace with tocamelcase
|
||||
const {
|
||||
channel_id: channelID,
|
||||
created_at: createdAt,
|
||||
max_age: maxAge,
|
||||
guild_id: guildID,
|
||||
target_user: targetUser,
|
||||
target_user_type: targetUserType,
|
||||
max_uses: maxUses,
|
||||
...rest
|
||||
} = payload.d as InviteCreateEvent;
|
||||
|
||||
eventHandlers.inviteCreate?.({
|
||||
...rest,
|
||||
channelID,
|
||||
guildID,
|
||||
maxAge,
|
||||
targetUser,
|
||||
targetUserType,
|
||||
maxUses,
|
||||
createdAt,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, InviteDeleteEvent } from "../../types/mod.ts";
|
||||
|
||||
export function handleInviteDelete(payload: DiscordPayload) {
|
||||
if (payload.t !== "INVITE_DELETE") return;
|
||||
|
||||
const {
|
||||
channel_id: channelID,
|
||||
guild_id: guildID,
|
||||
...rest
|
||||
} = payload.d as InviteDeleteEvent;
|
||||
|
||||
eventHandlers.inviteDelete?.({
|
||||
...rest,
|
||||
channelID,
|
||||
guildID,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, MessageCreateOptions } from "../../types/mod.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleMessageCreate(data: DiscordPayload) {
|
||||
const payload = data.d as MessageCreateOptions;
|
||||
const channel = await cacheHandlers.get("channels", payload.channel_id);
|
||||
if (channel) channel.lastMessageID = payload.id;
|
||||
|
||||
const guild = payload.guild_id
|
||||
? await cacheHandlers.get("guilds", payload.guild_id)
|
||||
: undefined;
|
||||
|
||||
if (payload.member && guild) {
|
||||
// If in a guild cache the author as a member
|
||||
const memberStruct = await structures.createMemberStruct(
|
||||
{ ...payload.member, user: payload.author },
|
||||
guild.id,
|
||||
);
|
||||
await cacheHandlers.set("members", memberStruct.id, memberStruct);
|
||||
}
|
||||
|
||||
await Promise.all(payload.mentions.map(async (mention) => {
|
||||
// Cache the member if its a valid member
|
||||
if (mention.member && guild) {
|
||||
const memberStruct = await structures.createMemberStruct(
|
||||
{ ...mention.member, user: mention },
|
||||
guild.id,
|
||||
);
|
||||
|
||||
return cacheHandlers.set("members", memberStruct.id, memberStruct);
|
||||
}
|
||||
}));
|
||||
|
||||
const message = await structures.createMessageStruct(payload);
|
||||
// Cache the message
|
||||
await cacheHandlers.set("messages", payload.id, message);
|
||||
|
||||
eventHandlers.messageCreate?.(message);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, MessageDeletePayload } from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleMessageDelete(data: DiscordPayload) {
|
||||
const payload = data.d as MessageDeletePayload;
|
||||
const channel = await cacheHandlers.get("channels", payload.channel_id);
|
||||
if (!channel) return;
|
||||
|
||||
eventHandlers.messageDelete?.(
|
||||
{ id: payload.id, channel },
|
||||
await cacheHandlers.get("messages", payload.id),
|
||||
);
|
||||
|
||||
await cacheHandlers.delete("messages", payload.id);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, MessageDeleteBulkPayload } from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleMessageDeleteBulk(data: DiscordPayload) {
|
||||
const payload = data.d as MessageDeleteBulkPayload;
|
||||
const channel = await cacheHandlers.get("channels", payload.channel_id);
|
||||
if (!channel) return;
|
||||
|
||||
return Promise.all(payload.ids.map(async (id) => {
|
||||
eventHandlers.messageDelete?.(
|
||||
{ id, channel },
|
||||
await cacheHandlers.get("messages", id),
|
||||
);
|
||||
await cacheHandlers.delete("messages", id);
|
||||
}));
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { botID, eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, MessageReactionPayload } from "../../types/mod.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleMessageReactionAdd(data: DiscordPayload) {
|
||||
const payload = data.d as MessageReactionPayload;
|
||||
const message = await cacheHandlers.get("messages", payload.message_id);
|
||||
|
||||
if (message) {
|
||||
const reactionExisted = message.reactions?.find(
|
||||
(reaction) =>
|
||||
reaction.emoji.id === payload.emoji.id &&
|
||||
reaction.emoji.name === payload.emoji.name,
|
||||
);
|
||||
|
||||
if (reactionExisted) reactionExisted.count++;
|
||||
else {
|
||||
const newReaction = {
|
||||
count: 1,
|
||||
me: payload.user_id === botID,
|
||||
emoji: { ...payload.emoji, id: payload.emoji.id || undefined },
|
||||
};
|
||||
message.reactions = message.reactions
|
||||
? [...message.reactions, newReaction]
|
||||
: [newReaction];
|
||||
}
|
||||
|
||||
await cacheHandlers.set("messages", payload.message_id, message);
|
||||
}
|
||||
|
||||
if (payload.member && payload.guild_id) {
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (guild) {
|
||||
const memberStruct = await structures.createMemberStruct(
|
||||
payload.member,
|
||||
guild.id,
|
||||
);
|
||||
await cacheHandlers.set("members", memberStruct.id, memberStruct);
|
||||
}
|
||||
}
|
||||
|
||||
const uncachedOptions = {
|
||||
...payload,
|
||||
id: payload.message_id,
|
||||
channelID: payload.channel_id,
|
||||
guildID: payload.guild_id || "",
|
||||
};
|
||||
|
||||
eventHandlers.reactionAdd?.(
|
||||
uncachedOptions,
|
||||
payload.emoji,
|
||||
payload.user_id,
|
||||
message,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import { botID, eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, MessageReactionPayload } from "../../types/mod.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleMessageReactionRemove(
|
||||
data: DiscordPayload,
|
||||
) {
|
||||
const payload = data.d as MessageReactionPayload;
|
||||
const message = await cacheHandlers.get("messages", payload.message_id);
|
||||
|
||||
if (message) {
|
||||
const reactionExisted = message.reactions?.find(
|
||||
(reaction) =>
|
||||
reaction.emoji.id === payload.emoji.id &&
|
||||
reaction.emoji.name === payload.emoji.name,
|
||||
);
|
||||
|
||||
if (reactionExisted) reactionExisted.count--;
|
||||
else {
|
||||
const newReaction = {
|
||||
count: 1,
|
||||
me: payload.user_id === botID,
|
||||
emoji: { ...payload.emoji, id: payload.emoji.id || undefined },
|
||||
};
|
||||
message.reactions = message.reactions
|
||||
? [...message.reactions, newReaction]
|
||||
: [newReaction];
|
||||
}
|
||||
|
||||
await cacheHandlers.set("messages", payload.message_id, message);
|
||||
}
|
||||
|
||||
if (payload.member && payload.guild_id) {
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (guild) {
|
||||
const memberStruct = await structures.createMemberStruct(
|
||||
payload.member,
|
||||
guild.id,
|
||||
);
|
||||
await cacheHandlers.set("members", memberStruct.id, memberStruct);
|
||||
}
|
||||
}
|
||||
|
||||
const uncachedOptions = {
|
||||
...payload,
|
||||
id: payload.message_id,
|
||||
channelID: payload.channel_id,
|
||||
guildID: payload.guild_id,
|
||||
};
|
||||
|
||||
eventHandlers.reactionRemove?.(
|
||||
uncachedOptions,
|
||||
payload.emoji,
|
||||
payload.user_id,
|
||||
message,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { BaseMessageReactionPayload, DiscordPayload } from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleMessageReactionRemoveAll(
|
||||
data: DiscordPayload,
|
||||
) {
|
||||
const payload = data.d as BaseMessageReactionPayload;
|
||||
const message = await cacheHandlers.get("messages", payload.message_id);
|
||||
|
||||
if (message?.reactions) {
|
||||
message.reactions = undefined;
|
||||
|
||||
await cacheHandlers.set("messages", payload.message_id, message);
|
||||
}
|
||||
|
||||
eventHandlers.reactionRemoveAll?.(data.d as BaseMessageReactionPayload);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { botID, eventHandlers } from "../../bot.ts";
|
||||
import {
|
||||
DiscordPayload,
|
||||
MessageReactionRemoveEmojiPayload,
|
||||
} from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleMessageReactionRemoveEmoji(
|
||||
data: DiscordPayload,
|
||||
) {
|
||||
const payload = data.d as MessageReactionRemoveEmojiPayload;
|
||||
const message = await cacheHandlers.get("messages", payload.message_id);
|
||||
|
||||
if (message?.reactions) {
|
||||
message.reactions = message.reactions?.filter(
|
||||
(reaction) =>
|
||||
!(
|
||||
reaction.emoji.id === payload.emoji.id &&
|
||||
reaction.emoji.name === payload.emoji.name
|
||||
),
|
||||
);
|
||||
|
||||
await cacheHandlers.set("messages", payload.message_id, message);
|
||||
}
|
||||
|
||||
eventHandlers.reactionRemoveEmoji?.(
|
||||
data.d as MessageReactionRemoveEmojiPayload,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, MessageCreateOptions } from "../../types/mod.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleMessageUpdate(data: DiscordPayload) {
|
||||
const payload = data.d as MessageCreateOptions;
|
||||
const channel = await cacheHandlers.get("channels", payload.channel_id);
|
||||
if (!channel) return;
|
||||
|
||||
const cachedMessage = await cacheHandlers.get("messages", payload.id);
|
||||
if (!cachedMessage) return;
|
||||
|
||||
const oldMessage = {
|
||||
attachments: cachedMessage.attachments,
|
||||
content: cachedMessage.content,
|
||||
embeds: cachedMessage.embeds,
|
||||
editedTimestamp: cachedMessage.editedTimestamp,
|
||||
tts: cachedMessage.tts,
|
||||
pinned: cachedMessage.pinned,
|
||||
};
|
||||
|
||||
// Messages with embeds can trigger update but they wont have edited_timestamp
|
||||
if (
|
||||
!payload.edited_timestamp ||
|
||||
(cachedMessage.content === payload.content)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const message = await structures.createMessageStruct(payload);
|
||||
|
||||
await cacheHandlers.set("messages", payload.id, message);
|
||||
|
||||
eventHandlers.messageUpdate?.(message, oldMessage);
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
import { handleChannelCreate } from "./channels/CHANNEL_CREATE.ts";
|
||||
import { handleChannelDelete } from "./channels/CHANNEL_DELETE.ts";
|
||||
import { handleChannelPinsUpdate } from "./channels/CHANNEL_PINS_UPDATE.ts";
|
||||
import { handleChannelUpdate } from "./channels/CHANNEL_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 { handleGuildBanAdd } from "./guilds/GUILD_BAN_ADD.ts";
|
||||
import { handleGuildBanRemove } from "./guilds/GUILD_BAN_REMOVE.ts";
|
||||
import { handleGuildCreate } from "./guilds/GUILD_CREATE.ts";
|
||||
import { handleGuildDelete } from "./guilds/GUILD_DELETE.ts";
|
||||
import { handleGuildEmojisUpdate } from "./guilds/GUILD_EMOJIS_UPDATE.ts";
|
||||
import { handleGuildIntegrationsUpdate } from "./guilds/GUILD_INTEGRATIONS_UPDATE.ts";
|
||||
import { handleGuildMembersChunk } from "./guilds/GUILD_MEMBERS_CHUNK.ts";
|
||||
import { handleGuildMemberAdd } from "./guilds/GUILD_MEMBER_ADD.ts";
|
||||
import { handleGuildMemberRemove } from "./guilds/GUILD_MEMBER_REMOVE.ts";
|
||||
import { handleGuildMemberUpdate } from "./guilds/GUILD_MEMBER_UPDATE.ts";
|
||||
import { handleGuildRoleCreate } from "./guilds/GUILD_ROLE_CREATE.ts";
|
||||
import { handleGuildRoleDelete } from "./guilds/GUILD_ROLE_DELETE.ts";
|
||||
import { handleGuildRoleUpdate } from "./guilds/GUILD_ROLE_UPDATE.ts";
|
||||
import { handleGuildUpdate } from "./guilds/GUILD_UPDATE.ts";
|
||||
import { handleIntegrationCreate } from "./integrations/INTEGRATION_CREATE.ts";
|
||||
import { handleIntegrationDelete } from "./integrations/INTEGRATION_DELETE.ts";
|
||||
import { handleIntegrationUpdate } from "./integrations/INTEGRATION_UPDATE.ts";
|
||||
import { handleInteractionCreate } from "./interactions/INTERACTION_CREATE.ts";
|
||||
import { handleInviteCreate } from "./invites/INVITE_CREATE.ts";
|
||||
import { handleMessageCreate } from "./messages/MESSAGE_CREATE.ts";
|
||||
import { handleMessageDelete } from "./messages/MESSAGE_DELETE.ts";
|
||||
import { handleMessageDeleteBulk } from "./messages/MESSAGE_DELETE_BULK.ts";
|
||||
import { handleMessageReactionAdd } from "./messages/MESSAGE_REACTION_ADD.ts";
|
||||
import { handleMessageReactionRemove } from "./messages/MESSAGE_REACTION_REMOVE.ts";
|
||||
import { handleMessageReactionRemoveAll } from "./messages/MESSAGE_REACTION_REMOVE_ALL.ts";
|
||||
import { handleMessageReactionRemoveEmoji } from "./messages/MESSAGE_REACTION_REMOVE_EMOJI.ts";
|
||||
import { handleMessageUpdate } from "./messages/MESSAGE_UPDATE.ts";
|
||||
import { handlePresenceUpdate } from "./presence/PRESENCE_UPDATE.ts";
|
||||
import { handleTypingStart } from "./presence/TYPING_START.ts";
|
||||
import { handleUserUpdate } from "./presence/USER_UPDATE.ts";
|
||||
import { handleReady } from "./READY.ts";
|
||||
import { handleVoiceServerUpdate } from "./voice/VOICE_SERVER_UPDATE.ts";
|
||||
import { handleVoiceStateUpdate } from "./voice/VOICE_STATE_UPDATE.ts";
|
||||
import { handleWebhooksUpdate } from "./webhooks/WEBHOOKS_UPDATE.ts";
|
||||
|
||||
export {
|
||||
handleApplicationCommandCreate,
|
||||
handleApplicationCommandDelete,
|
||||
handleApplicationCommandUpdate,
|
||||
handleChannelCreate,
|
||||
handleChannelDelete,
|
||||
handleChannelPinsUpdate,
|
||||
handleChannelUpdate,
|
||||
handleGuildBanAdd,
|
||||
handleGuildBanRemove,
|
||||
handleGuildCreate,
|
||||
handleGuildDelete,
|
||||
handleGuildEmojisUpdate,
|
||||
handleGuildIntegrationsUpdate,
|
||||
handleGuildMemberAdd,
|
||||
handleGuildMemberRemove,
|
||||
handleGuildMembersChunk,
|
||||
handleGuildMemberUpdate,
|
||||
handleGuildRoleCreate,
|
||||
handleGuildRoleDelete,
|
||||
handleGuildRoleUpdate,
|
||||
handleGuildUpdate,
|
||||
handleIntegrationCreate,
|
||||
handleIntegrationDelete,
|
||||
handleIntegrationUpdate,
|
||||
handleInteractionCreate,
|
||||
handleInviteCreate,
|
||||
handleMessageCreate,
|
||||
handleMessageDelete,
|
||||
handleMessageDeleteBulk,
|
||||
handleMessageReactionAdd,
|
||||
handleMessageReactionRemove,
|
||||
handleMessageReactionRemoveAll,
|
||||
handleMessageReactionRemoveEmoji,
|
||||
handleMessageUpdate,
|
||||
handlePresenceUpdate,
|
||||
handleReady,
|
||||
handleTypingStart,
|
||||
handleUserUpdate,
|
||||
handleVoiceServerUpdate,
|
||||
handleVoiceStateUpdate,
|
||||
handleWebhooksUpdate,
|
||||
};
|
||||
|
||||
export let handlers = {
|
||||
READY: handleReady,
|
||||
// channels
|
||||
CHANNEL_CREATE: handleChannelCreate,
|
||||
CHANNEL_DELETE: handleChannelDelete,
|
||||
CHANNEL_PINS_UPDATE: handleChannelPinsUpdate,
|
||||
CHANNEL_UPDATE: handleChannelUpdate,
|
||||
// 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,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, PresenceUpdatePayload } from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handlePresenceUpdate(data: DiscordPayload) {
|
||||
const payload = data.d as PresenceUpdatePayload;
|
||||
const oldPresence = await cacheHandlers.get("presences", payload.user.id);
|
||||
await cacheHandlers.set("presences", payload.user.id, payload);
|
||||
|
||||
eventHandlers.presenceUpdate?.(payload, oldPresence);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, TypingStartPayload } from "../../types/mod.ts";
|
||||
|
||||
export function handleTypingStart(data: DiscordPayload) {
|
||||
eventHandlers.typingStart?.(data.d as TypingStartPayload);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, UserPayload } from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleUserUpdate(data: DiscordPayload) {
|
||||
const userData = data.d as UserPayload;
|
||||
|
||||
const member = await cacheHandlers.get("members", userData.id);
|
||||
if (!member) return;
|
||||
|
||||
Object.entries(userData).forEach(([key, value]) => {
|
||||
// @ts-ignore index signatures
|
||||
if (member[key] !== value) return member[key] = value;
|
||||
});
|
||||
|
||||
await cacheHandlers.set("members", userData.id, member);
|
||||
|
||||
eventHandlers.botUpdate?.(userData);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import {
|
||||
DiscordPayload,
|
||||
DiscordVoiceServerUpdateEvent,
|
||||
} from "../../types/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleVoiceServerUpdate(data: DiscordPayload) {
|
||||
const payload = data.d as DiscordVoiceServerUpdateEvent;
|
||||
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
eventHandlers.voiceServerUpdate?.(payload.token, guild, payload.endpoint);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, VoiceStateUpdatePayload } from "../../types/mod.ts";
|
||||
import { structures } from "../../structures/mod.ts";
|
||||
import { cacheHandlers } from "../../cache.ts";
|
||||
|
||||
export async function handleVoiceStateUpdate(data: DiscordPayload) {
|
||||
const payload = data.d as VoiceStateUpdatePayload;
|
||||
if (!payload.guild_id) return;
|
||||
|
||||
const guild = await cacheHandlers.get("guilds", payload.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
const member = payload.member
|
||||
? await structures.createMemberStruct(payload.member, guild.id)
|
||||
: await cacheHandlers.get("members", payload.user_id);
|
||||
if (!member) return;
|
||||
|
||||
// No cached state before so lets make one for em
|
||||
const cachedState = guild.voiceStates.get(payload.user_id);
|
||||
|
||||
guild.voiceStates.set(payload.user_id, {
|
||||
...payload,
|
||||
guildID: payload.guild_id,
|
||||
channelID: payload.channel_id || "",
|
||||
userID: payload.user_id,
|
||||
sessionID: payload.session_id,
|
||||
selfDeaf: payload.self_deaf,
|
||||
selfMute: payload.self_mute,
|
||||
selfStream: payload.self_stream || false,
|
||||
});
|
||||
|
||||
await cacheHandlers.set("guilds", payload.guild_id, guild);
|
||||
|
||||
if (cachedState?.channelID !== payload.channel_id) {
|
||||
// Either joined or moved channels
|
||||
if (payload.channel_id) {
|
||||
if (cachedState?.channelID) { // Was in a channel before
|
||||
eventHandlers.voiceChannelSwitch?.(
|
||||
member,
|
||||
payload.channel_id,
|
||||
cachedState.channelID,
|
||||
);
|
||||
} else { // Was not in a channel before so user just joined
|
||||
eventHandlers.voiceChannelJoin?.(member, payload.channel_id);
|
||||
}
|
||||
} // Left the channel
|
||||
else if (cachedState?.channelID) {
|
||||
guild.voiceStates.delete(payload.user_id);
|
||||
eventHandlers.voiceChannelLeave?.(member, cachedState.channelID);
|
||||
}
|
||||
}
|
||||
|
||||
eventHandlers.voiceStateUpdate?.(member, payload);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { eventHandlers } from "../../bot.ts";
|
||||
import { DiscordPayload, WebhookUpdatePayload } from "../../types/mod.ts";
|
||||
|
||||
export function handleWebhooksUpdate(data: DiscordPayload) {
|
||||
const options = data.d as WebhookUpdatePayload;
|
||||
eventHandlers.webhooksUpdate?.(
|
||||
options.channel_id,
|
||||
options.guild_id,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user