f
This commit is contained in:
1 parent
9f9c852a36
commit
09ddaba972
18 files changed
+1205
-64
No files matched your search
@@ -0,0 +1,84 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { time } = require("discord.js");
|
||||
|
||||
module.exports = {
|
||||
name: 'autorole',
|
||||
description: `assign a role to new members when they join the server`,
|
||||
aliases: ['ar'],
|
||||
usage: 'autorole <role>',
|
||||
|
||||
async execute(client, message, args) {
|
||||
if (!message.member.permissions.has('Administrator')) {
|
||||
return message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: '<:no:1481811955592466492> you do not have permission to use this command!',
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
const role = message.mentions.roles.first() || message.guild.roles.cache.get(args[0]);
|
||||
|
||||
if (!role) {
|
||||
return message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: '<:no:1481811955592466492> please provide a valid role!',
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
// add the role to a json file for the guild and save it to be used when new members join (if the role is already in the database, update it to the new role)
|
||||
const dbPath = path.join(__dirname, '..', '..', 'db.json');
|
||||
|
||||
let db = {};
|
||||
if (fs.existsSync(dbPath)) {
|
||||
db = JSON.parse(fs.readFileSync(dbPath, 'utf8'));
|
||||
}
|
||||
|
||||
if (!db.autoroles) {
|
||||
db.autoroles = {};
|
||||
}
|
||||
|
||||
db.autoroles[message.guild.id] = role.id;
|
||||
|
||||
fs.writeFileSync(dbPath, JSON.stringify(db, null, 2));
|
||||
|
||||
message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: `<:check:1481811973447356496> "${role.name}" has been set as the autorole!`,
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}]
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,88 @@
|
||||
'use strict';
|
||||
|
||||
const { time } = require("discord.js");
|
||||
|
||||
module.exports = {
|
||||
name: 'ban',
|
||||
description: `ban a user from the current server`,
|
||||
aliases: ['banish'],
|
||||
usage: 'ban <user> [reason] [duration]',
|
||||
|
||||
async execute(client, message, args) {
|
||||
if (!message.member.permissions.has('BanMembers')) {
|
||||
return message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: '<:no:1481811955592466492> you do not have permission to use this command!',
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
const user = message.mentions.users.first() || client.users.cache.get(args[0]);
|
||||
if (!user) {
|
||||
return message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: '<:no:1481811955592466492> please specify a user to ban!',
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
const reason = args.slice(1).join(' ') || 'no reason provided (twitter)';
|
||||
const duration = args[2] ? parseInt(args[2]) : null;
|
||||
|
||||
try {
|
||||
await message.guild.members.ban(user, { reason });
|
||||
message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: `<:check:1481811973447356496> ${user.username} has been banned!`,
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}]
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: '<:no:1481811955592466492> an error occurred while trying to ban the user!',
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}]
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
+43
-13
@@ -1,8 +1,10 @@
|
||||
const { EmbedBuilder } = require('discord.js');
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
name: 'help',
|
||||
description: 'Lists all available commands or shows info about a specific one.',
|
||||
description: 'lists all available commands or shows info about a specific one',
|
||||
aliases: ['h', 'commands'],
|
||||
usage: 'help [command]',
|
||||
|
||||
@@ -15,17 +17,29 @@ module.exports = {
|
||||
const command = client.commands.get(name);
|
||||
|
||||
if (!command) {
|
||||
return message.reply(`No command found for \`${name}\`.`);
|
||||
return message.reply(`no command found for \`${name}\`.`);
|
||||
}
|
||||
|
||||
const lines = [`**${prefix}${command.name}**`];
|
||||
if (command.description) lines.push(`> ${command.description}`);
|
||||
if (command.aliases?.length)
|
||||
lines.push(`> **Aliases:** ${command.aliases.map((a) => `\`${prefix}${a}\``).join(', ')}`);
|
||||
if (command.usage)
|
||||
lines.push(`> **Usage:** \`${prefix}${command.usage}\``);
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor(0x1da1f2)
|
||||
.setTitle(`${prefix}${command.name}`)
|
||||
.setDescription(command.description || 'no description');
|
||||
|
||||
return message.reply(lines.join('\n'));
|
||||
if (command.aliases?.length) {
|
||||
embed.addFields({
|
||||
name: 'aliases',
|
||||
value: command.aliases.map((a) => `\`${prefix}${a}\``).join(', '),
|
||||
});
|
||||
}
|
||||
|
||||
if (command.usage) {
|
||||
embed.addFields({
|
||||
name: 'usage',
|
||||
value: `\`${prefix}${command.usage}\``,
|
||||
});
|
||||
}
|
||||
|
||||
return message.reply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// Build a deduplicated command list (ignore aliases pointing to the same command)
|
||||
@@ -35,11 +49,27 @@ module.exports = {
|
||||
for (const command of client.commands.values()) {
|
||||
if (seen.has(command.name)) continue;
|
||||
seen.add(command.name);
|
||||
commandList.push(`\`${prefix}${command.name}\` — ${command.description || 'No description.'}`);
|
||||
commandList.push(`\`${prefix}${command.name}\` — ${command.description || 'no description'}`);
|
||||
}
|
||||
|
||||
return message.reply(
|
||||
`**Available commands:**\n${commandList.join('\n')}\n\nUse \`${prefix}help <command>\` for more details.`,
|
||||
);
|
||||
const embed = {
|
||||
color: 0x8aa2b3,
|
||||
title: '',
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: `-# use ${prefix}help <command> for more details`,
|
||||
fields: [
|
||||
{ name: 'commands', value: commandList.join('\n') },
|
||||
],
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
};
|
||||
|
||||
return message.reply({ embeds: [embed] });
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,88 @@
|
||||
'use strict';
|
||||
|
||||
const { time } = require("discord.js");
|
||||
|
||||
module.exports = {
|
||||
name: 'kick',
|
||||
description: `kick a user from the current server`,
|
||||
aliases: ['kick'],
|
||||
usage: 'kick <user> [reason]',
|
||||
|
||||
async execute(client, message, args) {
|
||||
if (!message.member.permissions.has('KickMembers')) {
|
||||
return message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: '<:no:1481811955592466492> you do not have permission to use this command!',
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
const user = message.mentions.users.first() || client.users.cache.get(args[0]);
|
||||
if (!user) {
|
||||
return message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: '<:no:1481811955592466492> please specify a user to ban!',
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
const reason = args.slice(1).join(' ') || 'no reason provided (twitter)';
|
||||
const duration = args[2] ? parseInt(args[2]) : null;
|
||||
|
||||
try {
|
||||
await message.guild.members.kick(user, { reason });
|
||||
message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: `<:check:1481811973447356496> ${user.username} has been kicked!`,
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}]
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: '<:no:1481811955592466492> an error occurred while trying to ban the user!',
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}]
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
+30
-5
@@ -1,18 +1,43 @@
|
||||
'use strict';
|
||||
|
||||
const { time } = require("discord.js");
|
||||
|
||||
module.exports = {
|
||||
name: 'ping',
|
||||
description: 'Replies with Pong! and shows the bot latency.',
|
||||
description: `test the bot's latency to discord's servers and api`,
|
||||
aliases: ['pong'],
|
||||
usage: 'ping',
|
||||
|
||||
async execute(client, message) {
|
||||
const sent = await message.reply('Pinging…');
|
||||
const sent = await message.reply('pinging');
|
||||
const latency = sent.createdTimestamp - message.createdTimestamp;
|
||||
const apiLatency = Math.round(client.ws.ping);
|
||||
|
||||
await sent.edit(
|
||||
`🏓 Pong!\n> Bot latency: **${latency}ms** | API latency: **${apiLatency}ms**`,
|
||||
);
|
||||
const embed = {
|
||||
color: 0x8aa2b3,
|
||||
title: '',
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: 'fuck you!!!! 🖕',
|
||||
fields: [
|
||||
{ name: '# of cmds loaded', value: `**${client.commands.size}**`, inline: true },
|
||||
{ name: 'bot latency', value: `**${latency}ms**`, inline: true },
|
||||
{ name: 'api latency', value: `**${apiLatency}ms**`, inline: true },
|
||||
],
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
thumbnail: {
|
||||
url: client.user.displayAvatarURL(),
|
||||
height: 1024,
|
||||
width: 1024,
|
||||
},
|
||||
};
|
||||
|
||||
await sent.edit({ content: null, embeds: [embed] });
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
'use strict';
|
||||
|
||||
const { time } = require("discord.js");
|
||||
|
||||
module.exports = {
|
||||
name: 'purge',
|
||||
description: `delete a specified number of messages from the current channel`,
|
||||
aliases: ['clear', 'p'],
|
||||
usage: 'purge <number>',
|
||||
|
||||
async execute(client, message) {
|
||||
if (!message.member.permissions.has('ManageMessages')) {
|
||||
return message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
description: '<:no:1481811955592466492> you do not have permission to use this command!',
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
const args = message.content.split(' ').slice(1);
|
||||
const amount = parseInt(args[0]) + 1;
|
||||
|
||||
if (isNaN(amount) || amount < 1 || amount > 100) {
|
||||
return message.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
description: '<:no:1481811955592466492> please provide a number between 1 and 100!',
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
const deletedMessages = await message.channel.bulkDelete(amount, true);
|
||||
const reply = await message.channel.send({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: `<:no:1481811955592466492> successfully deleted ${deletedMessages.size - 1} messages!`,
|
||||
footer: {
|
||||
text: `twitter @ ${message.guild.name}`,
|
||||
icon_url: client.user.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}],
|
||||
});
|
||||
setTimeout(() => reply.delete().catch(() => { }), 5000);
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { Events } = require('discord.js');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
module.exports = (client, member) => {
|
||||
const dbPath = path.join(__dirname, '..', '..', 'db.json');
|
||||
const db = JSON.parse(fs.readFileSync(dbPath, 'utf8'));
|
||||
const roleId = db.autoroles ? db.autoroles[member.guild.id] : null;
|
||||
|
||||
if (!roleId) {
|
||||
logger.info(`member "${member.user.tag}" joined guild "${member.guild.name}", but no autorole is set up.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const role = member.guild.roles.cache.get(roleId);
|
||||
|
||||
if (!role) {
|
||||
logger.error(`role with id "${roleId}" not found in guild "${member.guild.name}".`);
|
||||
return;
|
||||
}
|
||||
logger.info("member has joined the server! assigning member role...");
|
||||
|
||||
member.roles.add(role)
|
||||
.then(() => logger.info(`assigned role "${role.name}" to user "${member.user.tag}"!`))
|
||||
.catch(error => logger.error(`failed to assign role "${role.name}" to user "${member.user.tag}": ${error}`));
|
||||
};
|
||||
@@ -21,16 +21,31 @@ module.exports = {
|
||||
if (!command) return;
|
||||
|
||||
logger.info(
|
||||
`[Command] "${commandName}" used by ${message.author.tag} (${message.author.id})` +
|
||||
` in ${message.guild ? `#${message.channel.name} (${message.guild.name})` : 'DMs'}`,
|
||||
`[command] "${commandName}" used by ${message.author.tag} (${message.author.id})` +
|
||||
` in ${message.guild ? `#${message.channel.name} (${message.guild.name})` : 'dms'}`,
|
||||
);
|
||||
|
||||
try {
|
||||
await command.execute(client, message, args);
|
||||
} catch (err) {
|
||||
logger.error(`[Command] Error executing "${commandName}":`, err);
|
||||
logger.error(`[command] error executing "${commandName}":`, err);
|
||||
await message
|
||||
.reply('An error occurred while running that command.')
|
||||
.reply({
|
||||
content: null, embeds: [{
|
||||
color: 0x8aa2b3,
|
||||
title: '',
|
||||
author: {
|
||||
name: message.author.username,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
description: '<:no:1481811955592466492> an error occurred while executing that command!',
|
||||
footer: {
|
||||
text: `${message.author.username} @ twitter`,
|
||||
icon_url: message.author.displayAvatarURL(),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
}]
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
},
|
||||
|
||||
+16
-2
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { Events } = require('discord.js');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
@@ -8,7 +10,19 @@ module.exports = {
|
||||
once: true,
|
||||
|
||||
execute(client) {
|
||||
logger.info(`[Ready] Logged in as ${client.user.tag} (${client.user.id})`);
|
||||
logger.info(`[Ready] Serving ${client.guilds.cache.size} guild(s).`);
|
||||
const db_path = path.join(process.cwd(), 'db.json');
|
||||
if (!fs.existsSync(db_path)) {
|
||||
fs.writeFileSync(db_path, JSON.stringify({}, null, 2));
|
||||
logger.info('[db] created db.json');
|
||||
}
|
||||
|
||||
const db = JSON.parse(fs.readFileSync(db_path, 'utf8'));
|
||||
const variables = Object.keys(db);
|
||||
logger.info(`[db] loaded variables from db.json: ${variables.length > 0 ? variables.join(', ') : 'none'}`);
|
||||
|
||||
logger.info(`[ready] logged in as ${client.user.tag} (${client.user.id})`);
|
||||
logger.info(`[ready] serving ${client.guilds.cache.size} guild(s)`);
|
||||
|
||||
client.user.setActivity(`${client.guilds.cache.size} servers`, { type: 'WATCHING' });
|
||||
},
|
||||
};
|
||||
@@ -24,7 +24,7 @@ function loadCommands(client) {
|
||||
|
||||
if (!command.name || typeof command.execute !== 'function') {
|
||||
logger.warn(
|
||||
`[CommandHandler] Skipping ${file}: missing "name" or "execute".`,
|
||||
`[commandhandler] skipping ${file}: missing "name" or "execute"`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@@ -38,14 +38,14 @@ function loadCommands(client) {
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug(`[CommandHandler] Loaded command: ${command.name}`);
|
||||
logger.debug(`[commandhandler] loaded command: ${command.name}`);
|
||||
loaded++;
|
||||
} catch (err) {
|
||||
logger.error(`[CommandHandler] Failed to load ${file}:`, err);
|
||||
logger.error(`[commandhandler] failed to load ${file}:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`[CommandHandler] ${loaded} command(s) loaded.`);
|
||||
logger.info(`[commandhandler] ${loaded} command(s) loaded`);
|
||||
}
|
||||
|
||||
module.exports = { loadCommands };
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { Events } = require('discord.js');
|
||||
const guildMemberAddEvent = require('../events/guildMemberAdd');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
/**
|
||||
@@ -24,7 +26,7 @@ function loadEvents(client) {
|
||||
|
||||
if (!event.name || typeof event.execute !== 'function') {
|
||||
logger.warn(
|
||||
`[EventHandler] Skipping ${file}: missing "name" or "execute".`,
|
||||
`[eventhandler] skipping ${file}: missing "name" or "execute"`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@@ -35,14 +37,17 @@ function loadEvents(client) {
|
||||
client.on(event.name, (...args) => event.execute(client, ...args));
|
||||
}
|
||||
|
||||
logger.debug(`[EventHandler] Registered event: ${event.name}`);
|
||||
logger.debug(`[eventhandler] registered event: ${event.name}`);
|
||||
loaded++;
|
||||
} catch (err) {
|
||||
logger.error(`[EventHandler] Failed to load ${file}:`, err);
|
||||
logger.error(`[eventhandler] failed to load ${file}:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`[EventHandler] ${loaded} event(s) registered.`);
|
||||
client.on(Events.GuildMemberAdd, guildMemberAddEvent.bind(null, client));
|
||||
loaded++;
|
||||
|
||||
logger.info(`[eventhandler] ${loaded} event(s) registered`);
|
||||
}
|
||||
|
||||
module.exports = { loadEvents };
|
||||
+4
-3
@@ -19,6 +19,7 @@ if (!process.env.BOT_TOKEN) {
|
||||
const client = new Client({
|
||||
intents: [
|
||||
GatewayIntentBits.Guilds,
|
||||
GatewayIntentBits.GuildMembers,
|
||||
GatewayIntentBits.GuildMessages,
|
||||
GatewayIntentBits.MessageContent, // Required to read message content for prefix commands
|
||||
GatewayIntentBits.DirectMessages,
|
||||
@@ -34,16 +35,16 @@ loadEvents(client);
|
||||
|
||||
// Global error handling
|
||||
process.on('unhandledRejection', (err) => {
|
||||
logger.error('[Process] Unhandled rejection:', err);
|
||||
logger.error('[process] unhandled rejection:', err);
|
||||
});
|
||||
|
||||
process.on('uncaughtException', (err) => {
|
||||
logger.error('[Process] Uncaught exception:', err);
|
||||
logger.error('[process] uncaught exception:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Connect to Discord
|
||||
client.login(process.env.BOT_TOKEN).catch((err) => {
|
||||
logger.error('[Login] Failed to log in:', err);
|
||||
logger.error('[login] failed to log in:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
+44
-24
@@ -1,45 +1,65 @@
|
||||
'use strict';
|
||||
|
||||
const { createLogger, format, transports } = require('winston');
|
||||
const { combine, timestamp, printf, colorize, errors } = format;
|
||||
const { consoleFormat } = require("winston-console-format");
|
||||
const { printf } = format;
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
// Ensure logs directory exists
|
||||
const logsDir = path.join(__dirname, '..', '..', 'logs');
|
||||
if (!fs.existsSync(logsDir)) {
|
||||
fs.mkdirSync(logsDir, { recursive: true });
|
||||
const logs_dir = path.join(__dirname, '..', '..', 'logs');
|
||||
if (!fs.existsSync(logs_dir)) {
|
||||
fs.mkdirSync(logs_dir, { recursive: true });
|
||||
}
|
||||
|
||||
const logFormat = printf(({ level, message, timestamp: ts, stack }) => {
|
||||
return `[${ts}] [${level}]: ${stack || message}`;
|
||||
});
|
||||
|
||||
const logger = createLogger({
|
||||
level: process.env.LOG_LEVEL || 'info',
|
||||
format: combine(
|
||||
timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
|
||||
errors({ stack: true }),
|
||||
logFormat,
|
||||
level: "silly",
|
||||
format: format.combine(
|
||||
format.timestamp(),
|
||||
format.ms(),
|
||||
format.errors({ stack: true }),
|
||||
format.splat(),
|
||||
format.json()
|
||||
),
|
||||
transports: [
|
||||
// Human-readable coloured output in the console
|
||||
new transports.Console({
|
||||
format: combine(
|
||||
colorize({ all: true }),
|
||||
timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
|
||||
errors({ stack: true }),
|
||||
logFormat,
|
||||
format: format.combine(
|
||||
format.colorize({ all: true }),
|
||||
format.padLevels(),
|
||||
consoleFormat({
|
||||
showMeta: true,
|
||||
metaStrip: ["timestamp", "service"],
|
||||
inspectOptions: {
|
||||
depth: Infinity,
|
||||
colors: true,
|
||||
maxArrayLength: Infinity,
|
||||
breakLength: 120,
|
||||
compact: Infinity,
|
||||
},
|
||||
})
|
||||
),
|
||||
}),
|
||||
// All logs at info level and above written to combined.log
|
||||
|
||||
new transports.File({
|
||||
filename: path.join(logsDir, 'combined.log'),
|
||||
filename: path.join(logs_dir, 'combined.log'),
|
||||
}),
|
||||
// Error logs written to a dedicated file
|
||||
|
||||
new transports.File({
|
||||
filename: path.join(logsDir, 'error.log'),
|
||||
filename: path.join(logs_dir, 'error.log'),
|
||||
level: 'error',
|
||||
format: format.combine(
|
||||
format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss.SSS' }),
|
||||
format.errors({ stack: true }),
|
||||
printf(({ level, message, timestamp, stack, ...meta }) => {
|
||||
let log = `${timestamp} [${level.toUpperCase()}]: ${message}`;
|
||||
if (stack) {
|
||||
log += `\ntrace: ${stack}`;
|
||||
}
|
||||
if (Object.keys(meta).length > 0) {
|
||||
log += `\nmetadata: ${JSON.stringify(meta, null, 2)}`;
|
||||
}
|
||||
return log;
|
||||
})
|
||||
),
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user