diff --git a/package.json b/package.json index b43272a..8d1277d 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "jsonschema": "^1.4.0", "keyv": "^4.0.3", "leeks.js": "^0.2.2", - "leekslazylogger-fastify": "^0.1.1", + "leekslazylogger": "^3.0.2", "mustache": "^4.2.0", "node-emoji": "^1.11.0", "node-fetch": "^2.6.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0380b98..fc6940e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,7 +12,7 @@ specifiers: jsonschema: ^1.4.0 keyv: ^4.0.3 leeks.js: ^0.2.2 - leekslazylogger-fastify: ^0.1.1 + leekslazylogger: ^3.0.2 mariadb: ^2.5.4 mustache: ^4.2.0 mysql2: ^2.3.0 @@ -39,7 +39,7 @@ dependencies: jsonschema: 1.4.0 keyv: 4.0.3 leeks.js: 0.2.2 - leekslazylogger-fastify: 0.1.1 + leekslazylogger: 3.0.2 mustache: 4.2.0 node-emoji: 1.11.0 node-fetch: 2.6.1 @@ -1124,10 +1124,6 @@ packages: safe-buffer: 5.2.1 dev: true - /ee-first/1.1.1: - resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} - dev: false - /emoji-regex/7.0.3: resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} @@ -1326,10 +1322,6 @@ packages: resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=} dev: true - /fastify-plugin/3.0.0: - resolution: {integrity: sha512-ZdCvKEEd92DNLps5n0v231Bha8bkz1DjnPP/aEz37rz/q42Z5JVLmgnqR4DYuNn3NXAO3IDCPyRvgvxtJ4Ym4w==} - dev: false - /figures/3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} @@ -2004,14 +1996,6 @@ packages: resolution: {integrity: sha512-cXbDc4a0ft0pQwN2ubagjsT1xKBeW0CP6pPmbUo+KvKynFwaqtGaBjdtpwkBO5NdwSw2OcJ89BYe9mjeZEfzQQ==} dev: false - /leekslazylogger-fastify/0.1.1: - resolution: {integrity: sha512-O/BFEYpsjCX3/6/GnhwajJ/CA/T9F4AwiRAPyN6y7ET0PgPfv+Q6uLktKiK/ZBcVH0f+VunSPdD0UyTXbzj7wQ==} - dependencies: - fastify-plugin: 3.0.0 - leekslazylogger: 3.0.2 - on-finished: 2.3.0 - dev: false - /leekslazylogger/3.0.2: resolution: {integrity: sha512-eXgQuEgoSIbtwJRQXy/DHFp1255C4br+x6CtOnrBb5j3GwmeARPMutPur1cMB5YonKBZxFXnvZLqQhr69qKg5A==} dependencies: @@ -2438,13 +2422,6 @@ packages: resolution: {integrity: sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==} dev: true - /on-finished/2.3.0: - resolution: {integrity: sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=} - engines: {node: '>= 0.8'} - dependencies: - ee-first: 1.1.1 - dev: false - /once/1.4.0: resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} dependencies: diff --git a/src/commands/add.js b/src/commands/add.js index 1a3e384..54ea608 100644 --- a/src/commands/add.js +++ b/src/commands/add.js @@ -36,65 +36,75 @@ module.exports = class AddCommand extends Command { * @returns {Promise} */ async execute(message, args) { - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); const ticket = message.mentions.channels.first() ?? message.channel; const t_row = await this.client.tickets.resolve(ticket.id, message.guild.id); if (!t_row) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.add.response.not_a_ticket.title')) - .setDescription(i18n('commands.add.response.not_a_ticket.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.add.response.not_a_ticket.title')) + .setDescription(i18n('commands.add.response.not_a_ticket.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } const member = message.mentions.members.first() ?? message.guild.members.cache.get(args); if (!member) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.add.response.no_member.title')) - .setDescription(i18n('commands.add.response.no_member.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.add.response.no_member.title')) + .setDescription(i18n('commands.add.response.no_member.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } - if (t_row.creator !== message.author.id && !await message.member.isStaff()) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.add.response.no_permission.title')) - .setDescription(i18n('commands.add.response.no_permission.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + if (t_row.creator !== message.author.id && !await this.client.utils.isStaff(message.member)) { + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.add.response.no_permission.title')) + .setDescription(i18n('commands.add.response.no_permission.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } if (message.channel.id !== ticket.id) { - await message.channel.send( - new MessageEmbed() - .setColor(settings.success_colour) - .setAuthor(member.user.username, member.user.displayAvatarURL()) - .setTitle(i18n('commands.add.response.added.title')) - .setDescription(i18n('commands.add.response.added.description', member.toString(), ticket.toString())) - .setFooter(settings.footer, message.guild.iconURL()) - ); + await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.success_colour) + .setAuthor(member.user.username, member.user.displayAvatarURL()) + .setTitle(i18n('commands.add.response.added.title')) + .setDescription(i18n('commands.add.response.added.description', member.toString(), ticket.toString())) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } - await ticket.send( - new MessageEmbed() - .setColor(settings.colour) - .setAuthor(member.user.username, member.user.displayAvatarURL()) - .setTitle(i18n('ticket.member_added.title')) - .setDescription(i18n('ticket.member_added.description', member.toString(), message.author.toString())) - .setFooter(settings.footer, message.guild.iconURL()) - ); + await ticket.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setAuthor(member.user.username, member.user.displayAvatarURL()) + .setTitle(i18n('ticket.member_added.title')) + .setDescription(i18n('ticket.member_added.description', member.toString(), message.author.toString())) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); - await ticket.updateOverwrite(member, { + await ticket.permissionOverwrites.edit(member, { ATTACH_FILES: true, READ_MESSAGE_HISTORY: true, SEND_MESSAGES: true, @@ -105,4 +115,4 @@ module.exports = class AddCommand extends Command { this.client.log.info(`${message.author.tag} added ${member.user.tag} to ${ticket.id}`); } -}; \ No newline at end of file +}; diff --git a/src/commands/blacklist.js b/src/commands/blacklist.js index 0c9581d..ef7b90c 100644 --- a/src/commands/blacklist.js +++ b/src/commands/blacklist.js @@ -33,19 +33,21 @@ module.exports = class BlacklistCommand extends Command { * @returns {Promise} */ async execute(message, args) { - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); const member = message.mentions.members.first(); - if (member && (await member.isStaff() || member.hasPermission(this.permissions))) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle(i18n('commands.blacklist.response.illegal_action.title')) - .setDescription(i18n('commands.blacklist.response.illegal_action.description', `<@${member.id}>`)) - .setFooter(settings.footer, message.guild.iconURL()) - ); + if (member && (await this.client.utils.isStaff(member) || member.permissions.has(this.permissions))) { + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(i18n('commands.blacklist.response.illegal_action.title')) + .setDescription(i18n('commands.blacklist.response.illegal_action.description', `<@${member.id}>`)) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } @@ -60,13 +62,15 @@ module.exports = class BlacklistCommand extends Command { } else if (/\d{17,19}/.test(input)) { id = input; } else if (settings.blacklist.length === 0) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle(i18n('commands.blacklist.response.empty_list.title')) - .setDescription(i18n('commands.blacklist.response.empty_list.description', settings.command_prefix)) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(i18n('commands.blacklist.response.empty_list.title')) + .setDescription(i18n('commands.blacklist.response.empty_list.description', settings.command_prefix)) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } else { // list blacklisted members const blacklist = settings.blacklist.map(element => { @@ -74,13 +78,15 @@ module.exports = class BlacklistCommand extends Command { if (is_role) return `» <@&${element}> (\`${element}\`)`; else return `» <@${element}> (\`${element}\`)`; }); - return await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle(i18n('commands.blacklist.response.list.title')) - .setDescription(blacklist.join('\n')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(i18n('commands.blacklist.response.list.title')) + .setDescription(blacklist.join('\n')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } const is_role = role !== undefined || message.guild.roles.cache.has(id); @@ -91,25 +97,29 @@ module.exports = class BlacklistCommand extends Command { if (index === -1) { new_blacklist.push(id); - await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle(i18n(`commands.blacklist.response.${member_or_role}_added.title`)) - .setDescription(i18n(`commands.blacklist.response.${member_or_role}_added.description`, id)) - .setFooter(settings.footer, message.guild.iconURL()) - ); + await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(i18n(`commands.blacklist.response.${member_or_role}_added.title`)) + .setDescription(i18n(`commands.blacklist.response.${member_or_role}_added.description`, id)) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } else { new_blacklist.splice(index, 1); - await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle(i18n(`commands.blacklist.response.${member_or_role}_removed.title`)) - .setDescription(i18n(`commands.blacklist.response.${member_or_role}_removed.description`, id)) - .setFooter(settings.footer, message.guild.iconURL()) - ); + await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(i18n(`commands.blacklist.response.${member_or_role}_removed.title`)) + .setDescription(i18n(`commands.blacklist.response.${member_or_role}_removed.description`, id)) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } settings.blacklist = new_blacklist; await settings.save(); } -}; \ No newline at end of file +}; diff --git a/src/commands/close.js b/src/commands/close.js index d3c6d7c..a63f958 100644 --- a/src/commands/close.js +++ b/src/commands/close.js @@ -7,7 +7,6 @@ const { } = require('discord.js'); const { Op } = require('sequelize'); const toTime = require('to-time-monthsfork'); -const { footer } = require('../utils/discord'); module.exports = class CloseCommand extends Command { constructor(client) { @@ -60,7 +59,7 @@ module.exports = class CloseCommand extends Command { const arg_reason = this.args[1].name; const arg_time = this.args[2].name; - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); if (args[arg_time]) { @@ -69,13 +68,15 @@ module.exports = class CloseCommand extends Command { try { period = toTime(args[arg_time]).ms(); } catch { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.close.response.invalid_time.title')) - .setDescription(i18n('commands.close.response.invalid_time.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.close.response.invalid_time.title')) + .setDescription(i18n('commands.close.response.invalid_time.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } const tickets = await this.client.db.models.Ticket.findAndCountAll({ @@ -86,38 +87,46 @@ module.exports = class CloseCommand extends Command { }); if (tickets.count === 0) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.close.response.no_tickets.title')) - .setDescription(i18n('commands.close.response.no_tickets.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.close.response.no_tickets.title')) + .setDescription(i18n('commands.close.response.no_tickets.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } else { - const collector_message = await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle(i18n('commands.close.response.confirm_multiple.title')) - .setDescription(i18n('commands.close.response.confirm_multiple.description', tickets.count, tickets.count)) - .setFooter(settings.footer, message.guild.iconURL()) - ); + const collector_message = await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(i18n('commands.close.response.confirm_multiple.title')) + .setDescription(i18n('commands.close.response.confirm_multiple.description', tickets.count, tickets.count)) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); await collector_message.react('✅'); - const collector_filter = (reaction, user) => user.id === message.author.id && reaction.emoji.name === '✅'; - - const collector = collector_message.createReactionCollector(collector_filter, { time: 30000 }); + const filter = (reaction, user) => user.id === message.author.id && reaction.emoji.name === '✅'; + const collector = collector_message.createReactionCollector({ + filter, + time: 30000 + }); collector.on('collect', async () => { await collector_message.reactions.removeAll(); - await message.channel.send( - new MessageEmbed() - .setColor(settings.success_colour) - .setTitle(i18n('commands.close.response.closed_multiple.title', tickets.count, tickets.count)) - .setDescription(i18n('commands.close.response.closed_multiple.description', tickets.count, tickets.count)) - .setFooter(settings.footer, message.guild.iconURL()) - ); + await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.success_colour) + .setTitle(i18n('commands.close.response.closed_multiple.title', tickets.count, tickets.count)) + .setDescription(i18n('commands.close.response.closed_multiple.description', tickets.count, tickets.count)) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); for (const ticket of tickets.rows) { await this.client.tickets.close(ticket.id, message.author.id, message.guild.id, args[arg_reason]); @@ -128,14 +137,16 @@ module.exports = class CloseCommand extends Command { collector.on('end', async collected => { if (collected.size === 0) { await collector_message.reactions.removeAll(); - await collector_message.edit( - new MessageEmbed() - .setColor(settings.error_colour) - .setAuthor(message.author.username, message.author.displayAvatarURL()) - .setTitle(i18n('commands.close.response.confirmation_timeout.title')) - .setDescription(i18n('commands.close.response.confirmation_timeout.description')) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) - ); + await collector_message.edit({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setTitle(i18n('commands.close.response.confirmation_timeout.title')) + .setDescription(i18n('commands.close.response.confirmation_timeout.description')) + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) + ] + }); setTimeout(async () => { await collector_message .delete() @@ -155,41 +166,49 @@ module.exports = class CloseCommand extends Command { t_row = await this.client.tickets.resolve(args[arg_ticket], message.guild.id); if (!t_row) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.close.response.unresolvable.title')) - .setDescription(i18n('commands.close.response.unresolvable.description', args[arg_ticket])) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.close.response.unresolvable.title')) + .setDescription(i18n('commands.close.response.unresolvable.description', args[arg_ticket])) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } } else { t_row = await this.client.db.models.Ticket.findOne({ where: { id: message.channel.id } }); if (!t_row) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.close.response.not_a_ticket.title')) - .setDescription(i18n('commands.close.response.not_a_ticket.description', settings.command_prefix)) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.close.response.not_a_ticket.title')) + .setDescription(i18n('commands.close.response.not_a_ticket.description', settings.command_prefix)) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } } - const collector_message = await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle(i18n('commands.close.response.confirm.title')) - .setDescription(i18n('commands.close.response.confirm.description', t_row.number)) - .setFooter(settings.footer, message.guild.iconURL()) - ); + const collector_message = await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(i18n('commands.close.response.confirm.title')) + .setDescription(i18n('commands.close.response.confirm.description', t_row.number)) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); await collector_message.react('✅'); - const collector_filter = (reaction, user) => user.id === message.author.id && reaction.emoji.name === '✅'; - - const collector = collector_message.createReactionCollector(collector_filter, { time: 30000 }); + const filter = (reaction, user) => user.id === message.author.id && reaction.emoji.name === '✅'; + const collector = collector_message.createReactionCollector({ + filter, + time: 30000 + }); collector.on('collect', async () => { collector.stop(); @@ -198,13 +217,15 @@ module.exports = class CloseCommand extends Command { await collector_message.delete(); } else { await collector_message.reactions.removeAll(); - await collector_message.edit( - new MessageEmbed() - .setColor(settings.success_colour) - .setTitle(i18n('commands.close.response.closed.title')) - .setDescription(i18n('commands.close.response.closed.description', t_row.number)) - .setFooter(settings.footer, message.guild.iconURL()) - ); + await collector_message.edit({ + embeds: [ + new MessageEmbed() + .setColor(settings.success_colour) + .setTitle(i18n('commands.close.response.closed.title')) + .setDescription(i18n('commands.close.response.closed.description', t_row.number)) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } await this.client.tickets.close(t_row.id, message.author.id, message.guild.id, args[arg_reason]); @@ -213,14 +234,16 @@ module.exports = class CloseCommand extends Command { collector.on('end', async collected => { if (collected.size === 0) { await collector_message.reactions.removeAll(); - await collector_message.edit( - new MessageEmbed() - .setColor(settings.error_colour) - .setAuthor(message.author.username, message.author.displayAvatarURL()) - .setTitle(i18n('commands.close.response.confirmation_timeout.title')) - .setDescription(i18n('commands.close.response.confirmation_timeout.description')) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) - ); + await collector_message.edit({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setTitle(i18n('commands.close.response.confirmation_timeout.title')) + .setDescription(i18n('commands.close.response.confirmation_timeout.description')) + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) + ] + }); setTimeout(async () => { await collector_message .delete() @@ -234,4 +257,4 @@ module.exports = class CloseCommand extends Command { } } -}; \ No newline at end of file +}; diff --git a/src/commands/help.js b/src/commands/help.js index e43e486..ed500cc 100644 --- a/src/commands/help.js +++ b/src/commands/help.js @@ -33,7 +33,7 @@ module.exports = class HelpCommand extends Command { * @returns {Promise} */ async execute(message, args) { - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); const cmd = this.manager.commands.find(command => command.aliases.includes(args.toLowerCase())); @@ -41,9 +41,9 @@ module.exports = class HelpCommand extends Command { if (cmd) { return await cmd.sendUsage(message.channel, args); } else { - const is_staff = await message.member.isStaff(); + const is_staff = await this.client.utils.isStaff(message.member); const commands = this.manager.commands.filter(command => { - if (command.permissions.length >= 1) return message.member.hasPermission(command.permissions); + if (command.permissions.length >= 1) return message.member.permissions.has(command.permissions); else if (command.staff_only) return is_staff; else return true; }); @@ -53,14 +53,16 @@ module.exports = class HelpCommand extends Command { : command.description; return `**\`${settings.command_prefix}${command.name}\` ·** ${description}`; }); - return await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle(i18n('commands.help.response.list.title')) - .setDescription(i18n('commands.help.response.list.description', { prefix: settings.command_prefix })) - .addField(i18n('commands.help.response.list.fields.commands'), list.join('\n')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(i18n('commands.help.response.list.title')) + .setDescription(i18n('commands.help.response.list.description', { prefix: settings.command_prefix })) + .addField(i18n('commands.help.response.list.fields.commands'), list.join('\n')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } } -}; \ No newline at end of file +}; diff --git a/src/commands/new.js b/src/commands/new.js index 52d9e82..cc91203 100644 --- a/src/commands/new.js +++ b/src/commands/new.js @@ -3,7 +3,6 @@ const { Message, // eslint-disable-line no-unused-vars MessageEmbed } = require('discord.js'); -const { footer } = require('../utils/discord'); const { letters } = require('../utils/emoji'); const { wait } = require('../utils'); @@ -37,7 +36,7 @@ module.exports = class NewCommand extends Command { * @returns {Promise} */ async execute(message, args) { - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); const editOrSend = async (msg, content) => { @@ -57,12 +56,16 @@ module.exports = class NewCommand extends Command { if (tickets.count >= cat_row.max_per_member) { if (cat_row.max_per_member === 1) { response = await editOrSend(response, - new MessageEmbed() - .setColor(settings.error_colour) - .setAuthor(message.author.username, message.author.displayAvatarURL()) - .setTitle(i18n('commands.new.response.has_a_ticket.title')) - .setDescription(i18n('commands.new.response.has_a_ticket.description', tickets.rows[0].id)) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) + { + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setTitle(i18n('commands.new.response.has_a_ticket.title')) + .setDescription(i18n('commands.new.response.has_a_ticket.description', tickets.rows[0].id)) + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) + ] + } ); } else { const list = tickets.rows.map(row => { @@ -75,33 +78,45 @@ module.exports = class NewCommand extends Command { } }); response = await editOrSend(response, - new MessageEmbed() - .setColor(settings.error_colour) - .setAuthor(message.author.username, message.author.displayAvatarURL()) - .setTitle(i18n('commands.new.response.max_tickets.title', tickets.count)) - .setDescription(i18n('commands.new.response.max_tickets.description', settings.command_prefix, list.join('\n'))) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) + { + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setTitle(i18n('commands.new.response.max_tickets.title', tickets.count)) + .setDescription(i18n('commands.new.response.max_tickets.description', settings.command_prefix, list.join('\n'))) + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) + ] + } ); } } else { try { const t_row = await this.client.tickets.create(message.guild.id, message.author.id, cat_row.id, args); response = await editOrSend(response, - new MessageEmbed() - .setColor(settings.success_colour) - .setAuthor(message.author.username, message.author.displayAvatarURL()) - .setTitle(i18n('commands.new.response.created.title')) - .setDescription(i18n('commands.new.response.created.description', `<#${t_row.id}>`)) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) + { + embeds: [ + new MessageEmbed() + .setColor(settings.success_colour) + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setTitle(i18n('commands.new.response.created.title')) + .setDescription(i18n('commands.new.response.created.description', `<#${t_row.id}>`)) + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) + ] + } ); } catch (error) { response = await editOrSend(response, - new MessageEmbed() - .setColor(settings.error_colour) - .setAuthor(message.author.username, message.author.displayAvatarURL()) - .setTitle(i18n('commands.new.response.error.title')) - .setDescription(error.message) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) + { + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setTitle(i18n('commands.new.response.error.title')) + .setDescription(error.message) + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) + ] + } ); } } @@ -119,39 +134,45 @@ module.exports = class NewCommand extends Command { const categories = await this.client.db.models.Category.findAndCountAll({ where: { guild: message.guild.id } }); if (categories.count === 0) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setAuthor(message.author.username, message.author.displayAvatarURL()) - .setTitle(i18n('commands.new.response.no_categories.title')) - .setDescription(i18n('commands.new.response.no_categories.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setTitle(i18n('commands.new.response.no_categories.title')) + .setDescription(i18n('commands.new.response.no_categories.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } else if (categories.count === 1) { create(categories.rows[0]); // skip the category selection } else { const letters_array = Object.values(letters); // convert the A-Z emoji object to an array const category_list = categories.rows.map((category, i) => `${letters_array[i]} » ${category.name}`); // list category names with an A-Z emoji - const collector_message = await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setAuthor(message.author.username, message.author.displayAvatarURL()) - .setTitle(i18n('commands.new.response.select_category.title')) - .setDescription(i18n('commands.new.response.select_category.description', category_list.join('\n'))) - .setFooter(footer(settings.footer, i18n('collector_expires_in', 30)), message.guild.iconURL()) - ); + const collector_message = await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setTitle(i18n('commands.new.response.select_category.title')) + .setDescription(i18n('commands.new.response.select_category.description', category_list.join('\n'))) + .setFooter(this.client.utils.footer(settings.footer, i18n('collector_expires_in', 30)), message.guild.iconURL()) + ] + }); for (const i in categories.rows) { collector_message.react(letters_array[i]); // add the correct number of letter reactions await wait(1000); // 1 reaction per second rate-limit } - const collector_filter = (reaction, user) => { + const filter = (reaction, user) => { const allowed = letters_array.slice(0, categories.count); // get the first x letters of the emoji array return user.id === message.author.id && allowed.includes(reaction.emoji.name); }; - - const collector = collector_message.createReactionCollector(collector_filter, { time: 30000 }); + const collector = collector_message.createReactionCollector({ + filter, + time: 30000 + }); collector.on('collect', async reaction => { collector.stop(); @@ -168,14 +189,16 @@ module.exports = class NewCommand extends Command { collector.on('end', async collected => { if (collected.size === 0) { await collector_message.reactions.removeAll(); - await collector_message.edit( - new MessageEmbed() - .setColor(settings.error_colour) - .setAuthor(message.author.username, message.author.displayAvatarURL()) - .setTitle(i18n('commands.new.response.select_category_timeout.title')) - .setDescription(i18n('commands.new.response.select_category_timeout.description')) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) - ); + await collector_message.edit({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setTitle(i18n('commands.new.response.select_category_timeout.title')) + .setDescription(i18n('commands.new.response.select_category_timeout.description')) + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()) + ] + }); setTimeout(async () => { await collector_message .delete() diff --git a/src/commands/panel.js b/src/commands/panel.js index b228b5f..d7399d4 100644 --- a/src/commands/panel.js +++ b/src/commands/panel.js @@ -69,7 +69,7 @@ module.exports = class PanelCommand extends Command { const arg_emoji = this.args[2].name; const arg_categories = this.args[3].name; - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); if (!args[arg_emoji]) args[arg_emoji] = []; @@ -87,13 +87,15 @@ module.exports = class PanelCommand extends Command { }); if (invalid_category) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.panel.response.invalid_category.title')) - .setDescription(i18n('commands.panel.response.invalid_category.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.panel.response.invalid_category.title')) + .setDescription(i18n('commands.panel.response.invalid_category.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } let panel_channel, @@ -124,23 +126,25 @@ module.exports = class PanelCommand extends Command { position: 1, rateLimitPerUser: 30, reason: `${message.author.tag} created a new reaction-less panel`, - type: 'text' + type: 'GUILD_TEXT' }); embed.setDescription(args[arg_description]); - panel_message = await panel_channel.send(embed); + panel_message = await panel_channel.send({ embeds: [embed] }); this.client.log.info(`${message.author.tag} has created a new reaction-less panel`); } else { if (args[arg_categories].length !== args[arg_emoji].length) { // send error - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.panel.response.mismatch.title')) - .setDescription(i18n('commands.panel.response.mismatch.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.panel.response.mismatch.title')) + .setDescription(i18n('commands.panel.response.mismatch.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } else { panel_channel = await message.guild.channels.create('create-a-ticket', { permissionOverwrites: [ @@ -156,7 +160,7 @@ module.exports = class PanelCommand extends Command { ], position: 1, reason: `${message.author.tag} created a new panel`, - type: 'text' + type: 'GUILD_TEXT' }); if (args[arg_emoji].length === 1) { @@ -164,7 +168,7 @@ module.exports = class PanelCommand extends Command { categories_map = {}; categories_map[args[arg_emoji][0]] = args[arg_categories][0]; embed.setDescription(args[arg_description]); - panel_message = await panel_channel.send(embed); + panel_message = await panel_channel.send({ embeds: [embed] }); await panel_message.react(args[arg_emoji][0]); } else { // multi category @@ -183,7 +187,11 @@ module.exports = class PanelCommand extends Command { } embed.setDescription(args[arg_description] + '\n' + description); - panel_message = await panel_channel.send(embed); + panel_message = await panel_channel.send({ + embeds: [ + embed + ] + }); for (const emoji of args[arg_emoji]) { await panel_message.react(emoji); @@ -196,7 +204,7 @@ module.exports = class PanelCommand extends Command { } } - message.channel.send(`✅ ${panel_channel}`); + message.channel.send({ content: `✅ ${panel_channel}` }); await this.client.db.models.Panel.create({ categories: categories_map, diff --git a/src/commands/remove.js b/src/commands/remove.js index d610303..0b148c8 100644 --- a/src/commands/remove.js +++ b/src/commands/remove.js @@ -36,63 +36,73 @@ module.exports = class RemoveCommand extends Command { * @returns {Promise} */ async execute(message, args) { - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); const ticket = message.mentions.channels.first() ?? message.channel; const t_row = await this.client.tickets.resolve(ticket.id, message.guild.id); if (!t_row) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.remove.response.not_a_ticket.title')) - .setDescription(i18n('commands.remove.response.not_a_ticket.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.remove.response.not_a_ticket.title')) + .setDescription(i18n('commands.remove.response.not_a_ticket.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } const member = message.mentions.members.first() ?? message.guild.members.cache.get(args); if (!member) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.remove.response.no_member.title')) - .setDescription(i18n('commands.remove.response.no_member.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.remove.response.no_member.title')) + .setDescription(i18n('commands.remove.response.no_member.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } - if (t_row.creator !== message.author.id && !await message.member.isStaff()) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.remove.response.no_permission.title')) - .setDescription(i18n('commands.remove.response.no_permission.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + if (t_row.creator !== message.author.id && !await this.client.utils.isStaff(message.member)) { + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.remove.response.no_permission.title')) + .setDescription(i18n('commands.remove.response.no_permission.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } if (message.channel.id !== ticket.id) { - await message.channel.send( - new MessageEmbed() - .setColor(settings.success_colour) - .setAuthor(member.user.username, member.user.displayAvatarURL()) - .setTitle(i18n('commands.remove.response.removed.title')) - .setDescription(i18n('commands.remove.response.removed.description', member.toString(), ticket.toString())) - .setFooter(settings.footer, message.guild.iconURL()) - ); + await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.success_colour) + .setAuthor(member.user.username, member.user.displayAvatarURL()) + .setTitle(i18n('commands.remove.response.removed.title')) + .setDescription(i18n('commands.remove.response.removed.description', member.toString(), ticket.toString())) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } - await ticket.send( - new MessageEmbed() - .setColor(settings.colour) - .setAuthor(member.user.username, member.user.displayAvatarURL()) - .setTitle(i18n('ticket.member_removed.title')) - .setDescription(i18n('ticket.member_removed.description', member.toString(), message.author.toString())) - .setFooter(settings.footer, message.guild.iconURL()) - ); + await ticket.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setAuthor(member.user.username, member.user.displayAvatarURL()) + .setTitle(i18n('ticket.member_removed.title')) + .setDescription(i18n('ticket.member_removed.description', member.toString(), message.author.toString())) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); await ticket.permissionOverwrites .get(member.user.id) @@ -100,4 +110,4 @@ module.exports = class RemoveCommand extends Command { this.client.log.info(`${message.author.tag} removed ${member.user.tag} from ${ticket.id}`); } -}; \ No newline at end of file +}; diff --git a/src/commands/settings.js b/src/commands/settings.js index 5929502..1b9cdea 100644 --- a/src/commands/settings.js +++ b/src/commands/settings.js @@ -31,7 +31,7 @@ module.exports = class SettingsCommand extends Command { * @returns {Promise} */ async execute(message) { - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); const attachments = [...message.attachments.values()]; @@ -48,7 +48,7 @@ module.exports = class SettingsCommand extends Command { if (!valid) { this.client.log.warn('Settings validation error'); - return await message.channel.send(i18n('commands.settings.response.invalid', errors.map(error => `\`${error.stack}\``).join(',\n'))); + return await message.channel.send({ content: i18n('commands.settings.response.invalid', errors.map(error => `\`${error.stack}\``).join(',\n')) }); } settings.colour = data.colour; @@ -84,7 +84,7 @@ module.exports = class SettingsCommand extends Command { if (cat_channel.name !== c.name) await cat_channel.setName(c.name, `Tickets category updated by ${message.author.tag}`); for (const r of c.roles) { - await cat_channel.updateOverwrite(r, { + await cat_channel.permissionOverwrites.edit(r, { ATTACH_FILES: true, READ_MESSAGE_HISTORY: true, SEND_MESSAGES: true, @@ -114,7 +114,7 @@ module.exports = class SettingsCommand extends Command { ], position: 1, reason: `Tickets category created by ${message.author.tag}`, - type: 'category' + type: 'GUILD_CATEGORY' }); await this.client.db.models.Category.create({ @@ -149,7 +149,7 @@ module.exports = class SettingsCommand extends Command { } this.client.log.success(`Updated guild settings for "${message.guild.name}"`); - return await message.channel.send(i18n('commands.settings.response.updated')); + return await message.channel.send({ content: i18n('commands.settings.response.updated') }); } else { // upload settings as json to be edited diff --git a/src/commands/stats.js b/src/commands/stats.js index 9ccbb65..91ad106 100644 --- a/src/commands/stats.js +++ b/src/commands/stats.js @@ -27,7 +27,7 @@ module.exports = class StatsCommand extends Command { * @returns {Promise} */ async execute(message) { - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); const messages = await this.client.db.models.Message.findAndCountAll(); @@ -62,19 +62,25 @@ module.exports = class StatsCommand extends Command { if (stats.messages) guild_embed.addField(i18n('commands.stats.fields.messages'), stats.messages, true); - await message.channel.send(guild_embed); + await message.channel.send({ + embeds: [ + guild_embed + ] + }); if (this.client.guilds.cache.size > 1) { - await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle(i18n('commands.stats.response.global.title')) - .setDescription(i18n('commands.stats.response.global.description')) - .addField(i18n('commands.stats.fields.tickets'), stats.tickets, true) - .addField(i18n('commands.stats.fields.response_time.title'), i18n('commands.stats.fields.response_time.minutes', stats.response_time), true) - .addField(i18n('commands.stats.fields.messages'), stats.messages, true) - .setFooter(settings.footer, message.guild.iconURL()) - ); + await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(i18n('commands.stats.response.global.title')) + .setDescription(i18n('commands.stats.response.global.description')) + .addField(i18n('commands.stats.fields.tickets'), stats.tickets, true) + .addField(i18n('commands.stats.fields.response_time.title'), i18n('commands.stats.fields.response_time.minutes', stats.response_time), true) + .addField(i18n('commands.stats.fields.messages'), stats.messages, true) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } } -}; \ No newline at end of file +}; diff --git a/src/commands/survey.js b/src/commands/survey.js index 2655954..313d532 100644 --- a/src/commands/survey.js +++ b/src/commands/survey.js @@ -38,7 +38,7 @@ module.exports = class SurveyCommand extends Command { * @returns {Promise} */ async execute(message, args) { - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); const survey = await this.client.db.models.Survey.findOne({ @@ -90,13 +90,15 @@ module.exports = class SurveyCommand extends Command { const surveys = await this.client.db.models.Survey.findAll({ where: { guild: message.guild.id } }); const list = surveys.map(s => `❯ **\`${s.name}\`**`); - return await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle(i18n('commands.survey.response.list.title')) - .setDescription(list.join('\n')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(i18n('commands.survey.response.list.title')) + .setDescription(list.join('\n')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } } -}; \ No newline at end of file +}; diff --git a/src/commands/tag.js b/src/commands/tag.js index 2d3423e..805375b 100644 --- a/src/commands/tag.js +++ b/src/commands/tag.js @@ -37,7 +37,7 @@ module.exports = class TagCommand extends Command { * @returns {Promise} */ async execute(message, args) { - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); const t_row = await this.client.db.models.Ticket.findOne({ where: { id: message.channel.id } }); @@ -52,13 +52,15 @@ module.exports = class TagCommand extends Command { const requires_ticket = placeholders.some(p => p.startsWith('ticket.')); if (requires_ticket && !t_row) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.tag.response.not_a_ticket.title')) - .setDescription(i18n('commands.tag.response.not_a_ticket.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.tag.response.not_a_ticket.title')) + .setDescription(i18n('commands.tag.response.not_a_ticket.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } const expected = placeholders @@ -72,13 +74,15 @@ module.exports = class TagCommand extends Command { try { args = parseArgs(expected, { argv: argv(args) }); } catch (error) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.tag.response.error')) - .setDescription(`\`\`\`${error.message}\`\`\``) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.tag.response.error')) + .setDescription(`\`\`\`${error.message}\`\`\``) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } } else { args = {}; @@ -87,13 +91,15 @@ module.exports = class TagCommand extends Command { for (const p of expected) { if (!args[p.name]) { const list = expected.map(p => `\`${p.name}\``); - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.tag.response.error')) - .setDescription(i18n('commands.tag.response.missing', list.join(', '))) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.tag.response.error')) + .setDescription(i18n('commands.tag.response.missing', list.join(', '))) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } } @@ -104,21 +110,25 @@ module.exports = class TagCommand extends Command { // note that this regex is slightly different to the other const text = tag.replace(/(? this.client.i18n.resolve(args, $1)); - return await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setDescription(text) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setDescription(text) + ] + }); } else { const list = Object.keys(settings.tags).map(t => `❯ **\`${t}\`**`); - return await message.channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle(i18n('commands.tag.response.list.title')) - .setDescription(list.join('\n')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(i18n('commands.tag.response.list.title')) + .setDescription(list.join('\n')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } } -}; \ No newline at end of file +}; diff --git a/src/commands/topic.js b/src/commands/topic.js index c3250c3..9da4d42 100644 --- a/src/commands/topic.js +++ b/src/commands/topic.js @@ -30,19 +30,21 @@ module.exports = class TopicCommand extends Command { * @returns {Promise} */ async execute(message, args) { - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); const t_row = await this.client.db.models.Ticket.findOne({ where: { id: message.channel.id } }); if (!t_row) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('commands.topic.response.not_a_ticket.title')) - .setDescription(i18n('commands.topic.response.not_a_ticket.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('commands.topic.response.not_a_ticket.title')) + .setDescription(i18n('commands.topic.response.not_a_ticket.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); } await t_row.update({ topic: this.client.cryptr.encrypt(args) }); @@ -56,24 +58,28 @@ module.exports = class TopicCommand extends Command { .replace(/{+\s?(tag|ping|mention)?\s?}+/gi, member.user.toString()); const opening_message = await message.channel.messages.fetch(t_row.opening_message); - await opening_message.edit( - new MessageEmbed() - .setColor(settings.colour) - .setAuthor(member.user.username, member.user.displayAvatarURL()) - .setDescription(description) - .addField(i18n('ticket.opening_message.fields.topic'), args) - .setFooter(settings.footer, message.guild.iconURL()) - ); + await opening_message.edit({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setAuthor(member.user.username, member.user.displayAvatarURL()) + .setDescription(description) + .addField(i18n('ticket.opening_message.fields.topic'), args) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); - await message.channel.send( - new MessageEmbed() - .setColor(settings.success_colour) - .setAuthor(message.author.username, message.author.displayAvatarURL()) - .setTitle(i18n('commands.topic.response.changed.title')) - .setDescription(i18n('commands.topic.response.changed.description')) - .setFooter(settings.footer, message.guild.iconURL()) - ); + await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.success_colour) + .setAuthor(message.author.username, message.author.displayAvatarURL()) + .setTitle(i18n('commands.topic.response.changed.title')) + .setDescription(i18n('commands.topic.response.changed.description')) + .setFooter(settings.footer, message.guild.iconURL()) + ] + }); this.client.log.info(`${message.author.tag} changed the topic of ${message.channel.id}`); } -}; \ No newline at end of file +}; diff --git a/src/index.js b/src/index.js index 6258af8..af5001c 100644 --- a/src/index.js +++ b/src/index.js @@ -83,7 +83,7 @@ process.on('unhandledRejection', error => { log.error(error); }); -const { selectPresence } = require('./utils/discord'); +const DiscordUtils = require('./utils/discord'); const Cryptr = require('cryptr'); const I18n = require('@eartharoid/i18n'); const ListenerLoader = require('./modules/listeners/loader'); @@ -93,14 +93,12 @@ const TicketManager = require('./modules/tickets/manager'); const fetch = require('node-fetch'); -require('./modules/structures')(); // load extended structures before creating the client - const { Client, Intents } = require('discord.js'); // eslint-disable-next-line no-unused-vars -const FastifyLogger = require('leekslazylogger-fastify'); +const Logger = require('leekslazylogger'); /** * The Discord client @@ -110,13 +108,18 @@ const FastifyLogger = require('leekslazylogger-fastify'); class Bot extends Client { constructor() { super({ + intents: [ + Intents.FLAGS.GUILDS, + Intents.FLAGS.GUILD_MEMBERS, + Intents.FLAGS.GUILD_MESSAGES, + Intents.FLAGS.GUILD_MESSAGE_REACTIONS + ], partials: [ 'CHANNEL', 'MESSAGE', 'REACTION' ], - presence: selectPresence(), - ws: { intents: Intents.NON_PRIVILEGED } + presence: DiscordUtils.selectPresence() }); (async () => { @@ -125,7 +128,7 @@ class Bot extends Client { /** * A [leekslazylogger](https://logger.eartharoid.me) instance - * @type {FastifyLogger} + * @type {Logger} */ this.log = log; @@ -170,6 +173,9 @@ class Bot extends Client { this.plugins = new PluginManager(this); this.plugins.load(); // load plugins + /** Some utility methods */ + this.utils = new DiscordUtils(this); + this.log.info('Connecting to Discord API...'); this.login(); diff --git a/src/listeners/guildDelete.js b/src/listeners/guildDelete.js index f98544d..6d06581 100644 --- a/src/listeners/guildDelete.js +++ b/src/listeners/guildDelete.js @@ -7,6 +7,6 @@ module.exports = class GuildDeleteEventListener extends EventListener { async execute(guild) { this.client.log.info(`Removed from "${guild.name}"`); - // await guild.deleteSettings(); + await guild.deleteSettings(); } }; \ No newline at end of file diff --git a/src/listeners/message.js b/src/listeners/messageCreate.js similarity index 76% rename from src/listeners/message.js rename to src/listeners/messageCreate.js index 872085d..f1de5d6 100644 --- a/src/listeners/message.js +++ b/src/listeners/messageCreate.js @@ -1,17 +1,16 @@ const EventListener = require('../modules/listeners/listener'); const { MessageEmbed } = require('discord.js'); -const { footer } = require('../utils/discord'); -module.exports = class MessageEventListener extends EventListener { +module.exports = class MessageCreateEventListener extends EventListener { constructor(client) { - super(client, { event: 'message' }); + super(client, { event: 'messageCreate' }); } async execute(message) { if (!message.guild) return; - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); const t_row = await this.client.db.models.Ticket.findOne({ where: { id: message.channel.id } }); @@ -53,11 +52,11 @@ module.exports = class MessageEventListener extends EventListener { .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(i18n('commands.new.response.has_a_ticket.title')) .setDescription(i18n('commands.new.response.has_a_ticket.description', tickets.rows[0].id)) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()); + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()); try { - response = await message.author.send(embed); + response = await message.author.send({ embeds: [embed] }); } catch { - response = await message.channel.send(embed); + response = await message.channel.send({ embeds: [embed] }); } } else { const list = tickets.rows.map(row => { @@ -74,11 +73,11 @@ module.exports = class MessageEventListener extends EventListener { .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(i18n('commands.new.response.max_tickets.title', tickets.count)) .setDescription(i18n('commands.new.response.max_tickets.description', settings.command_prefix, list.join('\n'))) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.author.iconURL()); + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.author.iconURL()); try { - response = await message.author.send(embed); + response = await message.author.send({ embeds: [embed] }); } catch { - response = await message.channel.send(embed); + response = await message.channel.send({ embeds: [embed] }); } } } else { @@ -90,11 +89,11 @@ module.exports = class MessageEventListener extends EventListener { .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(i18n('commands.new.response.error.title')) .setDescription(error.message) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()); + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), message.guild.iconURL()); try { - response = await message.author.send(embed); + response = await message.author.send({ embeds: [embed] }); } catch { - response = await message.channel.send(embed); + response = await message.channel.send({ embeds: [embed] }); } } } diff --git a/src/listeners/messageDelete.js b/src/listeners/messageDelete.js index 0bc1ff9..d817a59 100644 --- a/src/listeners/messageDelete.js +++ b/src/listeners/messageDelete.js @@ -8,7 +8,7 @@ module.exports = class MessageDeleteEventListener extends EventListener { async execute(message) { if (!message.guild) return; - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); if (settings.log_messages && !message.system) this.client.tickets.archives.deleteMessage(message); // mark the message as deleted in the database (if it exists) } diff --git a/src/listeners/messageReactionAdd.js b/src/listeners/messageReactionAdd.js index 64f0365..e72c936 100644 --- a/src/listeners/messageReactionAdd.js +++ b/src/listeners/messageReactionAdd.js @@ -1,7 +1,6 @@ const EventListener = require('../modules/listeners/listener'); const { MessageEmbed } = require('discord.js'); -const { footer } = require('../utils/discord'); module.exports = class MessageReactionAddEventListener extends EventListener { constructor(client) { @@ -31,7 +30,7 @@ module.exports = class MessageReactionAddEventListener extends EventListener { const guild = reaction.message.guild; if (!guild) return; - const settings = await guild.getSettings(); + const settings = await this.client.utils.getSettings(guild); const i18n = this.client.i18n.getLocale(settings.locale); const channel = reaction.message.channel; @@ -50,29 +49,31 @@ module.exports = class MessageReactionAddEventListener extends EventListener { const t_row = await this.client.db.models.Ticket.findOne({ where: { id: channel.id } }); if (t_row && t_row.opening_message === reaction.message.id) { - if (reaction.emoji.name === '🙌' && await member.isStaff()) { + if (reaction.emoji.name === '🙌' && await this.client.utils.isStaff(member)) { // ticket claiming await t_row.update({ claimed_by: member.user.id }); - await channel.updateOverwrite(member.user.id, { VIEW_CHANNEL: true }, `Ticket claimed by ${member.user.tag}`); + await channel.permissionOverwrites.edit(member.user.id, { VIEW_CHANNEL: true }, `Ticket claimed by ${member.user.tag}`); const cat_row = await this.client.db.models.Category.findOne({ where: { id: t_row.category } }); for (const role of cat_row.roles) { - await channel.updateOverwrite(role, { VIEW_CHANNEL: false }, `Ticket claimed by ${member.user.tag}`); + await channel.permissionOverwrites.edit(role, { VIEW_CHANNEL: false }, `Ticket claimed by ${member.user.tag}`); } this.client.log.info(`${member.user.tag} has claimed "${channel.name}" in "${guild.name}"`); - await channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setAuthor(member.user.username, member.user.displayAvatarURL()) - .setTitle(i18n('ticket.claimed.title')) - .setDescription(i18n('ticket.claimed.description', member.toString())) - .setFooter(settings.footer, guild.iconURL()) - ); + await channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setAuthor(member.user.username, member.user.displayAvatarURL()) + .setTitle(i18n('ticket.claimed.title')) + .setDescription(i18n('ticket.claimed.description', member.toString())) + .setFooter(settings.footer, guild.iconURL()) + ] + }); } else { await reaction.users.remove(user.id); } @@ -105,11 +106,11 @@ module.exports = class MessageReactionAddEventListener extends EventListener { .setAuthor(user.username, user.displayAvatarURL()) .setTitle(i18n('commands.new.response.has_a_ticket.title')) .setDescription(i18n('commands.new.response.has_a_ticket.description', tickets.rows[0].id)) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), guild.iconURL()); + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), guild.iconURL()); try { - response = await user.send(embed); + response = await user.send({ embeds: [embed] }); } catch { - response = await channel.send(embed); + response = await channel.send({ embeds: [embed] }); } } else { const list = tickets.rows.map(row => { @@ -126,11 +127,11 @@ module.exports = class MessageReactionAddEventListener extends EventListener { .setAuthor(user.username, user.displayAvatarURL()) .setTitle(i18n('commands.new.response.max_tickets.title', tickets.count)) .setDescription(i18n('commands.new.response.max_tickets.description', settings.command_prefix, list.join('\n'))) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), user.iconURL()); + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), user.iconURL()); try { - response = await user.send(embed); + response = await user.send({ embeds: [embed] }); } catch { - response = await channel.send(embed); + response = await channel.send({ embeds: [embed] }); } } } else { @@ -142,11 +143,11 @@ module.exports = class MessageReactionAddEventListener extends EventListener { .setAuthor(user.username, user.displayAvatarURL()) .setTitle(i18n('commands.new.response.error.title')) .setDescription(error.message) - .setFooter(footer(settings.footer, i18n('message_will_be_deleted_in', 15)), guild.iconURL()); + .setFooter(this.client.utils.footer(settings.footer, i18n('message_will_be_deleted_in', 15)), guild.iconURL()); try { - response = await user.send(embed); + response = await user.send({ embeds: [embed] }); } catch { - response = await channel.send(embed); + response = await channel.send({ embeds: [embed] }); } } } diff --git a/src/listeners/messageReactionRemove.js b/src/listeners/messageReactionRemove.js index 7acd4c2..d3d274d 100644 --- a/src/listeners/messageReactionRemove.js +++ b/src/listeners/messageReactionRemove.js @@ -30,7 +30,7 @@ module.exports = class MessageReactionRemoveEventListener extends EventListener const guild = reaction.message.guild; if (!guild) return; - const settings = await guild.getSettings(); + const settings = await this.client.utils.getSettings(guild); const i18n = this.client.i18n.getLocale(settings.locale); const channel = reaction.message.channel; @@ -39,7 +39,7 @@ module.exports = class MessageReactionRemoveEventListener extends EventListener const t_row = await this.client.db.models.Ticket.findOne({ where: { id: channel.id } }); if (t_row && t_row.opening_message === reaction.message.id) { - if (reaction.emoji.name === '🙌' && await member.isStaff()) { + if (reaction.emoji.name === '🙌' && await this.client.utils.isStaff(member)) { // ticket claiming await t_row.update({ claimed_by: null }); @@ -51,19 +51,21 @@ module.exports = class MessageReactionRemoveEventListener extends EventListener const cat_row = await this.client.db.models.Category.findOne({ where: { id: t_row.category } }); for (const role of cat_row.roles) { - await channel.updateOverwrite(role, { VIEW_CHANNEL: true }, `Ticket released by ${member.user.tag}`); + await channel.permissionOverwrites.edit(role, { VIEW_CHANNEL: true }, `Ticket released by ${member.user.tag}`); } this.client.log.info(`${member.user.tag} has released "${channel.name}" in "${guild.name}"`); - await channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setAuthor(member.user.username, member.user.displayAvatarURL()) - .setTitle(i18n('ticket.released.title')) - .setDescription(i18n('ticket.released.description', member.toString())) - .setFooter(settings.footer, guild.iconURL()) - ); + await channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setAuthor(member.user.username, member.user.displayAvatarURL()) + .setTitle(i18n('ticket.released.title')) + .setDescription(i18n('ticket.released.description', member.toString())) + .setFooter(settings.footer, guild.iconURL()) + ] + }); } } } diff --git a/src/listeners/messageUpdate.js b/src/listeners/messageUpdate.js index 8ab7b18..ec286d5 100644 --- a/src/listeners/messageUpdate.js +++ b/src/listeners/messageUpdate.js @@ -16,7 +16,7 @@ module.exports = class MessageUpdateEventListener extends EventListener { if (!newm.guild) return; - const settings = await newm.guild.getSettings(); + const settings = await this.client.utils.getSettings(newm.guild); if (settings.log_messages && !newm.system) this.client.tickets.archives.updateMessage(newm); // update the message in the database } diff --git a/src/listeners/ready.js b/src/listeners/ready.js index fbc6b53..3230b54 100644 --- a/src/listeners/ready.js +++ b/src/listeners/ready.js @@ -20,7 +20,7 @@ module.exports = class ReadyEventListener extends EventListener { setInterval(() => { const presence = selectPresence(); this.client.user.setPresence(presence); - this.client.log.debug(`Updated presence: ${presence.activity.type} ${presence.activity.name}`); + this.client.log.debug(`Updated presence: ${presence.activities[0].type} ${presence.activities[0].name}`); }, this.client.config.presence.duration * 1000); } diff --git a/src/logger.js b/src/logger.js index 2fb156e..7768cd6 100644 --- a/src/logger.js +++ b/src/logger.js @@ -1,6 +1,6 @@ const { path } = require('./utils/fs'); const config = require('../user/config'); -const Logger = require('leekslazylogger-fastify'); +const Logger = require('leekslazylogger'); module.exports = new Logger({ debug: config.debug, directory: path('./logs/'), diff --git a/src/modules/commands/command.js b/src/modules/commands/command.js index 9403341..f4a0237 100644 --- a/src/modules/commands/command.js +++ b/src/modules/commands/command.js @@ -122,7 +122,7 @@ module.exports = class Command { * @returns {Promise} */ async sendUsage(channel, alias) { - const settings = await channel.guild.getSettings(); + const settings = await this.client.utils.getSettings(channel.guild); if (!alias) alias = this.name; const prefix = settings.command_prefix; @@ -156,7 +156,7 @@ module.exports = class Command { } this.args.forEach(arg => addArgs(embed, arg)); - return await channel.send(embed); + return await channel.send({ embeds: [embed] }); } diff --git a/src/modules/commands/manager.js b/src/modules/commands/manager.js index 7dd6210..ff99568 100644 --- a/src/modules/commands/manager.js +++ b/src/modules/commands/manager.js @@ -72,7 +72,7 @@ module.exports = class CommandManager { async handle(message) { if (message.author.bot) return; // ignore self and other bots - const settings = await message.guild.getSettings(); + const settings = await this.client.utils.getSettings(message.guild); const i18n = this.client.i18n.getLocale(settings.locale); const prefix = settings.command_prefix; const escaped_prefix = prefix.toLowerCase().replace(/(?=\W)/g, '\\'); // (lazy) escape every character so it can be used in a RexExp @@ -122,14 +122,16 @@ module.exports = class CommandManager { if (!bot_permissions.has(required_bot_permissions)) { const perms = required_bot_permissions.map(p => `\`${p}\``).join(', '); if (bot_permissions.has(['EMBED_LINKS', 'SEND_MESSAGES'])) { - await message.channel.send( - new MessageEmbed() - .setColor('ORANGE') - .setTitle(i18n('bot.missing_permissions.title')) - .setDescription(i18n('bot.missing_permissions.description', perms)) - ); + await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor('ORANGE') + .setTitle(i18n('bot.missing_permissions.title')) + .setDescription(i18n('bot.missing_permissions.description', perms)) + ] + }); } else if (bot_permissions.has('SEND_MESSAGES')) { - await message.channel.send('⚠️ ' + i18n('bot.missing_permissions.description', perms)); + await message.channel.send({ content: '⚠️ ' + i18n('bot.missing_permissions.description', perms) }); } else if (bot_permissions.has('ADD_REACTIONS')) { await message.react('⚠️'); } else { @@ -138,24 +140,28 @@ module.exports = class CommandManager { return; } - const missing_permissions = cmd.permissions instanceof Array && !message.member.hasPermission(cmd.permissions); + const missing_permissions = cmd.permissions instanceof Array && !message.member.permissions.has(cmd.permissions); if (missing_permissions) { const perms = cmd.permissions.map(p => `\`${p}\``).join(', '); - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('missing_permissions.title')) - .setDescription(i18n('missing_permissions.description', perms)) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('missing_permissions.title')) + .setDescription(i18n('missing_permissions.description', perms)) + ] + }); } - if (cmd.staff_only && await message.member.isStaff() === false) { - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('staff_only.title')) - .setDescription(i18n('staff_only.description')) - ); + if (cmd.staff_only && await this.client.utils.isStaff(message.member) === false) { + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('staff_only.title')) + .setDescription(i18n('staff_only.description')) + ] + }); } let args = raw_args; @@ -165,12 +171,14 @@ module.exports = class CommandManager { args = parseArgs(cmd.args, { argv: argv(raw_args) }); } catch (error) { const help_cmd = `${settings.command_prefix}${i18n('commands.help.name')} ${cmd_name}`; - return await message.channel.send( - new MessageEmbed() - .setColor(settings.error_colour) - .setTitle(i18n('cmd_usage.invalid_named_args.title')) - .setDescription(i18n('cmd_usage.invalid_named_args.description', error.message, help_cmd)) - ); + return await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.error_colour) + .setTitle(i18n('cmd_usage.invalid_named_args.title')) + .setDescription(i18n('cmd_usage.invalid_named_args.description', error.message, help_cmd)) + ] + }); } for (const arg of cmd.args) { if (arg.required && args[arg.name] === undefined) { @@ -191,13 +199,15 @@ module.exports = class CommandManager { } catch (e) { this.client.log.warn(`An error occurred whilst executing the ${cmd.name} command`); this.client.log.error(e); - await message.channel.send( - new MessageEmbed() - .setColor('ORANGE') - .setTitle(i18n('command_execution_error.title')) - .setDescription(i18n('command_execution_error.description')) - ); // hopefully no user will ever see this message + await message.channel.send({ + embeds: [ + new MessageEmbed() + .setColor('ORANGE') + .setTitle(i18n('command_execution_error.title')) + .setDescription(i18n('command_execution_error.description')) + ] + }); // hopefully no user will ever see this message } } -}; \ No newline at end of file +}; diff --git a/src/modules/structures.js b/src/modules/structures.js deleted file mode 100644 index ac5167f..0000000 --- a/src/modules/structures.js +++ /dev/null @@ -1,9 +0,0 @@ -const fs = require('fs'); -const { path } = require('../utils/fs'); - -module.exports = () => { - const files = fs.readdirSync(path('./src/structures')) - .filter(file => file.endsWith('.js')); - - for (const file of files) require(`../structures/${file}`); -}; \ No newline at end of file diff --git a/src/modules/tickets/manager.js b/src/modules/tickets/manager.js index bb065a5..da9d228 100644 --- a/src/modules/tickets/manager.js +++ b/src/modules/tickets/manager.js @@ -2,7 +2,6 @@ const EventEmitter = require('events'); const TicketArchives = require('./archives'); const { MessageEmbed } = require('discord.js'); -const { footer } = require('../../utils/discord'); /** Manages tickets */ module.exports = class TicketManager extends EventEmitter { @@ -51,10 +50,10 @@ module.exports = class TicketManager extends EventEmitter { parent: category_id, reason: `${creator.user.tag} requested a new ticket channel`, topic: `${creator}${topic.length > 0 ? ` | ${topic}` : ''}`, - type: 'text' + type: 'GUILD_TEXT' }); - t_channel.updateOverwrite(creator_id, { + t_channel.permissionOverwrites.edit(creator_id, { ATTACH_FILES: true, READ_MESSAGE_HISTORY: true, SEND_MESSAGES: true, @@ -71,7 +70,7 @@ module.exports = class TicketManager extends EventEmitter { }); (async () => { - const settings = await guild.getSettings(); + const settings = await this.client.utils.getSettings(guild); const i18n = this.client.i18n.getLocale(settings.locale); topic = t_row.topic @@ -85,11 +84,11 @@ module.exports = class TicketManager extends EventEmitter { ? '@here' : `<@&${id}>`); - await t_channel.send(mentions.join(', ')); + await t_channel.send({ content: mentions.join(', ') }); } if (cat_row.image) { - await t_channel.send(cat_row.image); + await t_channel.send({ content: cat_row.image }); } const description = cat_row.opening_message @@ -103,7 +102,10 @@ module.exports = class TicketManager extends EventEmitter { if (topic) embed.addField(i18n('ticket.opening_message.fields.topic'), topic); - const sent = await t_channel.send(creator.user.toString(), embed); + const sent = await t_channel.send({ + content: creator.user.toString(), + embeds: [embed] + }); await sent.pin({ reason: 'Ticket opening message' }); await t_row.update({ opening_message: sent.id }); @@ -128,17 +130,21 @@ module.exports = class TicketManager extends EventEmitter { } if (cat_row.require_topic && topic.length === 0) { - const collector_message = await t_channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle('⚠️ ' + i18n('commands.new.request_topic.title')) - .setDescription(i18n('commands.new.request_topic.description')) - .setFooter(footer(settings.footer, i18n('collector_expires_in', 120)), guild.iconURL()) - ); + const collector_message = await t_channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle('⚠️ ' + i18n('commands.new.request_topic.title')) + .setDescription(i18n('commands.new.request_topic.description')) + .setFooter(this.client.utils.footer(settings.footer, i18n('collector_expires_in', 120)), guild.iconURL()) + ] + }); - const collector_filter = message => message.author.id === t_row.creator; - - const collector = t_channel.createMessageCollector(collector_filter, { time: 120000 }); + const filter = message => message.author.id === t_row.creator; + const collector = t_channel.createMessageCollector({ + filter, + time: 120000 + }); collector.on('collect', async message => { topic = message.content; @@ -161,22 +167,26 @@ module.exports = class TicketManager extends EventEmitter { .delete() .catch(() => this.client.log.warn('Failed to delete topic collector message')); if (cat_row.opening_questions) { - await t_channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setDescription(i18n('ticket.questions', questions)) - .setFooter(settings.footer, guild.iconURL()) - ); + await t_channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setDescription(i18n('ticket.questions', questions)) + .setFooter(settings.footer, guild.iconURL()) + ] + }); } }); } else { if (cat_row.opening_questions) { - await t_channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setDescription(i18n('ticket.questions', questions)) - .setFooter(settings.footer, guild.iconURL()) - ); + await t_channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setDescription(i18n('ticket.questions', questions)) + .setFooter(settings.footer, guild.iconURL()) + ] + }); } } })(); @@ -203,7 +213,7 @@ module.exports = class TicketManager extends EventEmitter { this.emit('beforeClose', ticket_id); const guild = this.client.guilds.cache.get(t_row.guild); - const settings = await guild.getSettings(); + const settings = await this.client.utils.getSettings(guild); const i18n = this.client.i18n.getLocale(settings.locale); const channel = await this.client.channels.fetch(t_row.id); @@ -224,14 +234,16 @@ module.exports = class TicketManager extends EventEmitter { const description = reason ? i18n('ticket.closed_by_member_with_reason.description', closer.user.toString(), reason) : i18n('ticket.closed_by_member.description', closer.user.toString()); - await channel.send( - new MessageEmbed() - .setColor(settings.success_colour) - .setAuthor(closer.user.username, closer.user.displayAvatarURL()) - .setTitle(i18n('ticket.closed.title')) - .setDescription(description) - .setFooter(settings.footer, guild.iconURL()) - ); + await channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.success_colour) + .setAuthor(closer.user.username, closer.user.displayAvatarURL()) + .setTitle(i18n('ticket.closed.title')) + .setDescription(description) + .setFooter(settings.footer, guild.iconURL()) + ] + }); setTimeout(async () => { await channel.delete(`Ticket channel closed by ${closer.user.tag}${reason ? `: "${reason}"` : ''}`); @@ -242,13 +254,15 @@ module.exports = class TicketManager extends EventEmitter { const description = reason ? i18n('ticket.closed_with_reason.description') : i18n('ticket.closed.description'); - await channel.send( - new MessageEmbed() - .setColor(settings.success_colour) - .setTitle(i18n('ticket.closed.title')) - .setDescription(description) - .setFooter(settings.footer, guild.iconURL()) - ); + await channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.success_colour) + .setTitle(i18n('ticket.closed.title')) + .setDescription(description) + .setFooter(settings.footer, guild.iconURL()) + ] + }); setTimeout(async () => { await channel.delete(`Ticket channel closed${reason ? `: "${reason}"` : ''}`); @@ -272,20 +286,25 @@ module.exports = class TicketManager extends EventEmitter { }); if (survey) { - const r_collector_message = await channel.send( - creator.toString(), - new MessageEmbed() - .setColor(settings.colour) - .setTitle(i18n('ticket.survey.start.title')) - .setDescription(i18n('ticket.survey.start.description', creator.toString(), survey.questions.length)) - .setFooter(i18n('collector_expires_in', 60)) - ); + const r_collector_message = await channel.send({ + content: creator.toString(), + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(i18n('ticket.survey.start.title')) + .setDescription(i18n('ticket.survey.start.description', creator.toString(), survey.questions.length)) + .setFooter(i18n('collector_expires_in', 60)) + ] + }); await r_collector_message.react('✅'); - const collector_filter = (reaction, user) => user.id === creator.user.id && reaction.emoji.name === '✅'; + const filter = (reaction, user) => user.id === creator.user.id && reaction.emoji.name === '✅'; - const r_collector = r_collector_message.createReactionCollector(collector_filter, { time: 60000 }); + const r_collector = r_collector_message.createReactionCollector({ + filter, + time: 60000 + }); r_collector.on('collect', async () => { r_collector.stop(); @@ -293,17 +312,20 @@ module.exports = class TicketManager extends EventEmitter { let answers = []; let number = 1; for (const question of survey.questions) { - await channel.send( - new MessageEmbed() - .setColor(settings.colour) - .setTitle(`${number++}/${survey.questions.length}`) - .setDescription(question) - .setFooter(i18n('collector_expires_in', 60)) - ); + await channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.colour) + .setTitle(`${number++}/${survey.questions.length}`) + .setDescription(question) + .setFooter(i18n('collector_expires_in', 60)) + ] + }); try { - const collected = await channel.awaitMessages(filter, { + const collected = await channel.awaitMessages({ errors: ['time'], + filter, max: 1, time: 60000 }); @@ -313,13 +335,15 @@ module.exports = class TicketManager extends EventEmitter { } } - await channel.send( - new MessageEmbed() - .setColor(settings.success_colour) - .setTitle(i18n('ticket.survey.complete.title')) - .setDescription(i18n('ticket.survey.complete.description')) - .setFooter(settings.footer, guild.iconURL()) - ); + await channel.send({ + embeds: [ + new MessageEmbed() + .setColor(settings.success_colour) + .setTitle(i18n('ticket.survey.complete.title')) + .setDescription(i18n('ticket.survey.complete.description')) + .setFooter(settings.footer, guild.iconURL()) + ] + }); answers = answers.map(a => this.client.cryptr.encrypt(a)); await this.client.db.models.SurveyResponse.create({ diff --git a/src/structures/guild.js b/src/structures/guild.js deleted file mode 100644 index 392464e..0000000 --- a/src/structures/guild.js +++ /dev/null @@ -1,21 +0,0 @@ -const { Structures } = require('discord.js'); - -Structures.extend('Guild', Guild => class extends Guild { - constructor(client, data) { - super(client, data); - } - - async deleteSettings() { - const row = await this.settings; - return await row.destroy(); - } - - async getSettings() { - const data = { id: this.id }; - const [settings] = await this.client.db.models.Guild.findOrCreate({ - defaults: data, - where: data - }); - return settings; - } -}); \ No newline at end of file diff --git a/src/structures/guild_member.js b/src/structures/guild_member.js deleted file mode 100644 index ae53569..0000000 --- a/src/structures/guild_member.js +++ /dev/null @@ -1,14 +0,0 @@ -const { Structures } = require('discord.js'); - -Structures.extend('GuildMember', GuildMember => class extends GuildMember { - constructor(client, data, guild) { - super(client, data, guild); - } - - async isStaff() { - const guild_categories = await this.client.db.models.Category.findAll({ where: { guild: this.guild.id } }); - - return guild_categories.some(cat => cat.roles.some(r => this.roles.cache.has(r))); - } - -}); \ No newline at end of file diff --git a/src/utils/discord.js b/src/utils/discord.js index 55b59ae..6b97178 100644 --- a/src/utils/discord.js +++ b/src/utils/discord.js @@ -1,23 +1,66 @@ -const config = require('../../user/config'); +const { + Guild, // eslint-disable-line no-unused-vars + GuildMember // eslint-disable-line no-unused-vars +} = require('discord.js'); +const config = require('../../user/config'); let current_presence = -1; -module.exports = { +module.exports = class DiscordUtils { + constructor(client) { + this.client = client; + } + /** - * + * Generate embed footer text * @param {string} text * @param {string} [additional] * @returns {string} */ - footer: (text, additional) => { + footer(text, additional) { if (text && additional) return `${text} | ${additional}`; else return additional || text || ''; - }, + } + + /** + * Check if a guild member is staff + * @param {GuildMember} member - the guild member + * @returns {boolean} + */ + async isStaff(member) { + const guild_categories = await this.client.db.models.Category.findAll({ where: { guild: member.guild.id } }); + return guild_categories.some(cat => cat.roles.some(r => member.roles.cache.has(r))); + } + + /** + * get a guild's settings + * @param {Guild} guild - The Guild + * @returns {Promise} + */ + async getSettings(guild) { + const data = { id: guild.id }; + const [settings] = await this.client.db.models.Guild.findOrCreate({ + defaults: data, + where: data + }); + return settings; + } + + /** + * Delete a guild's settings + * @param {Guild} guild - The Guild + * @returns {Promise} + */ + async deleteSettings(guild) { + const row = await this.getSettings(guild); + return await row.destroy(); + } + /** * Select a presence from the config * @returns {PresenceData} */ - selectPresence: () => { + static selectPresence() { const length = config.presence.presences.length; if (length === 0) return {}; @@ -42,11 +85,13 @@ module.exports = { } = config.presence.presences[num]; return { - activity: { - name, - type, - url - }, + activities: [ + { + name, + type, + url + } + ], status }; }