All files / src/modules/bot/events Gateway.ts

0% Statements 0/30
0% Branches 0/9
0% Functions 0/10
0% Lines 0/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110                                                                                                                                                                                                                           
import { Config } from "@/modules/shared/config/types";
import { IDatabaseService } from "@/modules/shared/database/interfaces/IDatabaseService";
import { Services } from "@/types/Constants";
import { Inject, Injectable, Logger } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { OnEvent } from "@nestjs/event-emitter";
import { RESTJSONErrorCodes } from "discord-api-types/v10";
import { ActivityType, Client, DiscordAPIError, PresenceData, REST, RateLimitData } from "discord.js";
import { Context, ContextOf, On, Once } from "necord";
 
@Injectable()
export class GatewayEvents {
	public constructor(
		@Inject(Services.Database) private readonly database: IDatabaseService,
		private readonly config: ConfigService<Config>,
	) {}
 
	private readonly logger = new Logger(GatewayEvents.name);
 
	private IGNORED_ERRORS = [
		RESTJSONErrorCodes.UnknownMessage,
		RESTJSONErrorCodes.UnknownChannel,
		RESTJSONErrorCodes.UnknownGuild,
		RESTJSONErrorCodes.UnknownUser,
		RESTJSONErrorCodes.UnknownInteraction,
		// User blocked bot or DM disabled
		RESTJSONErrorCodes.CannotSendMessagesToThisUser,
		// User blocked bot or DM disabled
		RESTJSONErrorCodes.ReactionWasBlocked,
		RESTJSONErrorCodes.MaximumActiveThreads,
	];
 
	@Once("ready")
	public async onReady(@Context() [client]: ContextOf<"ready">) {
		this.logger.log(`Bot logged in as ${client.user.username}`);
		await this._setPresence(client);
		for (const guild of client.guilds.cache.values()) {
			if (!(await this.database.GuildRepo().get(guild.id))) {
				await this.database.GuildRepo().create(guild);
			}
		}
	}
 
	@On("warn")
	public onWarn(@Context() [data]: ContextOf<"warn">) {
		this.logger.warn(data);
	}
 
	@Once("debug")
	public async onDebug(@Context() [data]: ContextOf<"debug">) {
		if (this.config.getOrThrow<Config["Debug"]>("Debug").Client) this.logger.debug(data);
	}
 
	@On("error")
	public async onError(@Context() [error]: ContextOf<"error">) {
		if (
			error instanceof DiscordAPIError &&
			typeof error.code === "number" &&
			this.IGNORED_ERRORS.includes(error.code)
		) {
			return;
		}
		this.logger.verbose(`\nMessage: ${error.message}\nCause: ${error.stack}`);
	}
 
	@OnEvent("rest")
	public async onRest(rest: REST) {
		rest.on("rateLimited", async ({ majorParameter, timeToReset, route, method }: RateLimitData) => {
			this.logger.fatal(`RateLimit on route: ${method} ${route} ${majorParameter}, Time: ${timeToReset}ms`);
		});
	}
 
	private async _setPresence(client: Client) {
		const presences: PresenceData = {
			activities: [
				{
					type: ActivityType.Custom,
					name: "WorkingAt",
					state: `${""}N-D-B | 🎵 Music Player - 🚧 WIP`,
					url: "https://discord.gg/5CHARxbaRk",
				},
				{
					type: ActivityType.Watching,
					name: "Best Bot of Discord",
				},
				{
					type: ActivityType.Streaming,
					name: "Watch my Creator Streams on Twitch!",
					url: "https://Twitch.TV/NedcloarBR",
				},
				{
					type: ActivityType.Custom,
					name: "TotalStatus",
					state: `👤 ${client.users.cache.size} Users - 🏠 ${client.guilds.cache.size} Guilds`,
				},
			],
			status: "dnd",
		};
 
		function setPresence() {
			const activity = presences.activities[Math.floor(Math.random() * presences.activities.length)];
			client.user.setPresence({
				activities: [activity],
			});
		}
		setPresence();
		setInterval(() => setPresence(), 120_000);
	}
}