Updated to discord.js v13 preview

This commit is contained in:
WatDuhHekBro 2021-05-17 17:12:14 -05:00 committed by Alyxia Sother
parent 8ffbc367b1
commit 36bc488757
No known key found for this signature in database
GPG Key ID: 355968D14144B739
17 changed files with 148 additions and 80 deletions

67
package-lock.json generated
View File

@ -12,7 +12,7 @@
"dependencies": { "dependencies": {
"canvas": "^2.7.0", "canvas": "^2.7.0",
"chalk": "^4.1.0", "chalk": "^4.1.0",
"discord.js": "^12.5.1", "discord.js": "github:discordjs/discord.js",
"discord.js-lavalink-lib": "^0.1.8", "discord.js-lavalink-lib": "^0.1.8",
"figlet": "^1.5.0", "figlet": "^1.5.0",
"glob": "^7.1.6", "glob": "^7.1.6",
@ -20,7 +20,7 @@
"mathjs": "^9.3.0", "mathjs": "^9.3.0",
"moment": "^2.29.1", "moment": "^2.29.1",
"ms": "^2.1.3", "ms": "^2.1.3",
"onion-lasers": "^1.1.2", "onion-lasers": "^1.2.0-unstable.0",
"pet-pet-gif": "^1.0.8", "pet-pet-gif": "^1.0.8",
"relevant-urban": "^2.0.0", "relevant-urban": "^2.0.0",
"translate-google": "^1.4.3", "translate-google": "^1.4.3",
@ -41,7 +41,7 @@
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"ts-jest": "^26.4.4", "ts-jest": "^26.4.4",
"tsc-watch": "^4.2.9", "tsc-watch": "^4.2.9",
"typescript": "^3.9.7" "typescript": "^4.2.4"
}, },
"optionalDependencies": { "optionalDependencies": {
"fsevents": "^2.1.2" "fsevents": "^2.1.2"
@ -2348,21 +2348,20 @@
} }
}, },
"node_modules/discord.js": { "node_modules/discord.js": {
"version": "12.5.3", "version": "12.5.0",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.3.tgz", "resolved": "git+ssh://git@github.com/discordjs/discord.js.git#ab82cafcde0ee259a32ef14303c1b4a64dea8fae",
"integrity": "sha512-D3nkOa/pCkNyn6jLZnAiJApw2N9XrIsXUAdThf01i7yrEuqUmDGc7/CexVWwEcgbQR97XQ+mcnqJpmJ/92B4Aw==", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@discordjs/collection": "^0.1.6", "@discordjs/collection": "^0.1.6",
"@discordjs/form-data": "^3.0.1", "@discordjs/form-data": "^3.0.1",
"abort-controller": "^3.0.0", "abort-controller": "^3.0.0",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"prism-media": "^1.2.9", "prism-media": "^1.2.2",
"setimmediate": "^1.0.5",
"tweetnacl": "^1.0.3", "tweetnacl": "^1.0.3",
"ws": "^7.4.4" "ws": "^7.3.1"
}, },
"engines": { "engines": {
"node": ">=12.0.0" "node": ">=14.0.0"
} }
}, },
"node_modules/discord.js-lavalink-lib": { "node_modules/discord.js-lavalink-lib": {
@ -5406,11 +5405,11 @@
} }
}, },
"node_modules/onion-lasers": { "node_modules/onion-lasers": {
"version": "1.1.2", "version": "1.2.0-unstable.0",
"resolved": "https://registry.npmjs.org/onion-lasers/-/onion-lasers-1.1.2.tgz", "resolved": "https://registry.npmjs.org/onion-lasers/-/onion-lasers-1.2.0-unstable.0.tgz",
"integrity": "sha512-gQHQCdcfDSLeWFFXMTBCy2PZR/n603B+Q2L3vTj+9T1CmJS7OfO7zoFM5QrTkOY4N5hESboOdJ8eRvPXQgdxDg==", "integrity": "sha512-seKXo0CouLNNp2p/M0eORqQ56eJ6MNJe1dSXCI251we8OMJTI5+qRpzB1+OhR2/G4zRkNuWb2aXTUPYNsmVZrA==",
"dependencies": { "dependencies": {
"discord.js": "^12.5.3", "discord.js": "github:discordjs/discord.js",
"glob": "^7.1.6" "glob": "^7.1.6"
} }
}, },
@ -6506,11 +6505,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
},
"node_modules/shebang-command": { "node_modules/shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@ -7466,9 +7460,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "3.9.9", "version": "4.2.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
"integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==", "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==",
"dev": true, "dev": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
@ -9800,18 +9794,16 @@
"dev": true "dev": true
}, },
"discord.js": { "discord.js": {
"version": "12.5.3", "version": "git+ssh://git@github.com/discordjs/discord.js.git#ab82cafcde0ee259a32ef14303c1b4a64dea8fae",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.3.tgz", "from": "discord.js@github:discordjs/discord.js",
"integrity": "sha512-D3nkOa/pCkNyn6jLZnAiJApw2N9XrIsXUAdThf01i7yrEuqUmDGc7/CexVWwEcgbQR97XQ+mcnqJpmJ/92B4Aw==",
"requires": { "requires": {
"@discordjs/collection": "^0.1.6", "@discordjs/collection": "^0.1.6",
"@discordjs/form-data": "^3.0.1", "@discordjs/form-data": "^3.0.1",
"abort-controller": "^3.0.0", "abort-controller": "^3.0.0",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"prism-media": "^1.2.9", "prism-media": "^1.2.2",
"setimmediate": "^1.0.5",
"tweetnacl": "^1.0.3", "tweetnacl": "^1.0.3",
"ws": "^7.4.4" "ws": "^7.3.1"
} }
}, },
"discord.js-lavalink-lib": { "discord.js-lavalink-lib": {
@ -12190,11 +12182,11 @@
} }
}, },
"onion-lasers": { "onion-lasers": {
"version": "1.1.2", "version": "1.2.0-unstable.0",
"resolved": "https://registry.npmjs.org/onion-lasers/-/onion-lasers-1.1.2.tgz", "resolved": "https://registry.npmjs.org/onion-lasers/-/onion-lasers-1.2.0-unstable.0.tgz",
"integrity": "sha512-gQHQCdcfDSLeWFFXMTBCy2PZR/n603B+Q2L3vTj+9T1CmJS7OfO7zoFM5QrTkOY4N5hESboOdJ8eRvPXQgdxDg==", "integrity": "sha512-seKXo0CouLNNp2p/M0eORqQ56eJ6MNJe1dSXCI251we8OMJTI5+qRpzB1+OhR2/G4zRkNuWb2aXTUPYNsmVZrA==",
"requires": { "requires": {
"discord.js": "^12.5.3", "discord.js": "github:discordjs/discord.js",
"glob": "^7.1.6" "glob": "^7.1.6"
} }
}, },
@ -13018,11 +13010,6 @@
} }
} }
}, },
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
},
"shebang-command": { "shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@ -13778,9 +13765,9 @@
} }
}, },
"typescript": { "typescript": {
"version": "3.9.9", "version": "4.2.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
"integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==", "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==",
"dev": true "dev": true
}, },
"underscore": { "underscore": {

View File

@ -12,12 +12,12 @@
"dev-instance": "rimraf dist && tsc && node . dev", "dev-instance": "rimraf dist && tsc && node . dev",
"test": "jest", "test": "jest",
"format": "prettier --write **/*", "format": "prettier --write **/*",
"postinstall": "husky install" "postinstall": "node patch.js && husky install"
}, },
"dependencies": { "dependencies": {
"canvas": "^2.7.0", "canvas": "^2.7.0",
"chalk": "^4.1.0", "chalk": "^4.1.0",
"discord.js": "^12.5.1", "discord.js": "github:discordjs/discord.js",
"discord.js-lavalink-lib": "^0.1.8", "discord.js-lavalink-lib": "^0.1.8",
"figlet": "^1.5.0", "figlet": "^1.5.0",
"glob": "^7.1.6", "glob": "^7.1.6",
@ -25,7 +25,7 @@
"mathjs": "^9.3.0", "mathjs": "^9.3.0",
"moment": "^2.29.1", "moment": "^2.29.1",
"ms": "^2.1.3", "ms": "^2.1.3",
"onion-lasers": "^1.1.2", "onion-lasers": "^1.2.0-unstable.0",
"pet-pet-gif": "^1.0.8", "pet-pet-gif": "^1.0.8",
"relevant-urban": "^2.0.0", "relevant-urban": "^2.0.0",
"translate-google": "^1.4.3", "translate-google": "^1.4.3",
@ -46,7 +46,7 @@
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"ts-jest": "^26.4.4", "ts-jest": "^26.4.4",
"tsc-watch": "^4.2.9", "tsc-watch": "^4.2.9",
"typescript": "^3.9.7" "typescript": "^4.2.4"
}, },
"optionalDependencies": { "optionalDependencies": {
"fsevents": "^2.1.2" "fsevents": "^2.1.2"

23
patch.js Normal file
View File

@ -0,0 +1,23 @@
// This is a nightmarishly bad way to handle module patches... but oh well, it's on the unstable branch for a reason.
const fs = require("fs");
const DECLARATION_FILE = "node_modules/discord.js/typings/index.d.ts";
fs.readFile(DECLARATION_FILE, "utf-8", (err, data) => {
if (err) console.error(err);
else {
const declaration = data.split(/\r?\n/);
// "discord-api-types/v8" is apparently not found so just ignore it to get the typings to work.
for (let i = 0; i < declaration.length; i++) {
const line = declaration[i];
if (line.includes("@ts-ignore")) {
break;
} else if (line.includes("discord-api-types/v8")) {
declaration.splice(i, 0, "// @ts-ignore");
fs.writeFile(DECLARATION_FILE, declaration.join("\n"), () => {});
break;
}
}
}
});

View File

@ -282,7 +282,7 @@ export default new NamedCommand({
const newName = combined; const newName = combined;
if (!voiceChannel) return send("You are not in a voice channel."); if (!voiceChannel) return send("You are not in a voice channel.");
if (!guild!.me?.hasPermission(Permissions.FLAGS.MANAGE_CHANNELS)) if (!guild!.me?.permissions.has(Permissions.FLAGS.MANAGE_CHANNELS))
return send("I can't change channel names without the `Manage Channels` permission."); return send("I can't change channel names without the `Manage Channels` permission.");
guildStorage.channelNames[voiceChannel.id] = newName; guildStorage.channelNames[voiceChannel.id] = newName;
@ -332,6 +332,30 @@ export default new NamedCommand({
} }
}) })
}), }),
purge: new NamedCommand({
description: "Purges the bot's own messages.",
permission: PERMISSIONS.BOT_SUPPORT,
channelType: CHANNEL_TYPE.GUILD,
async run({send, message, channel, guild, client}) {
// It's probably better to go through the bot's own messages instead of calling bulkDelete which requires MANAGE_MESSAGES.
if (guild!.me?.permissions.has(Permissions.FLAGS.MANAGE_MESSAGES)) {
message.delete();
const msgs = await channel.messages.fetch({
limit: 100
});
const travMessages = msgs.filter((m) => m.author.id === client.user?.id);
await send(`Found ${travMessages.size} messages to delete.`).then((m) => {
setTimeout(() => {
m.delete();
}, 5000);
});
await (channel as TextChannel).bulkDelete(travMessages);
} else {
send("This command must be executed in a guild where I have the `MANAGE_MESSAGES` permission.");
}
}
}),
clear: new NamedCommand({ clear: new NamedCommand({
description: "Clears a given amount of messages.", description: "Clears a given amount of messages.",
usage: "<amount>", usage: "<amount>",

View File

@ -9,7 +9,7 @@ export default new NamedCommand({
const voiceChannel = message.member?.voice.channel; const voiceChannel = message.member?.voice.channel;
if (!voiceChannel) return send("You are not in a voice channel."); if (!voiceChannel) return send("You are not in a voice channel.");
if (!voiceChannel.guild.me?.hasPermission("MANAGE_CHANNELS")) if (!voiceChannel.guild.me?.permissions.has("MANAGE_CHANNELS"))
return send("I am lacking the required permissions to perform this action."); return send("I am lacking the required permissions to perform this action.");
const prevName = voiceChannel.name; const prevName = voiceChannel.name;

View File

@ -196,12 +196,13 @@ async function getGuildInfo(guild: Guild, currentGuild: Guild | null) {
const iconURL = guild.iconURL({dynamic: true}); const iconURL = guild.iconURL({dynamic: true});
const embed = new MessageEmbed().setDescription(`**Guild information for __${guild.name}__**`).setColor("BLUE"); const embed = new MessageEmbed().setDescription(`**Guild information for __${guild.name}__**`).setColor("BLUE");
const displayRoles = !!(currentGuild && guild.id === currentGuild.id); const displayRoles = !!(currentGuild && guild.id === currentGuild.id);
const owner = await guild.fetchOwner();
embed embed
.addField("General", [ .addField("General", [
`** Name:** ${guild.name}`, `** Name:** ${guild.name}`,
`** ID:** ${guild.id}`, `** ID:** ${guild.id}`,
`** Owner:** ${guild.owner?.user.tag} (${guild.ownerID})`, `** Owner:** ${owner.user.tag} (${guild.ownerID})`,
`** Region:** ${regions[guild.region]}`, `** Region:** ${regions[guild.region]}`,
`** Boost Tier:** ${guild.premiumTier ? `Tier ${guild.premiumTier}` : "None"}`, `** Boost Tier:** ${guild.premiumTier ? `Tier ${guild.premiumTier}` : "None"}`,
`** Explicit Filter:** ${filterLevels[guild.explicitContentFilter]}`, `** Explicit Filter:** ${filterLevels[guild.explicitContentFilter]}`,

View File

@ -38,7 +38,9 @@ export default new NamedCommand({
let emotes = new Map<string, string>(); let emotes = new Map<string, string>();
for (const emote of emoteCollection) { for (const emote of emoteCollection) {
emotes.set(emote.id, emote.name); if (emote.name) {
emotes.set(emote.id, emote.name);
}
} }
// The result will be sandbox.emotes because it'll be modified in-place. // The result will be sandbox.emotes because it'll be modified in-place.
@ -77,6 +79,7 @@ export default new NamedCommand({
async function displayEmoteList(emotes: GuildEmoji[], send: SendFunction, author: User) { async function displayEmoteList(emotes: GuildEmoji[], send: SendFunction, author: User) {
emotes.sort((a, b) => { emotes.sort((a, b) => {
if (!a.name || !b.name) return 0;
const first = a.name.toLowerCase(); const first = a.name.toLowerCase();
const second = b.name.toLowerCase(); const second = b.name.toLowerCase();

View File

@ -51,9 +51,11 @@ function searchSimilarEmotes(query: string): GuildEmoji[] {
const emoteCandidates: {emote: GuildEmoji; dist: number}[] = []; const emoteCandidates: {emote: GuildEmoji; dist: number}[] = [];
for (const emote of client.emojis.cache.values()) { for (const emote of client.emojis.cache.values()) {
const dist = levenshtein(emote.name, query); if (emote.name) {
if (dist <= maxAcceptedDistance) { const dist = levenshtein(emote.name, query);
emoteCandidates.push({emote, dist}); if (dist <= maxAcceptedDistance) {
emoteCandidates.push({emote, dist});
}
} }
} }

View File

@ -47,7 +47,7 @@ export default new NamedCommand({
else send("Cannot send an empty message."); else send("Cannot send an empty message.");
} }
if (guild!.me?.hasPermission(Permissions.FLAGS.MANAGE_MESSAGES)) message.delete(); if (guild!.me?.permissions.has(Permissions.FLAGS.MANAGE_MESSAGES)) message.delete();
} }
}) })
}); });

View File

@ -24,7 +24,7 @@ export default new NamedCommand({
const stats: { const stats: {
[id: string]: { [id: string]: {
name: string; name: string | null;
formatted: string; formatted: string;
users: number; users: number;
bots: number; bots: number;

View File

@ -1,10 +1,10 @@
import "./modules/globals"; import "./modules/globals";
import {Client, Permissions} from "discord.js"; import {Client, Permissions, Intents} from "discord.js";
import path from "path"; import path from "path";
// This is here in order to make it much less of a headache to access the client from other files. // This is here in order to make it much less of a headache to access the client from other files.
// This of course won't actually do anything until the setup process is complete and it logs in. // This of course won't actually do anything until the setup process is complete and it logs in.
export const client = new Client(); export const client = new Client({intents: Intents.ALL});
import {launch} from "onion-lasers"; import {launch} from "onion-lasers";
import setup from "./modules/setup"; import setup from "./modules/setup";
@ -31,15 +31,15 @@ launch(client, path.join(__dirname, "commands"), {
name: "Moderator", name: "Moderator",
check: (_user, member) => check: (_user, member) =>
!!member && !!member &&
(member.hasPermission(Permissions.FLAGS.MANAGE_ROLES) || (member.permissions.has(Permissions.FLAGS.MANAGE_ROLES) ||
member.hasPermission(Permissions.FLAGS.MANAGE_MESSAGES) || member.permissions.has(Permissions.FLAGS.MANAGE_MESSAGES) ||
member.hasPermission(Permissions.FLAGS.KICK_MEMBERS) || member.permissions.has(Permissions.FLAGS.KICK_MEMBERS) ||
member.hasPermission(Permissions.FLAGS.BAN_MEMBERS)) member.permissions.has(Permissions.FLAGS.BAN_MEMBERS))
}, },
{ {
// ADMIN // // ADMIN //
name: "Administrator", name: "Administrator",
check: (_user, member) => !!member && member.hasPermission(Permissions.FLAGS.ADMINISTRATOR) check: (_user, member) => !!member && member.permissions.has(Permissions.FLAGS.ADMINISTRATOR)
}, },
{ {
// OWNER // // OWNER //

View File

@ -10,7 +10,7 @@ client.on("voiceStateUpdate", async (before, after) => {
channel && channel &&
channel.members.size === 0 && channel.members.size === 0 &&
channel.id in channelNames && channel.id in channelNames &&
before.guild.me?.hasPermission(Permissions.FLAGS.MANAGE_CHANNELS) before.guild.me?.permissions.has(Permissions.FLAGS.MANAGE_CHANNELS)
) { ) {
channel.setName(channelNames[channel.id]); channel.setName(channelNames[channel.id]);
} }

View File

@ -2,17 +2,49 @@
// Like with logging each command invocation, it's not a good idea to pollute the logs with this kind of stuff when it works most of the time. // Like with logging each command invocation, it's not a good idea to pollute the logs with this kind of stuff when it works most of the time.
// However, it's also a pain to debug when no context is provided for an error message. // However, it's also a pain to debug when no context is provided for an error message.
import {client} from ".."; import {client} from "..";
import {setExecuteCommandListener} from "onion-lasers";
import {TextChannel, DMChannel, NewsChannel} from "discord.js";
let lastEvent = "N/A"; let lastEvent = "N/A";
let lastCommandInfo: {
header: string;
args: string[];
channel: TextChannel | DMChannel | NewsChannel | null;
} = {
header: "N/A",
args: [],
channel: null
};
// A generic process handler is set to catch unhandled rejections other than the ones from Lavalink and Discord.
process.on("unhandledRejection", (reason: any) => { process.on("unhandledRejection", (reason: any) => {
const isLavalinkError = reason?.code === "ECONNREFUSED"; const isLavalinkError = reason?.code === "ECONNREFUSED";
const isDiscordError = reason?.name === "DiscordAPIError"; const isDiscordError = reason?.name === "DiscordAPIError";
// If it's a DiscordAPIError on a message event, I'll make the assumption that it comes from the command handler. if (!isLavalinkError) {
if (!isLavalinkError && (!isDiscordError || lastEvent !== "message")) // If it's a DiscordAPIError on a message event, I'll make the assumption that it comes from the command handler.
console.error(`@${lastEvent}\n${reason.stack}`); // That's not always the case though, especially if you add your own message events. Just be wary of that.
if (isDiscordError && lastEvent === "message") {
console.error(
`Command Error: ${lastCommandInfo.header} (${lastCommandInfo.args.join(", ")})\n${reason.stack}`
);
lastCommandInfo.channel?.send(
`There was an error while trying to execute that command!\`\`\`${reason.stack}\`\`\``
);
} else {
console.error(
`@${lastEvent} : /${lastCommandInfo.header} (${lastCommandInfo.args.join(", ")})\n${reason.stack}`
);
}
}
});
// Store info on which command was executed last.
setExecuteCommandListener(({header, args, channel}) => {
lastCommandInfo = {
header,
args,
channel
};
}); });
// This will dynamically attach all known events instead of doing it manually. // This will dynamically attach all known events instead of doing it manually.

View File

@ -1,10 +1,10 @@
import {GuildMember, VoiceChannel, MessageEmbed, TextChannel, Message, Collection} from "discord.js"; import {GuildMember, VoiceChannel, MessageEmbed, TextChannel, Message, Collection, StageChannel} from "discord.js";
import {client} from "../index"; import {client} from "../index";
import {Storage} from "../structures"; import {Storage} from "../structures";
type Stream = { type Stream = {
streamer: GuildMember; streamer: GuildMember;
channel: VoiceChannel; channel: VoiceChannel | StageChannel;
category: string; category: string;
description?: string; description?: string;
thumbnail?: string; thumbnail?: string;
@ -19,7 +19,7 @@ export const streamList = new Collection<string, Stream>();
// Probably find a better, DRY way of doing this. // Probably find a better, DRY way of doing this.
function getStreamEmbed( function getStreamEmbed(
streamer: GuildMember, streamer: GuildMember,
channel: VoiceChannel, channel: VoiceChannel | StageChannel,
streamStart: number, streamStart: number,
category: string, category: string,
description?: string, description?: string,

View File

@ -5,21 +5,17 @@ import {Config} from "../structures";
// Logging which guilds the bot is added to and removed from makes sense. // Logging which guilds the bot is added to and removed from makes sense.
// However, logging the specific channels that are added/removed is a tad bit privacy-invading. // However, logging the specific channels that are added/removed is a tad bit privacy-invading.
client.on("guildCreate", (guild) => { client.on("guildCreate", async (guild) => {
console.log( const owner = await guild.fetchOwner();
`[GUILD JOIN] ${guild.name} (${guild.id}) added the bot. Owner: ${guild.owner!.user.tag} (${
guild.owner!.user.id console.log(`[GUILD JOIN] ${guild.name} (${guild.id}) added the bot. Owner: ${owner.user.tag} (${owner.user.id}).`);
}).`
);
if (Config.systemLogsChannel) { if (Config.systemLogsChannel) {
const channel = client.channels.cache.get(Config.systemLogsChannel); const channel = client.channels.cache.get(Config.systemLogsChannel);
if (channel && channel.type === "text") { if (channel && channel.type === "text") {
(channel as TextChannel).send( (channel as TextChannel).send(
`TravBot joined: \`${guild.name}\`. The owner of this guild is: \`${guild.owner!.user.tag}\` (\`${ `TravBot joined: \`${guild.name}\`. The owner of this guild is: \`${owner.user.tag}\` (\`${owner.user.id}\`)`
guild.owner!.user.id
}\`)`
); );
} else { } else {
console.warn(`${Config.systemLogsChannel} is not a valid text channel for system logs!`); console.warn(`${Config.systemLogsChannel} is not a valid text channel for system logs!`);

View File

@ -8,7 +8,7 @@ const ID_PATTERN = /(\d{17,})/;
// Resolve any available webhooks available for a selected channel. // Resolve any available webhooks available for a selected channel.
export async function resolveWebhook(channel: TextChannel | NewsChannel): Promise<Webhook | null> { export async function resolveWebhook(channel: TextChannel | NewsChannel): Promise<Webhook | null> {
if (channel.guild.me?.hasPermission(Permissions.FLAGS.MANAGE_WEBHOOKS)) { if (channel.guild.me?.permissions.has(Permissions.FLAGS.MANAGE_WEBHOOKS)) {
const webhooksInChannel = await channel.fetchWebhooks(); const webhooksInChannel = await channel.fetchWebhooks();
if (webhooksInChannel.size > 0) return webhooksInChannel.first()!; if (webhooksInChannel.size > 0) return webhooksInChannel.first()!;

View File

@ -243,9 +243,9 @@ export function getPrefix(guild: DiscordGuild | null): string {
} }
export interface EmoteRegistryDumpEntry { export interface EmoteRegistryDumpEntry {
ref: string; ref: string | null;
id: Snowflake; id: Snowflake;
name: string; name: string | null;
requires_colons: boolean; requires_colons: boolean;
animated: boolean; animated: boolean;
url: string; url: string;