From 953d7bd3d227e11f6eaf86787bebb0316c12d76e Mon Sep 17 00:00:00 2001 From: notsapinho <52896767+notsapinho@users.noreply.github.com> Date: Thu, 8 Apr 2021 11:40:57 -0300 Subject: [PATCH 1/4] MongooseCache resubscription --- package.json | 2 + src/listener/listener.ts | 332 ++++++++++++++++++++------------------- 2 files changed, 175 insertions(+), 159 deletions(-) diff --git a/package.json b/package.json index 85cf4148..f3fd3362 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "lambert-db": "^1.1.8", "lambert-server": "^1.1.7", "missing-native-js-functions": "^1.2.3", + "mongoose-autopopulate": "^0.12.3", "node-fetch": "^2.6.1", "typescript": "^4.2.3", "uuid": "^8.3.2", @@ -27,6 +28,7 @@ }, "devDependencies": { "@types/jsonwebtoken": "^8.5.0", + "@types/mongoose-autopopulate": "^0.10.1", "@types/uuid": "^8.3.0", "@types/ws": "^7.4.0" } diff --git a/src/listener/listener.ts b/src/listener/listener.ts index 988a791a..85dd33fc 100644 --- a/src/listener/listener.ts +++ b/src/listener/listener.ts @@ -12,174 +12,188 @@ import WebSocket from "../util/WebSocket"; // https://discord.com/developers/docs/topics/gateway#sharding export async function setupListener(this: WebSocket) { - const user = await UserModel.findOne({ id: this.user_id }).lean().exec(); - var guilds = user.guilds; - const shard_count = 10n; - const shard_id = 0n; + const user = await UserModel.findOne({ id: this.user_id }).lean().exec(); + var guilds = user.guilds; + const shard_count = 10n; + const shard_id = 0n; - if (shard_count) { - guilds = user.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); - } + if (shard_count) { + guilds = user.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); + } - const eventStream = new MongooseCache( - db.collection("events"), - [ - { - $match: { - $or: [{ "fullDocument.guild_id": { $in: guilds } }, { "fullDocument.user_id": this.user_id }], - }, - }, - ], - { onlyEvents: true } - ); - await eventStream.init(); - eventStream.on("insert", dispatch.bind(this)); + const eventStream = new MongooseCache( + db.collection("events"), + [ + { + $match: { + $or: [{ "fullDocument.guild_id": { $in: guilds } }, { "fullDocument.user_id": user.id }] + } + } + ], + { + onlyEvents: true + } + ); - this.once("close", () => eventStream.destroy()); + await eventStream.init(); + eventStream.on("insert", async (document) => { + dispatch.call(this, document); + + const newUser = await UserModel.findOne({ id: user.id }).lean().exec(); + var newGuilds = user.guilds; + + if (shard_count) { + newGuilds = user.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); + } + + eventStream.changeStream([{ $match: { $or: [{ "fullDocument.guild_id": { $in: newGuilds } }, { "fullDocument.user_id": newUser.id }] } }]); + }); + + this.once("close", () => eventStream.destroy()); } export async function dispatch(this: WebSocket, document: Event) { - var permission = new Permissions("ADMINISTRATOR"); // default permission for dms - console.log("event", document); + var permission = new Permissions("ADMINISTRATOR"); // default permission for dms + console.log("event", document); - if (document.guild_id) { - if (!this.intents.has("GUILDS")) return; - const channel_id = document.channel_id || document.data?.channel_id; - permission = await getPermission(this.user_id, document.guild_id, channel_id); - } + if (document.guild_id) { + if (!this.intents.has("GUILDS")) return; + const channel_id = document.channel_id || document.data?.channel_id; + permission = await getPermission(this.user_id, document.guild_id, channel_id); + } - // check intents: https://discord.com/developers/docs/topics/gateway#gateway-intents - switch (document.event) { - case "GUILD_CREATE": - case "GUILD_DELETE": - case "GUILD_UPDATE": - case "GUILD_ROLE_CREATE": - case "GUILD_ROLE_UPDATE": - case "GUILD_ROLE_DELETE": - case "CHANNEL_CREATE": - case "CHANNEL_DELETE": - case "CHANNEL_UPDATE": - // gets sent if GUILDS intent is set (already checked in if document.guild_id) - break; - case "GUILD_INTEGRATIONS_UPDATE": - if (!this.intents.has("GUILD_INTEGRATIONS")) return; - break; - case "WEBHOOKS_UPDATE": - if (!this.intents.has("GUILD_WEBHOOKS")) return; - break; - case "GUILD_EMOJI_UPDATE": - if (!this.intents.has("GUILD_EMOJIS")) return; - break; - // only send them, if the user subscribed for this part of the member list, or is a bot - case "GUILD_MEMBER_ADD": - case "GUILD_MEMBER_REMOVE": - case "GUILD_MEMBER_UPDATE": - if (!this.intents.has("GUILD_MEMBERS")) return; - break; - case "VOICE_STATE_UPDATE": - if (!this.intents.has("GUILD_VOICE_STATES")) return; - break; - case "GUILD_BAN_ADD": - case "GUILD_BAN_REMOVE": - if (!this.intents.has("GUILD_BANS")) return; - break; - case "INVITE_CREATE": - case "INVITE_DELETE": - if (!this.intents.has("GUILD_INVITES")) return; - case "PRESENCE_UPDATE": - if (!this.intents.has("GUILD_PRESENCES")) return; - break; - case "MESSAGE_CREATE": - case "MESSAGE_DELETE": - case "MESSAGE_DELETE_BULK": - case "MESSAGE_UPDATE": - case "CHANNEL_PINS_UPDATE": - if (!this.intents.has("GUILD_MESSAGES") && document.guild_id) return; - if (!this.intents.has("DIRECT_MESSAGES") && !document.guild_id) return; - break; - case "MESSAGE_REACTION_ADD": - case "MESSAGE_REACTION_REMOVE": - case "MESSAGE_REACTION_REMOVE_ALL": - case "MESSAGE_REACTION_REMOVE_EMOJI": - if (!this.intents.has("GUILD_MESSAGE_REACTIONS") && document.guild_id) return; - if (!this.intents.has("DIRECT_MESSAGE_REACTIONS") && !document.guild_id) return; - break; + // check intents: https://discord.com/developers/docs/topics/gateway#gateway-intents + switch (document.event) { + case "GUILD_CREATE": + case "GUILD_DELETE": + case "GUILD_UPDATE": + case "GUILD_ROLE_CREATE": + case "GUILD_ROLE_UPDATE": + case "GUILD_ROLE_DELETE": + case "CHANNEL_CREATE": + case "CHANNEL_DELETE": + case "CHANNEL_UPDATE": + // gets sent if GUILDS intent is set (already checked in if document.guild_id) + break; + case "GUILD_INTEGRATIONS_UPDATE": + if (!this.intents.has("GUILD_INTEGRATIONS")) return; + break; + case "WEBHOOKS_UPDATE": + if (!this.intents.has("GUILD_WEBHOOKS")) return; + break; + case "GUILD_EMOJI_UPDATE": + if (!this.intents.has("GUILD_EMOJIS")) return; + break; + // only send them, if the user subscribed for this part of the member list, or is a bot + case "GUILD_MEMBER_ADD": + case "GUILD_MEMBER_REMOVE": + case "GUILD_MEMBER_UPDATE": + if (!this.intents.has("GUILD_MEMBERS")) return; + break; + case "VOICE_STATE_UPDATE": + if (!this.intents.has("GUILD_VOICE_STATES")) return; + break; + case "GUILD_BAN_ADD": + case "GUILD_BAN_REMOVE": + if (!this.intents.has("GUILD_BANS")) return; + break; + case "INVITE_CREATE": + case "INVITE_DELETE": + if (!this.intents.has("GUILD_INVITES")) return; + case "PRESENCE_UPDATE": + if (!this.intents.has("GUILD_PRESENCES")) return; + break; + case "MESSAGE_CREATE": + case "MESSAGE_DELETE": + case "MESSAGE_DELETE_BULK": + case "MESSAGE_UPDATE": + case "CHANNEL_PINS_UPDATE": + if (!this.intents.has("GUILD_MESSAGES") && document.guild_id) return; + if (!this.intents.has("DIRECT_MESSAGES") && !document.guild_id) return; + break; + case "MESSAGE_REACTION_ADD": + case "MESSAGE_REACTION_REMOVE": + case "MESSAGE_REACTION_REMOVE_ALL": + case "MESSAGE_REACTION_REMOVE_EMOJI": + if (!this.intents.has("GUILD_MESSAGE_REACTIONS") && document.guild_id) return; + if (!this.intents.has("DIRECT_MESSAGE_REACTIONS") && !document.guild_id) return; + break; - case "TYPING_START": - if (!this.intents.has("GUILD_MESSAGE_TYPING") && document.guild_id) return; - if (!this.intents.has("DIRECT_MESSAGE_TYPING") && !document.guild_id) return; - break; - case "READY": // will be sent by the gateway - case "USER_UPDATE": - case "APPLICATION_COMMAND_CREATE": - case "APPLICATION_COMMAND_DELETE": - case "APPLICATION_COMMAND_UPDATE": - default: - // Any events not defined in an intent are considered "passthrough" and will always be sent to you. - break; - } + case "TYPING_START": + if (!this.intents.has("GUILD_MESSAGE_TYPING") && document.guild_id) return; + if (!this.intents.has("DIRECT_MESSAGE_TYPING") && !document.guild_id) return; + break; + case "READY": // will be sent by the gateway + case "USER_UPDATE": + case "APPLICATION_COMMAND_CREATE": + case "APPLICATION_COMMAND_DELETE": + case "APPLICATION_COMMAND_UPDATE": + default: + // Any events not defined in an intent are considered "passthrough" and will always be sent to you. + break; + } - // check permissions - switch (document.event) { - case "GUILD_INTEGRATIONS_UPDATE": - if (!permission.has("MANAGE_GUILD")) return; - break; - case "WEBHOOKS_UPDATE": - if (!permission.has("MANAGE_WEBHOOKS")) return; - break; - case "GUILD_MEMBER_ADD": - case "GUILD_MEMBER_REMOVE": - case "GUILD_MEMBER_UPDATE": - // only send them, if the user subscribed for this part of the member list, or is a bot - break; - case "GUILD_BAN_ADD": - case "GUILD_BAN_REMOVE": - if (!permission.has("BAN_MEMBERS")) break; - break; - case "INVITE_CREATE": - case "INVITE_DELETE": - if (!permission.has("MANAGE_GUILD")) break; - case "PRESENCE_UPDATE": - break; - case "VOICE_STATE_UPDATE": - case "MESSAGE_CREATE": - case "MESSAGE_DELETE": - case "MESSAGE_DELETE_BULK": - case "MESSAGE_UPDATE": - case "CHANNEL_PINS_UPDATE": - case "MESSAGE_REACTION_ADD": - case "MESSAGE_REACTION_REMOVE": - case "MESSAGE_REACTION_REMOVE_ALL": - case "MESSAGE_REACTION_REMOVE_EMOJI": - case "TYPING_START": - // only gets send if the user is alowed to view the current channel - if (!permission.has("VIEW_CHANNEL")) return; - break; - case "GUILD_CREATE": - case "GUILD_DELETE": - case "GUILD_UPDATE": - case "GUILD_ROLE_CREATE": - case "GUILD_ROLE_UPDATE": - case "GUILD_ROLE_DELETE": - case "CHANNEL_CREATE": - case "CHANNEL_DELETE": - case "CHANNEL_UPDATE": - case "GUILD_EMOJI_UPDATE": - case "READY": // will be sent by the gateway - case "USER_UPDATE": - case "APPLICATION_COMMAND_CREATE": - case "APPLICATION_COMMAND_DELETE": - case "APPLICATION_COMMAND_UPDATE": - default: - // always gets sent - // Any events not defined in an intent are considered "passthrough" and will always be sent - break; - } + // check permissions + switch (document.event) { + case "GUILD_INTEGRATIONS_UPDATE": + if (!permission.has("MANAGE_GUILD")) return; + break; + case "WEBHOOKS_UPDATE": + if (!permission.has("MANAGE_WEBHOOKS")) return; + break; + case "GUILD_MEMBER_ADD": + case "GUILD_MEMBER_REMOVE": + case "GUILD_MEMBER_UPDATE": + // only send them, if the user subscribed for this part of the member list, or is a bot + break; + case "GUILD_BAN_ADD": + case "GUILD_BAN_REMOVE": + if (!permission.has("BAN_MEMBERS")) break; + break; + case "INVITE_CREATE": + case "INVITE_DELETE": + if (!permission.has("MANAGE_GUILD")) break; + case "PRESENCE_UPDATE": + break; + case "VOICE_STATE_UPDATE": + case "MESSAGE_CREATE": + case "MESSAGE_DELETE": + case "MESSAGE_DELETE_BULK": + case "MESSAGE_UPDATE": + case "CHANNEL_PINS_UPDATE": + case "MESSAGE_REACTION_ADD": + case "MESSAGE_REACTION_REMOVE": + case "MESSAGE_REACTION_REMOVE_ALL": + case "MESSAGE_REACTION_REMOVE_EMOJI": + case "TYPING_START": + // only gets send if the user is alowed to view the current channel + if (!permission.has("VIEW_CHANNEL")) return; + break; + case "GUILD_CREATE": + case "GUILD_DELETE": + case "GUILD_UPDATE": + case "GUILD_ROLE_CREATE": + case "GUILD_ROLE_UPDATE": + case "GUILD_ROLE_DELETE": + case "CHANNEL_CREATE": + case "CHANNEL_DELETE": + case "CHANNEL_UPDATE": + case "GUILD_EMOJI_UPDATE": + case "READY": // will be sent by the gateway + case "USER_UPDATE": + case "APPLICATION_COMMAND_CREATE": + case "APPLICATION_COMMAND_DELETE": + case "APPLICATION_COMMAND_UPDATE": + default: + // always gets sent + // Any events not defined in an intent are considered "passthrough" and will always be sent + break; + } - return Send(this, { - op: OPCODES.Dispatch, - t: document.event, - d: document.data, - s: this.sequence++, - }); + return Send(this, { + op: OPCODES.Dispatch, + t: document.event, + d: document.data, + s: this.sequence++ + }); } From 774fcc9373e4dd76e47d9361ae5371978658dbd5 Mon Sep 17 00:00:00 2001 From: notsapinho <52896767+notsapinho@users.noreply.github.com> Date: Thu, 8 Apr 2021 11:59:00 -0300 Subject: [PATCH 2/4] Update listener.ts --- src/listener/listener.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/listener/listener.ts b/src/listener/listener.ts index 85dd33fc..50ca8e65 100644 --- a/src/listener/listener.ts +++ b/src/listener/listener.ts @@ -36,18 +36,7 @@ export async function setupListener(this: WebSocket) { ); await eventStream.init(); - eventStream.on("insert", async (document) => { - dispatch.call(this, document); - - const newUser = await UserModel.findOne({ id: user.id }).lean().exec(); - var newGuilds = user.guilds; - - if (shard_count) { - newGuilds = user.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); - } - - eventStream.changeStream([{ $match: { $or: [{ "fullDocument.guild_id": { $in: newGuilds } }, { "fullDocument.user_id": newUser.id }] } }]); - }); + eventStream.on("insert", dispatch.bind(this)); this.once("close", () => eventStream.destroy()); } @@ -62,6 +51,17 @@ export async function dispatch(this: WebSocket, document: Event) { permission = await getPermission(this.user_id, document.guild_id, channel_id); } + if(document.event === "GUILD_CREATE") { + const newUser = await UserModel.findOne({ id: this.user_id }).lean().exec(); + var newGuilds = newUser.guilds; + + if (shard_count) { + newGuilds = newUser.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); + } + + eventStream.changeStream([{ $match: { $or: [{ "fullDocument.guild_id": { $in: newGuilds } }, { "fullDocument.user_id": newUser.id }] } }]); + } + // check intents: https://discord.com/developers/docs/topics/gateway#gateway-intents switch (document.event) { case "GUILD_CREATE": From 9d9a4c7e72244b50cf26f3e649aaf026181a3416 Mon Sep 17 00:00:00 2001 From: notsapinho <52896767+notsapinho@users.noreply.github.com> Date: Thu, 8 Apr 2021 12:25:29 -0300 Subject: [PATCH 3/4] fix little errors and new method to get new guilds --- src/listener/listener.ts | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/listener/listener.ts b/src/listener/listener.ts index 50ca8e65..9af8f298 100644 --- a/src/listener/listener.ts +++ b/src/listener/listener.ts @@ -11,14 +11,21 @@ import WebSocket from "../util/WebSocket"; // Sharding: calculate if the current shard id matches the formula: shard_id = (guild_id >> 22) % num_shards // https://discord.com/developers/docs/topics/gateway#sharding +export interface DispatchOpts { + eventStream: any; + user_guilds: Array; + shard_count?: bigint; + shard_id?: bigint; +} + export async function setupListener(this: WebSocket) { const user = await UserModel.findOne({ id: this.user_id }).lean().exec(); - var guilds = user.guilds; + var user_guilds = user.guilds; const shard_count = 10n; const shard_id = 0n; if (shard_count) { - guilds = user.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); + user_guilds = user.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); } const eventStream = new MongooseCache( @@ -26,7 +33,7 @@ export async function setupListener(this: WebSocket) { [ { $match: { - $or: [{ "fullDocument.guild_id": { $in: guilds } }, { "fullDocument.user_id": user.id }] + $or: [{ "fullDocument.guild_id": { $in: user_guilds } }, { "fullDocument.user_id": user.id }] } } ], @@ -36,12 +43,12 @@ export async function setupListener(this: WebSocket) { ); await eventStream.init(); - eventStream.on("insert", dispatch.bind(this)); + eventStream.on("insert", (document) => dispatch.call(this, { eventStream, user_guilds, shard_count, shard_id }, document)); this.once("close", () => eventStream.destroy()); } -export async function dispatch(this: WebSocket, document: Event) { +export async function dispatch(this: WebSocket, { eventStream, user_guilds, shard_count, shard_id }: DispatchOpts, document: Event) { var permission = new Permissions("ADMINISTRATOR"); // default permission for dms console.log("event", document); @@ -51,15 +58,14 @@ export async function dispatch(this: WebSocket, document: Event) { permission = await getPermission(this.user_id, document.guild_id, channel_id); } - if(document.event === "GUILD_CREATE") { - const newUser = await UserModel.findOne({ id: this.user_id }).lean().exec(); - var newGuilds = newUser.guilds; + if (document.event === "GUILD_CREATE") { + user_guilds.push(document.guild_id); if (shard_count) { - newGuilds = newUser.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); + user_guilds = user_guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); } - eventStream.changeStream([{ $match: { $or: [{ "fullDocument.guild_id": { $in: newGuilds } }, { "fullDocument.user_id": newUser.id }] } }]); + eventStream.changeStream([{ $match: { $or: [{ "fullDocument.guild_id": { $in: user_guilds } }, { "fullDocument.user_id": document.user_id }] } }]); } // check intents: https://discord.com/developers/docs/topics/gateway#gateway-intents From f268e9c42f9e2911a57a14d239b868ff598ef80a Mon Sep 17 00:00:00 2001 From: Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> Date: Thu, 8 Apr 2021 18:52:57 +0200 Subject: [PATCH 4/4] create getPipeline function + clean up --- src/listener/listener.ts | 347 +++++++++++++++++++-------------------- 1 file changed, 171 insertions(+), 176 deletions(-) diff --git a/src/listener/listener.ts b/src/listener/listener.ts index 9af8f298..f0f9d3e3 100644 --- a/src/listener/listener.ts +++ b/src/listener/listener.ts @@ -2,6 +2,7 @@ import { db, Event, MongooseCache, UserModel, getPermission, Permissions } from import { OPCODES } from "../util/Constants"; import { Send } from "../util/Send"; import WebSocket from "../util/WebSocket"; +import "missing-native-js-functions"; // TODO: close connection on Invalidated Token // TODO: check intent @@ -12,194 +13,188 @@ import WebSocket from "../util/WebSocket"; // https://discord.com/developers/docs/topics/gateway#sharding export interface DispatchOpts { - eventStream: any; - user_guilds: Array; - shard_count?: bigint; - shard_id?: bigint; + eventStream: MongooseCache; + guilds: Array; +} + +function getPipeline(this: WebSocket, guilds: string[]) { + if (this.shard_count) { + guilds = guilds.filter((x) => (BigInt(x) >> 22n) % this.shard_count === this.shard_id); + } + + return [ + { + $match: { + $or: [{ "fullDocument.guild_id": { $in: guilds } }, { "fullDocument.user_id": this.user_id }], + }, + }, + ]; } export async function setupListener(this: WebSocket) { - const user = await UserModel.findOne({ id: this.user_id }).lean().exec(); - var user_guilds = user.guilds; - const shard_count = 10n; - const shard_id = 0n; + const user = await UserModel.findOne({ id: this.user_id }).lean().exec(); + var guilds = user.guilds; - if (shard_count) { - user_guilds = user.guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); - } + const eventStream = new MongooseCache(db.collection("events"), getPipeline.call(this, guilds), { + onlyEvents: true, + }); - const eventStream = new MongooseCache( - db.collection("events"), - [ - { - $match: { - $or: [{ "fullDocument.guild_id": { $in: user_guilds } }, { "fullDocument.user_id": user.id }] - } - } - ], - { - onlyEvents: true - } - ); + await eventStream.init(); + eventStream.on("insert", (document: Event) => dispatch.call(this, document, { eventStream, guilds })); - await eventStream.init(); - eventStream.on("insert", (document) => dispatch.call(this, { eventStream, user_guilds, shard_count, shard_id }, document)); - - this.once("close", () => eventStream.destroy()); + this.once("close", () => eventStream.destroy()); } -export async function dispatch(this: WebSocket, { eventStream, user_guilds, shard_count, shard_id }: DispatchOpts, document: Event) { - var permission = new Permissions("ADMINISTRATOR"); // default permission for dms - console.log("event", document); +export async function dispatch(this: WebSocket, document: Event, { eventStream, guilds }: DispatchOpts) { + var permission = new Permissions("ADMINISTRATOR"); // default permission for dms + console.log("event", document); - if (document.guild_id) { - if (!this.intents.has("GUILDS")) return; - const channel_id = document.channel_id || document.data?.channel_id; - permission = await getPermission(this.user_id, document.guild_id, channel_id); - } + if (document.guild_id) { + if (!this.intents.has("GUILDS")) return; + const channel_id = document.channel_id || document.data?.channel_id; + permission = await getPermission(this.user_id, document.guild_id, channel_id); + } - if (document.event === "GUILD_CREATE") { - user_guilds.push(document.guild_id); + if (document.event === "GUILD_CREATE") { + guilds.push(document.guild_id); + eventStream.changeStream(getPipeline.call(this, guilds)); + } else if (document.event === "GUILD_DELETE") { + guilds.remove(document.guild); + eventStream.changeStream(getPipeline.call(this, guilds)); + } - if (shard_count) { - user_guilds = user_guilds.filter((x) => (BigInt(x) >> 22n) % shard_count === shard_id); - } + // check intents: https://discord.com/developers/docs/topics/gateway#gateway-intents + switch (document.event) { + case "GUILD_CREATE": + case "GUILD_DELETE": + case "GUILD_UPDATE": + case "GUILD_ROLE_CREATE": + case "GUILD_ROLE_UPDATE": + case "GUILD_ROLE_DELETE": + case "CHANNEL_CREATE": + case "CHANNEL_DELETE": + case "CHANNEL_UPDATE": + // gets sent if GUILDS intent is set (already checked in if document.guild_id) + break; + case "GUILD_INTEGRATIONS_UPDATE": + if (!this.intents.has("GUILD_INTEGRATIONS")) return; + break; + case "WEBHOOKS_UPDATE": + if (!this.intents.has("GUILD_WEBHOOKS")) return; + break; + case "GUILD_EMOJI_UPDATE": + if (!this.intents.has("GUILD_EMOJIS")) return; + break; + // only send them, if the user subscribed for this part of the member list, or is a bot + case "GUILD_MEMBER_ADD": + case "GUILD_MEMBER_REMOVE": + case "GUILD_MEMBER_UPDATE": + if (!this.intents.has("GUILD_MEMBERS")) return; + break; + case "VOICE_STATE_UPDATE": + if (!this.intents.has("GUILD_VOICE_STATES")) return; + break; + case "GUILD_BAN_ADD": + case "GUILD_BAN_REMOVE": + if (!this.intents.has("GUILD_BANS")) return; + break; + case "INVITE_CREATE": + case "INVITE_DELETE": + if (!this.intents.has("GUILD_INVITES")) return; + case "PRESENCE_UPDATE": + if (!this.intents.has("GUILD_PRESENCES")) return; + break; + case "MESSAGE_CREATE": + case "MESSAGE_DELETE": + case "MESSAGE_DELETE_BULK": + case "MESSAGE_UPDATE": + case "CHANNEL_PINS_UPDATE": + if (!this.intents.has("GUILD_MESSAGES") && document.guild_id) return; + if (!this.intents.has("DIRECT_MESSAGES") && !document.guild_id) return; + break; + case "MESSAGE_REACTION_ADD": + case "MESSAGE_REACTION_REMOVE": + case "MESSAGE_REACTION_REMOVE_ALL": + case "MESSAGE_REACTION_REMOVE_EMOJI": + if (!this.intents.has("GUILD_MESSAGE_REACTIONS") && document.guild_id) return; + if (!this.intents.has("DIRECT_MESSAGE_REACTIONS") && !document.guild_id) return; + break; - eventStream.changeStream([{ $match: { $or: [{ "fullDocument.guild_id": { $in: user_guilds } }, { "fullDocument.user_id": document.user_id }] } }]); - } + case "TYPING_START": + if (!this.intents.has("GUILD_MESSAGE_TYPING") && document.guild_id) return; + if (!this.intents.has("DIRECT_MESSAGE_TYPING") && !document.guild_id) return; + break; + case "READY": // will be sent by the gateway + case "USER_UPDATE": + case "APPLICATION_COMMAND_CREATE": + case "APPLICATION_COMMAND_DELETE": + case "APPLICATION_COMMAND_UPDATE": + default: + // Any events not defined in an intent are considered "passthrough" and will always be sent to you. + break; + } - // check intents: https://discord.com/developers/docs/topics/gateway#gateway-intents - switch (document.event) { - case "GUILD_CREATE": - case "GUILD_DELETE": - case "GUILD_UPDATE": - case "GUILD_ROLE_CREATE": - case "GUILD_ROLE_UPDATE": - case "GUILD_ROLE_DELETE": - case "CHANNEL_CREATE": - case "CHANNEL_DELETE": - case "CHANNEL_UPDATE": - // gets sent if GUILDS intent is set (already checked in if document.guild_id) - break; - case "GUILD_INTEGRATIONS_UPDATE": - if (!this.intents.has("GUILD_INTEGRATIONS")) return; - break; - case "WEBHOOKS_UPDATE": - if (!this.intents.has("GUILD_WEBHOOKS")) return; - break; - case "GUILD_EMOJI_UPDATE": - if (!this.intents.has("GUILD_EMOJIS")) return; - break; - // only send them, if the user subscribed for this part of the member list, or is a bot - case "GUILD_MEMBER_ADD": - case "GUILD_MEMBER_REMOVE": - case "GUILD_MEMBER_UPDATE": - if (!this.intents.has("GUILD_MEMBERS")) return; - break; - case "VOICE_STATE_UPDATE": - if (!this.intents.has("GUILD_VOICE_STATES")) return; - break; - case "GUILD_BAN_ADD": - case "GUILD_BAN_REMOVE": - if (!this.intents.has("GUILD_BANS")) return; - break; - case "INVITE_CREATE": - case "INVITE_DELETE": - if (!this.intents.has("GUILD_INVITES")) return; - case "PRESENCE_UPDATE": - if (!this.intents.has("GUILD_PRESENCES")) return; - break; - case "MESSAGE_CREATE": - case "MESSAGE_DELETE": - case "MESSAGE_DELETE_BULK": - case "MESSAGE_UPDATE": - case "CHANNEL_PINS_UPDATE": - if (!this.intents.has("GUILD_MESSAGES") && document.guild_id) return; - if (!this.intents.has("DIRECT_MESSAGES") && !document.guild_id) return; - break; - case "MESSAGE_REACTION_ADD": - case "MESSAGE_REACTION_REMOVE": - case "MESSAGE_REACTION_REMOVE_ALL": - case "MESSAGE_REACTION_REMOVE_EMOJI": - if (!this.intents.has("GUILD_MESSAGE_REACTIONS") && document.guild_id) return; - if (!this.intents.has("DIRECT_MESSAGE_REACTIONS") && !document.guild_id) return; - break; + // check permissions + switch (document.event) { + case "GUILD_INTEGRATIONS_UPDATE": + if (!permission.has("MANAGE_GUILD")) return; + break; + case "WEBHOOKS_UPDATE": + if (!permission.has("MANAGE_WEBHOOKS")) return; + break; + case "GUILD_MEMBER_ADD": + case "GUILD_MEMBER_REMOVE": + case "GUILD_MEMBER_UPDATE": + // only send them, if the user subscribed for this part of the member list, or is a bot + break; + case "GUILD_BAN_ADD": + case "GUILD_BAN_REMOVE": + if (!permission.has("BAN_MEMBERS")) break; + break; + case "INVITE_CREATE": + case "INVITE_DELETE": + if (!permission.has("MANAGE_GUILD")) break; + case "PRESENCE_UPDATE": + break; + case "VOICE_STATE_UPDATE": + case "MESSAGE_CREATE": + case "MESSAGE_DELETE": + case "MESSAGE_DELETE_BULK": + case "MESSAGE_UPDATE": + case "CHANNEL_PINS_UPDATE": + case "MESSAGE_REACTION_ADD": + case "MESSAGE_REACTION_REMOVE": + case "MESSAGE_REACTION_REMOVE_ALL": + case "MESSAGE_REACTION_REMOVE_EMOJI": + case "TYPING_START": + // only gets send if the user is alowed to view the current channel + if (!permission.has("VIEW_CHANNEL")) return; + break; + case "GUILD_CREATE": + case "GUILD_DELETE": + case "GUILD_UPDATE": + case "GUILD_ROLE_CREATE": + case "GUILD_ROLE_UPDATE": + case "GUILD_ROLE_DELETE": + case "CHANNEL_CREATE": + case "CHANNEL_DELETE": + case "CHANNEL_UPDATE": + case "GUILD_EMOJI_UPDATE": + case "READY": // will be sent by the gateway + case "USER_UPDATE": + case "APPLICATION_COMMAND_CREATE": + case "APPLICATION_COMMAND_DELETE": + case "APPLICATION_COMMAND_UPDATE": + default: + // always gets sent + // Any events not defined in an intent are considered "passthrough" and will always be sent + break; + } - case "TYPING_START": - if (!this.intents.has("GUILD_MESSAGE_TYPING") && document.guild_id) return; - if (!this.intents.has("DIRECT_MESSAGE_TYPING") && !document.guild_id) return; - break; - case "READY": // will be sent by the gateway - case "USER_UPDATE": - case "APPLICATION_COMMAND_CREATE": - case "APPLICATION_COMMAND_DELETE": - case "APPLICATION_COMMAND_UPDATE": - default: - // Any events not defined in an intent are considered "passthrough" and will always be sent to you. - break; - } - - // check permissions - switch (document.event) { - case "GUILD_INTEGRATIONS_UPDATE": - if (!permission.has("MANAGE_GUILD")) return; - break; - case "WEBHOOKS_UPDATE": - if (!permission.has("MANAGE_WEBHOOKS")) return; - break; - case "GUILD_MEMBER_ADD": - case "GUILD_MEMBER_REMOVE": - case "GUILD_MEMBER_UPDATE": - // only send them, if the user subscribed for this part of the member list, or is a bot - break; - case "GUILD_BAN_ADD": - case "GUILD_BAN_REMOVE": - if (!permission.has("BAN_MEMBERS")) break; - break; - case "INVITE_CREATE": - case "INVITE_DELETE": - if (!permission.has("MANAGE_GUILD")) break; - case "PRESENCE_UPDATE": - break; - case "VOICE_STATE_UPDATE": - case "MESSAGE_CREATE": - case "MESSAGE_DELETE": - case "MESSAGE_DELETE_BULK": - case "MESSAGE_UPDATE": - case "CHANNEL_PINS_UPDATE": - case "MESSAGE_REACTION_ADD": - case "MESSAGE_REACTION_REMOVE": - case "MESSAGE_REACTION_REMOVE_ALL": - case "MESSAGE_REACTION_REMOVE_EMOJI": - case "TYPING_START": - // only gets send if the user is alowed to view the current channel - if (!permission.has("VIEW_CHANNEL")) return; - break; - case "GUILD_CREATE": - case "GUILD_DELETE": - case "GUILD_UPDATE": - case "GUILD_ROLE_CREATE": - case "GUILD_ROLE_UPDATE": - case "GUILD_ROLE_DELETE": - case "CHANNEL_CREATE": - case "CHANNEL_DELETE": - case "CHANNEL_UPDATE": - case "GUILD_EMOJI_UPDATE": - case "READY": // will be sent by the gateway - case "USER_UPDATE": - case "APPLICATION_COMMAND_CREATE": - case "APPLICATION_COMMAND_DELETE": - case "APPLICATION_COMMAND_UPDATE": - default: - // always gets sent - // Any events not defined in an intent are considered "passthrough" and will always be sent - break; - } - - return Send(this, { - op: OPCODES.Dispatch, - t: document.event, - d: document.data, - s: this.sequence++ - }); + return Send(this, { + op: OPCODES.Dispatch, + t: document.event, + d: document.data, + s: this.sequence++, + }); }