mirror of
https://github.com/Hessenuk/DiscordTickets.git
synced 2025-09-06 18:21:25 +03:00
* feat: make command handler slash command-ready Only `help` and `settings` commands work so far * feat(commands): finish new settings command * fix(settings): convert `roles` and `ping` to an array * fix(commands): make `add` a slash command * fix(commands): make `blacklist` a slash command * fix(commands): remove URLs from `help` command * Add weblate badge and overview image * Update sponsors * sqlite things * imrpovements * update eslint rules * (⚠ untested) close command * fix: default locale for getting command option names * Update README.md * Update README.md * Update README.md * update new command to slash commands and fix close command * fixes and improvements * fix: closing a ticket when the creator has left * Revert "fix: closing a ticket when the creator has left" This reverts commit afc40ae17077782e344fd8cee03a089966c2347e. * fix: closing a ticket when the creator has left * fix: localisation issues in settings command * fix: delete category channel * New button and select panels + updated message panels Includes new options for panel embed message image and thumbnail Co-Authored-By: Puneet Gopinath <baalkrshna@gmail.com> Co-Authored-By: thevisuales <6569806+thevisuales@users.noreply.github.com> * Finish converting to buttons, added close button Co-Authored-By: Puneet Gopinath <baalkrshna@gmail.com> Co-Authored-By: thevisuales <6569806+thevisuales@users.noreply.github.com> * fully convert to slash commands * re-add "... has created a ticket" message * locales * fix add and remove commands * fix remove command * fix stats command * eslint Co-authored-by: Puneet Gopinath <baalkrshna@gmail.com> Co-authored-by: thevisuales <6569806+thevisuales@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
const Command = require('../modules/commands/command');
|
||||
const {
|
||||
Message, // eslint-disable-line no-unused-vars
|
||||
Interaction, // eslint-disable-line no-unused-vars
|
||||
MessageEmbed
|
||||
} = require('discord.js');
|
||||
|
||||
@@ -8,111 +8,111 @@ module.exports = class AddCommand extends Command {
|
||||
constructor(client) {
|
||||
const i18n = client.i18n.getLocale(client.config.locale);
|
||||
super(client, {
|
||||
aliases: [],
|
||||
args: [
|
||||
{
|
||||
description: i18n('commands.add.args.member.description'),
|
||||
example: i18n('commands.add.args.member.example'),
|
||||
name: i18n('commands.add.args.member.name'),
|
||||
required: true
|
||||
},
|
||||
{
|
||||
description: i18n('commands.add.args.ticket.description'),
|
||||
example: i18n('commands.add.args.ticket.example'),
|
||||
name: i18n('commands.add.args.ticket.name'),
|
||||
required: false
|
||||
}
|
||||
],
|
||||
description: i18n('commands.add.description'),
|
||||
internal: true,
|
||||
name: i18n('commands.add.name'),
|
||||
process_args: false
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.add.options.member.description'),
|
||||
name: i18n('commands.add.options.member.name'),
|
||||
required: true,
|
||||
type: Command.option_types.USER
|
||||
},
|
||||
{
|
||||
description: i18n('commands.add.options.ticket.description'),
|
||||
name: i18n('commands.add.options.ticket.name'),
|
||||
required: false,
|
||||
type: Command.option_types.CHANNEL
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Message} message
|
||||
* @param {string} args
|
||||
* @param {Interaction} interaction
|
||||
* @returns {Promise<void|any>}
|
||||
*/
|
||||
async execute(message, args) {
|
||||
const settings = await this.client.utils.getSettings(message.guild);
|
||||
async execute(interaction) {
|
||||
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
||||
const default_i18n = this.client.i18n.getLocale(this.client.config.defaults.locale); // command properties could be in a different locale
|
||||
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);
|
||||
const channel = interaction.options.getChannel(default_i18n('commands.add.options.ticket.name')) ?? interaction.channel;
|
||||
const t_row = await this.client.tickets.resolve(channel.id, interaction.guild.id);
|
||||
|
||||
if (!t_row) {
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
const member = message.mentions.members.first() ?? message.guild.members.cache.get(args);
|
||||
const member = interaction.options.getMember(default_i18n('commands.add.options.member.name'));
|
||||
|
||||
if (!member) {
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
if (t_row.creator !== message.author.id && !await this.client.utils.isStaff(message.member)) {
|
||||
return await message.channel.send({
|
||||
if (t_row.creator !== interaction.member.id && !await this.client.utils.isStaff(interaction.member)) {
|
||||
return await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
if (message.channel.id !== ticket.id) {
|
||||
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 interaction.reply({
|
||||
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(), channel.toString()))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
|
||||
await ticket.send({
|
||||
await channel.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())
|
||||
.setDescription(i18n('ticket.member_added.description', member.toString(), interaction.user.toString()))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
]
|
||||
});
|
||||
|
||||
await ticket.permissionOverwrites.edit(member, {
|
||||
await channel.permissionOverwrites.edit(member, {
|
||||
ATTACH_FILES: true,
|
||||
READ_MESSAGE_HISTORY: true,
|
||||
SEND_MESSAGES: true,
|
||||
VIEW_CHANNEL: true
|
||||
}, `${message.author.tag} added ${member.user.tag} to the ticket`);
|
||||
}, `${interaction.user.tag} added ${member.user.tag} to the ticket`);
|
||||
|
||||
await this.client.tickets.archives.updateMember(ticket.id, member);
|
||||
await this.client.tickets.archives.updateMember(channel.id, member);
|
||||
|
||||
this.client.log.info(`${message.author.tag} added ${member.user.tag} to ${ticket.id}`);
|
||||
this.client.log.info(`${interaction.user.tag} added ${member.user.tag} to ${channel.id}`);
|
||||
}
|
||||
};
|
||||
|
@@ -1,125 +1,156 @@
|
||||
const Command = require('../modules/commands/command');
|
||||
const {
|
||||
Message, // eslint-disable-line no-unused-vars
|
||||
MessageEmbed
|
||||
Interaction, // eslint-disable-line no-unused-vars
|
||||
MessageEmbed,
|
||||
Role
|
||||
} = require('discord.js');
|
||||
|
||||
module.exports = class BlacklistCommand extends Command {
|
||||
constructor(client) {
|
||||
const i18n = client.i18n.getLocale(client.config.locale);
|
||||
super(client, {
|
||||
aliases: [
|
||||
i18n('commands.blacklist.aliases.unblacklist')
|
||||
],
|
||||
args: [
|
||||
{
|
||||
description: i18n('commands.blacklist.args.member_or_role.description'),
|
||||
example: i18n('commands.blacklist.args.member_or_role.example'),
|
||||
name: i18n('commands.blacklist.args.member_or_role.name'),
|
||||
required: false
|
||||
}
|
||||
],
|
||||
description: i18n('commands.blacklist.description'),
|
||||
internal: true,
|
||||
name: i18n('commands.blacklist.name'),
|
||||
permissions: ['MANAGE_GUILD'],
|
||||
process_args: false
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.blacklist.options.add.description'),
|
||||
name: i18n('commands.blacklist.options.add.name'),
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.blacklist.options.add.options.member_or_role.description'),
|
||||
name: i18n('commands.blacklist.options.add.options.member_or_role.name'),
|
||||
required: true,
|
||||
type: Command.option_types.MENTIONABLE
|
||||
}
|
||||
],
|
||||
type: Command.option_types.SUB_COMMAND
|
||||
},
|
||||
{
|
||||
description: i18n('commands.blacklist.options.remove.description'),
|
||||
name: i18n('commands.blacklist.options.remove.name'),
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.blacklist.options.remove.options.member_or_role.description'),
|
||||
name: i18n('commands.blacklist.options.remove.options.member_or_role.name'),
|
||||
required: true,
|
||||
type: Command.option_types.MENTIONABLE
|
||||
}
|
||||
],
|
||||
type: Command.option_types.SUB_COMMAND
|
||||
},
|
||||
{
|
||||
description: i18n('commands.blacklist.options.show.description'),
|
||||
name: i18n('commands.blacklist.options.show.name'),
|
||||
type: Command.option_types.SUB_COMMAND
|
||||
}
|
||||
],
|
||||
staff_only: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Message} message
|
||||
* @param {string} args
|
||||
* @param {Interaction} interaction
|
||||
* @returns {Promise<void|any>}
|
||||
*/
|
||||
async execute(message, args) {
|
||||
const settings = await this.client.utils.getSettings(message.guild);
|
||||
async execute(interaction) {
|
||||
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
||||
const default_i18n = this.client.i18n.getLocale(this.client.config.defaults.locale); // command properties could be in a different locale
|
||||
const i18n = this.client.i18n.getLocale(settings.locale);
|
||||
const blacklist = JSON.parse(JSON.stringify(settings.blacklist)); // not the same as `const blacklist = { ...settings.blacklist };` ..?
|
||||
|
||||
const member = message.mentions.members.first();
|
||||
switch (interaction.options.getSubcommand()) {
|
||||
case default_i18n('commands.blacklist.options.add.name'): {
|
||||
const member_or_role = interaction.options.getMentionable(default_i18n('commands.blacklist.options.add.options.member_or_role.name'));
|
||||
const type = member_or_role instanceof Role ? 'role' : 'member';
|
||||
|
||||
if (member && (await this.client.utils.isStaff(member) || member.permissions.has(this.permissions))) {
|
||||
return await message.channel.send({
|
||||
if (type === 'member' && await this.client.utils.isStaff(member_or_role)) {
|
||||
return await interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setTitle(i18n('commands.blacklist.response.illegal_action.title'))
|
||||
.setDescription(i18n('commands.blacklist.response.illegal_action.description', member_or_role.toString()))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
blacklist[type + 's'].push(member_or_role.id);
|
||||
await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setColor(settings.success_colour)
|
||||
.setTitle(i18n(`commands.blacklist.response.${type}_added.title`))
|
||||
.setDescription(i18n(`commands.blacklist.response.${type}_added.description`, member_or_role.id))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
await settings.update({ blacklist });
|
||||
break;
|
||||
}
|
||||
case default_i18n('commands.blacklist.options.remove.name'): {
|
||||
const member_or_role = interaction.options.getMentionable(default_i18n('commands.blacklist.options.remove.options.member_or_role.name'));
|
||||
const type = member_or_role instanceof Role ? 'role' : 'member';
|
||||
const index = blacklist[type + 's'].findIndex(element => element === member_or_role.id);
|
||||
|
||||
if (index === -1) {
|
||||
return await interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setTitle(i18n('commands.blacklist.response.invalid.title'))
|
||||
.setDescription(i18n('commands.blacklist.response.invalid.description'))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
const role = message.mentions.roles.first();
|
||||
let id;
|
||||
const input = args.trim().split(/\s/g)[0];
|
||||
|
||||
if (member) {
|
||||
id = member.id;
|
||||
} else if (role) {
|
||||
id = role.id;
|
||||
} else if (/\d{17,19}/.test(input)) {
|
||||
id = input;
|
||||
} else if (settings.blacklist.length === 0) {
|
||||
return await message.channel.send({
|
||||
blacklist[type + 's'].splice(index, 1);
|
||||
await interaction.reply({
|
||||
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 => {
|
||||
const is_role = message.guild.roles.cache.has(element);
|
||||
if (is_role) return `» <@&${element}> (\`${element}\`)`;
|
||||
else return `» <@${element}> (\`${element}\`)`;
|
||||
});
|
||||
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())
|
||||
]
|
||||
.setColor(settings.success_colour)
|
||||
.setTitle(i18n(`commands.blacklist.response.${type}_removed.title`))
|
||||
.setDescription(i18n(`commands.blacklist.response.${type}_removed.description`, member_or_role.id))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
await settings.update({ blacklist });
|
||||
break;
|
||||
}
|
||||
case default_i18n('commands.blacklist.options.show.name'): {
|
||||
if (blacklist.members.length === 0 && blacklist.roles.length === 0) {
|
||||
return await interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.colour)
|
||||
.setTitle(i18n('commands.blacklist.response.empty_list.title'))
|
||||
.setDescription(i18n('commands.blacklist.response.empty_list.description'))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
} else {
|
||||
const members = blacklist.members.map(id => `**·** <@${id}>`);
|
||||
const roles = blacklist.roles.map(id => `**·** <@&${id}>`);
|
||||
return await interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.colour)
|
||||
.setTitle(i18n('commands.blacklist.response.list.title'))
|
||||
.addField(i18n('commands.blacklist.response.list.fields.members'), members.join('\n') || 'none')
|
||||
.addField(i18n('commands.blacklist.response.list.fields.roles'), roles.join('\n') || 'none')
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const is_role = role !== undefined || message.guild.roles.cache.has(id);
|
||||
const member_or_role = is_role ? 'role' : 'member';
|
||||
const index = settings.blacklist.findIndex(element => element === id);
|
||||
|
||||
const new_blacklist = [...settings.blacklist];
|
||||
|
||||
if (index === -1) {
|
||||
new_blacklist.push(id);
|
||||
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({
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
@@ -1,260 +1,297 @@
|
||||
const Command = require('../modules/commands/command');
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {
|
||||
Message, // eslint-disable-line no-unused-vars
|
||||
MessageEmbed,
|
||||
MessageMentions
|
||||
Interaction, // eslint-disable-line no-unused-vars
|
||||
MessageActionRow,
|
||||
MessageButton,
|
||||
MessageEmbed
|
||||
} = require('discord.js');
|
||||
const { Op } = require('sequelize');
|
||||
const toTime = require('to-time-monthsfork');
|
||||
const ms = require('ms');
|
||||
|
||||
module.exports = class CloseCommand extends Command {
|
||||
constructor(client) {
|
||||
const i18n = client.i18n.getLocale(client.config.locale);
|
||||
super(client, {
|
||||
aliases: [
|
||||
i18n('commands.close.aliases.delete'),
|
||||
i18n('commands.close.aliases.lock')
|
||||
],
|
||||
args: [
|
||||
{
|
||||
alias: i18n('commands.close.args.ticket.alias'),
|
||||
description: i18n('commands.close.args.ticket.description'),
|
||||
example: i18n('commands.close.args.ticket.example'),
|
||||
name: i18n('commands.close.args.ticket.name'),
|
||||
required: false,
|
||||
type: String
|
||||
},
|
||||
{
|
||||
alias: i18n('commands.close.args.reason.alias'),
|
||||
description: i18n('commands.close.args.reason.description'),
|
||||
example: i18n('commands.close.args.reason.example'),
|
||||
name: i18n('commands.close.args.reason.name'),
|
||||
required: false,
|
||||
type: String
|
||||
},
|
||||
{
|
||||
alias: i18n('commands.close.args.time.alias'),
|
||||
description: i18n('commands.close.args.time.description'),
|
||||
example: i18n('commands.close.args.time.example'),
|
||||
name: i18n('commands.close.args.time.name'),
|
||||
required: false,
|
||||
type: String
|
||||
}
|
||||
],
|
||||
description: i18n('commands.close.description'),
|
||||
internal: true,
|
||||
name: i18n('commands.close.name'),
|
||||
process_args: true
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.close.options.reason.description'),
|
||||
name: i18n('commands.close.options.reason.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.close.options.ticket.description'),
|
||||
name: i18n('commands.close.options.ticket.name'),
|
||||
required: false,
|
||||
type: Command.option_types.INTEGER
|
||||
},
|
||||
{
|
||||
description: i18n('commands.close.options.time.description'),
|
||||
name: i18n('commands.close.options.time.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Message} message
|
||||
* @param {*} args
|
||||
* @param {Interaction} interaction
|
||||
* @returns {Promise<void|any>}
|
||||
*/
|
||||
async execute(message, args) {
|
||||
const arg_ticket = this.args[0].name;
|
||||
const arg_reason = this.args[1].name;
|
||||
const arg_time = this.args[2].name;
|
||||
|
||||
const settings = await this.client.utils.getSettings(message.guild);
|
||||
async execute(interaction) {
|
||||
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
||||
const default_i18n = this.client.i18n.getLocale(this.client.config.defaults.locale); // command properties could be in a different locale
|
||||
const i18n = this.client.i18n.getLocale(settings.locale);
|
||||
|
||||
if (args[arg_time]) {
|
||||
let period;
|
||||
const reason = interaction.options.getString(default_i18n('commands.close.options.reason.name'));
|
||||
const ticket = interaction.options.getInteger(default_i18n('commands.close.options.ticket.name'));
|
||||
const time = interaction.options.getString(default_i18n('commands.close.options.time.name'));
|
||||
|
||||
if (time) {
|
||||
let period;
|
||||
try {
|
||||
period = toTime(args[arg_time]).ms();
|
||||
period = ms(time);
|
||||
} catch {
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
const tickets = await this.client.db.models.Ticket.findAndCountAll({
|
||||
where: {
|
||||
guild: message.guild.id,
|
||||
last_message: { [Op.lte]: new Date(Date.now() - period) }
|
||||
guild: interaction.guild.id,
|
||||
last_message: { [Op.lte]: new Date(Date.now() - period) },
|
||||
open: true
|
||||
}
|
||||
});
|
||||
|
||||
if (tickets.count === 0) {
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
} else {
|
||||
const collector_message = await message.channel.send({
|
||||
await interaction.reply({
|
||||
components: [
|
||||
new MessageActionRow()
|
||||
.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId(`confirm_close_multiple:${interaction.id}`)
|
||||
.setLabel(i18n('commands.close.response.confirm_multiple.buttons.confirm', tickets.count, tickets.count))
|
||||
.setEmoji('✅')
|
||||
.setStyle('SUCCESS')
|
||||
)
|
||||
.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId(`cancel_close_multiple:${interaction.id}`)
|
||||
.setLabel(i18n('commands.close.response.confirm_multiple.buttons.cancel'))
|
||||
.setEmoji('❌')
|
||||
.setStyle('SECONDARY')
|
||||
)
|
||||
],
|
||||
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())
|
||||
]
|
||||
.setFooter(this.client.utils.footer(settings.footer, i18n('collector_expires_in', 30)), interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
|
||||
await collector_message.react('✅');
|
||||
|
||||
const filter = (reaction, user) => user.id === message.author.id && reaction.emoji.name === '✅';
|
||||
const collector = collector_message.createReactionCollector({
|
||||
const filter = i => i.user.id === interaction.user.id && i.customId.includes(interaction.id);
|
||||
const collector = interaction.channel.createMessageComponentCollector({
|
||||
filter,
|
||||
time: 30000
|
||||
});
|
||||
|
||||
collector.on('collect', async () => {
|
||||
await collector_message.reactions.removeAll();
|
||||
collector.on('collect', async i => {
|
||||
await i.deferUpdate();
|
||||
|
||||
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())
|
||||
]
|
||||
});
|
||||
if (i.customId === `confirm_close_multiple:${interaction.id}`) {
|
||||
for (const ticket of tickets.rows) {
|
||||
await this.client.tickets.close(ticket.id, interaction.user.id, interaction.guild.id, reason);
|
||||
}
|
||||
|
||||
for (const ticket of tickets.rows) {
|
||||
await this.client.tickets.close(ticket.id, message.author.id, message.guild.id, args[arg_reason]);
|
||||
await i.editReply({
|
||||
components: [],
|
||||
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, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
} else {
|
||||
await i.editReply({
|
||||
components: [],
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setTitle(i18n('commands.close.response.canceled.title'))
|
||||
.setDescription(i18n('commands.close.response.canceled.description'))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
collector.stop();
|
||||
});
|
||||
|
||||
collector.on('end', async collected => {
|
||||
if (collected.size === 0) {
|
||||
await collector_message.reactions.removeAll();
|
||||
await collector_message.edit({
|
||||
await interaction.editReply({
|
||||
components: [],
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setAuthor(message.author.username, message.author.displayAvatarURL())
|
||||
.setAuthor(interaction.user.username, interaction.user.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())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
setTimeout(async () => {
|
||||
await collector_message
|
||||
.delete()
|
||||
.catch(() => this.client.log.warn('Failed to delete response (collector) message'));
|
||||
await message
|
||||
.delete()
|
||||
.catch(() => this.client.log.warn('Failed to delete original message'));
|
||||
}, 15000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
let t_row;
|
||||
if (args[arg_ticket]) {
|
||||
args[arg_ticket] = args[arg_ticket].replace(MessageMentions.CHANNELS_PATTERN, '$1');
|
||||
t_row = await this.client.tickets.resolve(args[arg_ticket], message.guild.id);
|
||||
|
||||
let t_row;
|
||||
if (ticket) {
|
||||
t_row = await this.client.tickets.resolve(ticket, interaction.guild.id);
|
||||
if (!t_row) {
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setDescription(i18n('commands.close.response.unresolvable.description', ticket))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
} else {
|
||||
t_row = await this.client.db.models.Ticket.findOne({ where: { id: message.channel.id } });
|
||||
|
||||
t_row = await this.client.db.models.Ticket.findOne({ where: { id: interaction.channel.id } });
|
||||
if (!t_row) {
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setDescription(i18n('commands.close.response.not_a_ticket.description'))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const collector_message = await message.channel.send({
|
||||
await interaction.reply({
|
||||
components: [
|
||||
new MessageActionRow()
|
||||
.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId(`confirm_close:${interaction.id}`)
|
||||
.setLabel(i18n('commands.close.response.confirm.buttons.confirm'))
|
||||
.setEmoji('✅')
|
||||
.setStyle('SUCCESS')
|
||||
)
|
||||
.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId(`cancel_close:${interaction.id}`)
|
||||
.setLabel(i18n('commands.close.response.confirm.buttons.cancel'))
|
||||
.setEmoji('❌')
|
||||
.setStyle('SECONDARY')
|
||||
)
|
||||
],
|
||||
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())
|
||||
]
|
||||
.setDescription(settings.log_messages ? i18n('commands.close.response.confirm.description_with_archive') : i18n('commands.close.response.confirm.description'))
|
||||
.setFooter(this.client.utils.footer(settings.footer, i18n('collector_expires_in', 30)), interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
|
||||
await collector_message.react('✅');
|
||||
|
||||
const filter = (reaction, user) => user.id === message.author.id && reaction.emoji.name === '✅';
|
||||
const collector = collector_message.createReactionCollector({
|
||||
const filter = i => i.user.id === interaction.user.id && i.customId.includes(interaction.id);
|
||||
const collector = interaction.channel.createMessageComponentCollector({
|
||||
filter,
|
||||
time: 30000
|
||||
});
|
||||
|
||||
collector.on('collect', async () => {
|
||||
collector.stop();
|
||||
collector.on('collect', async i => {
|
||||
await i.deferUpdate();
|
||||
|
||||
if (message.channel.id === t_row.id) {
|
||||
await collector_message.delete();
|
||||
} else {
|
||||
await collector_message.reactions.removeAll();
|
||||
await collector_message.edit({
|
||||
if (i.customId === `confirm_close:${interaction.id}`) {
|
||||
await this.client.tickets.close(t_row.id, interaction.user.id, interaction.guild.id, reason);
|
||||
await i.editReply({
|
||||
components: [],
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.success_colour)
|
||||
.setTitle(i18n('commands.close.response.closed.title'))
|
||||
.setTitle(i18n('commands.close.response.closed.title', t_row.number))
|
||||
.setDescription(i18n('commands.close.response.closed.description', t_row.number))
|
||||
.setFooter(settings.footer, message.guild.iconURL())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
} else {
|
||||
await i.editReply({
|
||||
components: [],
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setTitle(i18n('commands.close.response.canceled.title'))
|
||||
.setDescription(i18n('commands.close.response.canceled.description'))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
await this.client.tickets.close(t_row.id, message.author.id, message.guild.id, args[arg_reason]);
|
||||
collector.stop();
|
||||
});
|
||||
|
||||
collector.on('end', async collected => {
|
||||
if (collected.size === 0) {
|
||||
await collector_message.reactions.removeAll();
|
||||
await collector_message.edit({
|
||||
await interaction.editReply({
|
||||
components: [],
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setAuthor(message.author.username, message.author.displayAvatarURL())
|
||||
.setAuthor(interaction.user.username, interaction.user.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())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
setTimeout(async () => {
|
||||
await collector_message
|
||||
.delete()
|
||||
.catch(() => this.client.log.warn('Failed to delete response (collector) message'));
|
||||
await message
|
||||
.delete()
|
||||
.catch(() => this.client.log.warn('Failed to delete original message'));
|
||||
}, 15000);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -1,113 +0,0 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"categories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"claiming": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"image": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"max_per_member": {
|
||||
"type": "number"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"name_format": {
|
||||
"type": "string"
|
||||
},
|
||||
"opening_message": {
|
||||
"type": "string"
|
||||
},
|
||||
"opening_questions": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"ping": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"require_topic": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"roles": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"survey": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"roles"
|
||||
]
|
||||
}
|
||||
},
|
||||
"colour": {
|
||||
"type": "string"
|
||||
},
|
||||
"command_prefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"error_colour": {
|
||||
"type": "string"
|
||||
},
|
||||
"footer": {
|
||||
"type": "string"
|
||||
},
|
||||
"locale": {
|
||||
"type": "string"
|
||||
},
|
||||
"log_messages": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"success_colour": {
|
||||
"type": "string"
|
||||
},
|
||||
"surveys": {
|
||||
"type": "object"
|
||||
},
|
||||
"tags": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"categories",
|
||||
"colour",
|
||||
"command_prefix",
|
||||
"error_colour",
|
||||
"footer",
|
||||
"locale",
|
||||
"log_messages",
|
||||
"success_colour",
|
||||
"surveys",
|
||||
"tags"
|
||||
]
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
const Command = require('../modules/commands/command');
|
||||
const {
|
||||
Message, // eslint-disable-line no-unused-vars
|
||||
Interaction, // eslint-disable-line no-unused-vars
|
||||
MessageEmbed
|
||||
} = require('discord.js');
|
||||
|
||||
@@ -8,61 +8,42 @@ module.exports = class HelpCommand extends Command {
|
||||
constructor(client) {
|
||||
const i18n = client.i18n.getLocale(client.config.locale);
|
||||
super(client, {
|
||||
aliases: [
|
||||
i18n('commands.help.aliases.command'),
|
||||
i18n('commands.help.aliases.commands')
|
||||
],
|
||||
args: [
|
||||
{
|
||||
description: i18n('commands.help.args.command.description'),
|
||||
example: i18n('commands.help.args.command.example'),
|
||||
name: i18n('commands.help.args.command.name'),
|
||||
required: false
|
||||
}
|
||||
],
|
||||
description: i18n('commands.help.description'),
|
||||
internal: true,
|
||||
name: i18n('commands.help.name'),
|
||||
process_args: false
|
||||
name: i18n('commands.help.name')
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Message} message
|
||||
* @param {string} args
|
||||
* @param {Interaction} interaction
|
||||
* @returns {Promise<void|any>}
|
||||
*/
|
||||
async execute(message, args) {
|
||||
const settings = await this.client.utils.getSettings(message.guild);
|
||||
async execute(interaction) {
|
||||
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
||||
const i18n = this.client.i18n.getLocale(settings.locale);
|
||||
|
||||
const cmd = this.manager.commands.find(command => command.aliases.includes(args.toLowerCase()));
|
||||
|
||||
if (cmd) {
|
||||
return await cmd.sendUsage(message.channel, args);
|
||||
} else {
|
||||
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.permissions.has(command.permissions);
|
||||
else if (command.staff_only) return is_staff;
|
||||
else return true;
|
||||
});
|
||||
const list = commands.map(command => {
|
||||
const description = command.description.length > 50
|
||||
? command.description.substring(0, 50) + '...'
|
||||
: command.description;
|
||||
return `**\`${settings.command_prefix}${command.name}\` ·** ${description}`;
|
||||
});
|
||||
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())
|
||||
]
|
||||
});
|
||||
}
|
||||
const is_staff = await this.client.utils.isStaff(interaction.member);
|
||||
const commands = this.manager.commands.filter(command => {
|
||||
if (command.permissions.length >= 1) return interaction.member.permissions.has(command.permissions);
|
||||
else if (command.staff_only) return is_staff;
|
||||
else return true;
|
||||
});
|
||||
const list = commands.map(command => {
|
||||
const description = command.description.length > 50
|
||||
? command.description.substring(0, 50) + '...'
|
||||
: command.description;
|
||||
return `**\`/${command.name}\` ·** ${description}`;
|
||||
});
|
||||
return await interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.colour)
|
||||
.setTitle(i18n('commands.help.response.list.title'))
|
||||
.setDescription(i18n('commands.help.response.list.description'))
|
||||
.addField(i18n('commands.help.response.list.fields.commands'), list.join('\n'))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@@ -1,72 +1,64 @@
|
||||
const Command = require('../modules/commands/command');
|
||||
const {
|
||||
Message, // eslint-disable-line no-unused-vars
|
||||
MessageEmbed
|
||||
Interaction, // eslint-disable-line no-unused-vars,
|
||||
MessageActionRow,
|
||||
MessageEmbed,
|
||||
MessageSelectMenu
|
||||
} = require('discord.js');
|
||||
const { letters } = require('../utils/emoji');
|
||||
const { wait } = require('../utils');
|
||||
|
||||
module.exports = class NewCommand extends Command {
|
||||
constructor(client) {
|
||||
const i18n = client.i18n.getLocale(client.config.locale);
|
||||
super(client, {
|
||||
aliases: [
|
||||
i18n('commands.new.aliases.create'),
|
||||
i18n('commands.new.aliases.open'),
|
||||
i18n('commands.new.aliases.ticket')
|
||||
],
|
||||
args: [
|
||||
{
|
||||
description: i18n('commands.new.args.topic.description'),
|
||||
example: i18n('commands.new.args.topic.example'),
|
||||
name: i18n('commands.new.args.topic.name'),
|
||||
required: false
|
||||
}
|
||||
],
|
||||
description: i18n('commands.new.description'),
|
||||
internal: true,
|
||||
name: i18n('commands.new.name'),
|
||||
process_args: false
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.new.options.topic.description'),
|
||||
name: i18n('commands.new.options.topic.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Message} message
|
||||
* @param {string} args
|
||||
* @param {Interaction} interaction
|
||||
* @returns {Promise<void|any>}
|
||||
*/
|
||||
async execute(message, args) {
|
||||
const settings = await this.client.utils.getSettings(message.guild);
|
||||
async execute(interaction) {
|
||||
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
||||
const default_i18n = this.client.i18n.getLocale(this.client.config.defaults.locale); // command properties could be in a different locale
|
||||
const i18n = this.client.i18n.getLocale(settings.locale);
|
||||
|
||||
const editOrSend = async (msg, content) => {
|
||||
if (msg) return await msg.edit(content);
|
||||
else return await message.channel.send(content);
|
||||
};
|
||||
const topic = interaction.options.getString(default_i18n('commands.new.options.topic.name'));
|
||||
|
||||
const create = async (cat_row, response) => {
|
||||
const create = async (cat_row, i) => {
|
||||
const tickets = await this.client.db.models.Ticket.findAndCountAll({
|
||||
where: {
|
||||
category: cat_row.id,
|
||||
creator: message.author.id,
|
||||
creator: interaction.user.id,
|
||||
open: true
|
||||
}
|
||||
});
|
||||
|
||||
if (tickets.count >= cat_row.max_per_member) {
|
||||
if (cat_row.max_per_member === 1) {
|
||||
response = await editOrSend(response,
|
||||
{
|
||||
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())
|
||||
]
|
||||
}
|
||||
);
|
||||
const response = {
|
||||
components: [],
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setAuthor(interaction.user.username, interaction.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(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
};
|
||||
await i ? i.editReply(response) : interaction.reply(response);
|
||||
} else {
|
||||
const list = tickets.rows.map(row => {
|
||||
if (row.topic) {
|
||||
@@ -77,136 +69,120 @@ module.exports = class NewCommand extends Command {
|
||||
return `<#${row.id}>`;
|
||||
}
|
||||
});
|
||||
response = await editOrSend(response,
|
||||
{
|
||||
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())
|
||||
]
|
||||
}
|
||||
);
|
||||
const response = {
|
||||
components: [],
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setAuthor(interaction.user.username, interaction.user.displayAvatarURL())
|
||||
.setTitle(i18n('commands.new.response.max_tickets.title', tickets.count))
|
||||
.setDescription(i18n('commands.new.response.max_tickets.description', list.join('\n')))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
};
|
||||
await i ? i.editReply(response) : interaction.reply(response);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
const t_row = await this.client.tickets.create(message.guild.id, message.author.id, cat_row.id, args);
|
||||
response = await editOrSend(response,
|
||||
{
|
||||
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())
|
||||
]
|
||||
}
|
||||
);
|
||||
const t_row = await this.client.tickets.create(interaction.guild.id, interaction.user.id, cat_row.id, topic);
|
||||
const response = {
|
||||
components: [],
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.success_colour)
|
||||
.setAuthor(interaction.user.username, interaction.user.displayAvatarURL())
|
||||
.setTitle(i18n('commands.new.response.created.title'))
|
||||
.setDescription(i18n('commands.new.response.created.description', `<#${t_row.id}>`))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
};
|
||||
await i ? i.editReply(response) : interaction.reply(response);
|
||||
} catch (error) {
|
||||
response = await editOrSend(response,
|
||||
{
|
||||
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())
|
||||
]
|
||||
}
|
||||
);
|
||||
const response = {
|
||||
components: [],
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setAuthor(interaction.user.username, interaction.user.displayAvatarURL())
|
||||
.setTitle(i18n('commands.new.response.error.title'))
|
||||
.setDescription(error.message)
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
};
|
||||
await i ? i.editReply(response) : interaction.reply(response);
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(async () => {
|
||||
await response
|
||||
.delete()
|
||||
.catch(() => this.client.log.warn('Failed to delete response message'));
|
||||
await message
|
||||
.delete()
|
||||
.catch(() => this.client.log.warn('Failed to delete original message'));
|
||||
}, 15000);
|
||||
};
|
||||
|
||||
const categories = await this.client.db.models.Category.findAndCountAll({ where: { guild: message.guild.id } });
|
||||
const categories = await this.client.db.models.Category.findAndCountAll({ where: { guild: interaction.guild.id } });
|
||||
|
||||
if (categories.count === 0) {
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setAuthor(message.author.username, message.author.displayAvatarURL())
|
||||
.setAuthor(interaction.user.username, interaction.user.displayAvatarURL())
|
||||
.setTitle(i18n('commands.new.response.no_categories.title'))
|
||||
.setDescription(i18n('commands.new.response.no_categories.description'))
|
||||
.setFooter(settings.footer, message.guild.iconURL())
|
||||
.setFooter(settings.footer, interaction.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({
|
||||
await interaction.reply({
|
||||
components: [
|
||||
new MessageActionRow()
|
||||
.addComponents(
|
||||
new MessageSelectMenu()
|
||||
.setCustomId(`select_category:${interaction.id}`)
|
||||
.setPlaceholder('Select a category')
|
||||
.addOptions(categories.rows.map(row => ({
|
||||
label: row.name,
|
||||
value: row.id
|
||||
})))
|
||||
)
|
||||
],
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.colour)
|
||||
.setAuthor(message.author.username, message.author.displayAvatarURL())
|
||||
.setAuthor(interaction.user.username, interaction.user.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())
|
||||
]
|
||||
.setDescription(i18n('commands.new.response.select_category.description'))
|
||||
.setFooter(this.client.utils.footer(settings.footer, i18n('collector_expires_in', 30)), interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
|
||||
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 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({
|
||||
const filter = i => i.user.id === interaction.user.id && i.customId.includes(interaction.id);
|
||||
const collector = interaction.channel.createMessageComponentCollector({
|
||||
filter,
|
||||
time: 30000
|
||||
});
|
||||
|
||||
collector.on('collect', async reaction => {
|
||||
collector.on('collect', async i => {
|
||||
await i.deferUpdate();
|
||||
create(categories.rows.find(row => row.id === i.values[0]), i);
|
||||
collector.stop();
|
||||
const index = letters_array.findIndex(value => value === reaction.emoji.name); // find where the letter is in the alphabet
|
||||
if (index === -1) {
|
||||
return setTimeout(async () => {
|
||||
await collector_message.delete();
|
||||
}, 15000);
|
||||
}
|
||||
await collector_message.reactions.removeAll();
|
||||
create(categories.rows[index], collector_message); // create the ticket, passing the existing response message to be edited instead of creating a new one
|
||||
});
|
||||
|
||||
collector.on('end', async collected => {
|
||||
if (collected.size === 0) {
|
||||
await collector_message.reactions.removeAll();
|
||||
await collector_message.edit({
|
||||
await interaction.editReply({
|
||||
components: [],
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setAuthor(message.author.username, message.author.displayAvatarURL())
|
||||
.setAuthor(interaction.user.username, interaction.user.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())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
setTimeout(async () => {
|
||||
await collector_message
|
||||
.delete()
|
||||
.catch(() => this.client.log.warn('Failed to delete response (collector) message'));
|
||||
await message
|
||||
.delete()
|
||||
.catch(() => this.client.log.warn('Failed to delete original message'));
|
||||
}, 15000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -1,85 +1,98 @@
|
||||
const Command = require('../modules/commands/command');
|
||||
const {
|
||||
Message, // eslint-disable-line no-unused-vars
|
||||
MessageEmbed
|
||||
Interaction, // eslint-disable-line no-unused-vars
|
||||
MessageActionRow,
|
||||
MessageButton,
|
||||
MessageEmbed,
|
||||
MessageSelectMenu
|
||||
} = require('discord.js');
|
||||
const {
|
||||
some, wait
|
||||
} = require('../utils');
|
||||
const { emojify } = require('node-emoji');
|
||||
const { some } = require('../utils');
|
||||
|
||||
module.exports = class PanelCommand extends Command {
|
||||
constructor(client) {
|
||||
const i18n = client.i18n.getLocale(client.config.locale);
|
||||
super(client, {
|
||||
aliases: [],
|
||||
args: [
|
||||
{
|
||||
alias: i18n('commands.panel.args.title.alias'),
|
||||
description: i18n('commands.panel.args.title.description'),
|
||||
example: i18n('commands.panel.args.title.example'),
|
||||
name: i18n('commands.panel.args.title.name'),
|
||||
required: false,
|
||||
type: String
|
||||
},
|
||||
{
|
||||
alias: i18n('commands.panel.args.description.alias'),
|
||||
description: i18n('commands.panel.args.description.description'),
|
||||
example: i18n('commands.panel.args.description.example'),
|
||||
name: i18n('commands.panel.args.description.name'),
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
{
|
||||
alias: i18n('commands.panel.args.emoji.alias'),
|
||||
description: i18n('commands.panel.args.emoji.description'),
|
||||
example: i18n('commands.panel.args.emoji.example'),
|
||||
multiple: true,
|
||||
name: i18n('commands.panel.args.emoji.name'),
|
||||
required: false,
|
||||
type: String
|
||||
},
|
||||
{
|
||||
alias: i18n('commands.panel.args.categories.alias'),
|
||||
description: i18n('commands.panel.args.categories.description'),
|
||||
example: i18n('commands.panel.args.categories.example'),
|
||||
multiple: true,
|
||||
name: i18n('commands.panel.args.categories.name'),
|
||||
required: true,
|
||||
type: String
|
||||
}
|
||||
],
|
||||
description: i18n('commands.panel.description'),
|
||||
internal: true,
|
||||
name: i18n('commands.panel.name'),
|
||||
permissions: ['MANAGE_GUILD'],
|
||||
process_args: true
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.panel.options.categories.description'),
|
||||
multiple: true,
|
||||
name: i18n('commands.panel.options.categories.name'),
|
||||
required: true,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.panel.options.description.description'),
|
||||
name: i18n('commands.panel.options.description.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.panel.options.image.description'),
|
||||
name: i18n('commands.panel.options.image.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.panel.options.just_type.description') + ' (false)',
|
||||
name: i18n('commands.panel.options.just_type.name'),
|
||||
required: false,
|
||||
type: Command.option_types.BOOLEAN
|
||||
},
|
||||
{
|
||||
description: i18n('commands.panel.options.title.description'),
|
||||
name: i18n('commands.panel.options.title.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.panel.options.thumbnail.description'),
|
||||
name: i18n('commands.panel.options.thumbnail.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
}
|
||||
],
|
||||
staff_only: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Message} message
|
||||
* @param {*} args
|
||||
* @param {Interaction} interaction
|
||||
* @returns {Promise<void|any>}
|
||||
*/
|
||||
async execute(message, args) {
|
||||
// localised command and arg names are a pain
|
||||
const arg_title = this.args[0].name;
|
||||
const arg_description = this.args[1].name;
|
||||
const arg_emoji = this.args[2].name;
|
||||
const arg_categories = this.args[3].name;
|
||||
|
||||
const settings = await this.client.utils.getSettings(message.guild);
|
||||
async execute(interaction) {
|
||||
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
||||
const default_i18n = this.client.i18n.getLocale(this.client.config.defaults.locale); // command properties could be in a different locale
|
||||
const i18n = this.client.i18n.getLocale(settings.locale);
|
||||
|
||||
if (!args[arg_emoji]) args[arg_emoji] = [];
|
||||
const categories = interaction.options.getString(default_i18n('commands.panel.options.categories.name'))
|
||||
.replace(/\s/g, '')
|
||||
.split(',');
|
||||
const description = interaction.options.getString(default_i18n('commands.panel.options.description.name'));
|
||||
const image = interaction.options.getString(default_i18n('commands.panel.options.image.name'));
|
||||
const just_type = interaction.options.getBoolean(default_i18n('commands.panel.options.just_type.name'));
|
||||
const title = interaction.options.getString(default_i18n('commands.panel.options.title.name'));
|
||||
const thumbnail = interaction.options.getString(default_i18n('commands.panel.options.thumbnail.name'));
|
||||
|
||||
args[arg_emoji] = args[arg_emoji].map(emoji => emojify(emoji.replace(/\\/g, '')));
|
||||
if (just_type && categories.length > 1) {
|
||||
return await interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setTitle(i18n('commands.panel.response.too_many_categories.title'))
|
||||
.setDescription(i18n('commands.panel.response.too_many_categories.description'))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
const invalid_category = await some(args[arg_categories], async id => {
|
||||
const invalid_category = await some(categories, async id => {
|
||||
const cat_row = await this.client.db.models.Category.findOne({
|
||||
where: {
|
||||
guild: message.guild.id,
|
||||
guild: interaction.guild.id,
|
||||
id
|
||||
}
|
||||
});
|
||||
@@ -87,36 +100,36 @@ module.exports = class PanelCommand extends Command {
|
||||
});
|
||||
|
||||
if (invalid_category) {
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
let panel_channel,
|
||||
panel_message;
|
||||
|
||||
let categories_map = args[arg_categories][0];
|
||||
let panel_channel;
|
||||
|
||||
const embed = new MessageEmbed()
|
||||
.setColor(settings.colour)
|
||||
.setFooter(settings.footer, message.guild.iconURL());
|
||||
.setFooter(settings.footer, interaction.guild.iconURL());
|
||||
|
||||
if (args[arg_title]) embed.setTitle(args[arg_title]);
|
||||
if (description) embed.setDescription(description);
|
||||
if (image) embed.setImage(image);
|
||||
if (title) embed.setTitle(title);
|
||||
if (thumbnail) embed.setThumbnail(thumbnail);
|
||||
|
||||
if (args[arg_emoji].length === 0) {
|
||||
// reaction-less panel
|
||||
panel_channel = await message.guild.channels.create('create-a-ticket', {
|
||||
if (just_type) {
|
||||
panel_channel = await interaction.guild.channels.create('create-a-ticket', {
|
||||
permissionOverwrites: [
|
||||
{
|
||||
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'],
|
||||
deny: ['ATTACH_FILES', 'EMBED_LINKS', 'ADD_REACTIONS'],
|
||||
id: message.guild.roles.everyone
|
||||
id: interaction.guild.roles.everyone
|
||||
},
|
||||
{
|
||||
allow: ['SEND_MESSAGES', 'EMBED_LINKS', 'ADD_REACTIONS'],
|
||||
@@ -125,92 +138,75 @@ module.exports = class PanelCommand extends Command {
|
||||
],
|
||||
position: 1,
|
||||
rateLimitPerUser: 30,
|
||||
reason: `${message.author.tag} created a new reaction-less panel`,
|
||||
reason: `${interaction.user.tag} created a new message panel`,
|
||||
type: 'GUILD_TEXT'
|
||||
});
|
||||
await panel_channel.send({ embeds: [embed] });
|
||||
this.client.log.info(`${interaction.user.tag} has created a new message panel`);
|
||||
} else {
|
||||
panel_channel = await interaction.guild.channels.create('create-a-ticket', {
|
||||
permissionOverwrites: [
|
||||
{
|
||||
allow: ['VIEW_CHANNEL', 'READ_MESSAGE_HISTORY'],
|
||||
deny: ['SEND_MESSAGES', 'ADD_REACTIONS'],
|
||||
id: interaction.guild.roles.everyone
|
||||
},
|
||||
{
|
||||
allow: ['SEND_MESSAGES', 'EMBED_LINKS', 'ADD_REACTIONS'],
|
||||
id: this.client.user.id
|
||||
}
|
||||
],
|
||||
position: 1,
|
||||
reason: `${interaction.user.tag} created a new panel`,
|
||||
type: 'GUILD_TEXT'
|
||||
});
|
||||
|
||||
embed.setDescription(args[arg_description]);
|
||||
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({
|
||||
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: [
|
||||
{
|
||||
allow: ['VIEW_CHANNEL', 'READ_MESSAGE_HISTORY'],
|
||||
deny: ['SEND_MESSAGES', 'ADD_REACTIONS'],
|
||||
id: message.guild.roles.everyone
|
||||
},
|
||||
{
|
||||
allow: ['SEND_MESSAGES', 'EMBED_LINKS', 'ADD_REACTIONS'],
|
||||
id: this.client.user.id
|
||||
}
|
||||
if (categories.length === 1) {
|
||||
// single category
|
||||
await panel_channel.send({
|
||||
components: [
|
||||
new MessageActionRow()
|
||||
.addComponents(
|
||||
new MessageButton()
|
||||
.setCustomId(`panel.single:${categories[0]}`)
|
||||
.setLabel(i18n('panel.create_ticket'))
|
||||
.setStyle('PRIMARY')
|
||||
)
|
||||
],
|
||||
position: 1,
|
||||
reason: `${message.author.tag} created a new panel`,
|
||||
type: 'GUILD_TEXT'
|
||||
embeds: [embed]
|
||||
});
|
||||
|
||||
if (args[arg_emoji].length === 1) {
|
||||
// single category
|
||||
categories_map = {};
|
||||
categories_map[args[arg_emoji][0]] = args[arg_categories][0];
|
||||
embed.setDescription(args[arg_description]);
|
||||
panel_message = await panel_channel.send({ embeds: [embed] });
|
||||
await panel_message.react(args[arg_emoji][0]);
|
||||
} else {
|
||||
// multi category
|
||||
let description = '';
|
||||
categories_map = {};
|
||||
|
||||
for (const i in args[arg_emoji]) {
|
||||
categories_map[args[arg_emoji][i]] = args[arg_categories][i];
|
||||
const cat_row = await this.client.db.models.Category.findOne({
|
||||
where: {
|
||||
guild: message.guild.id,
|
||||
id: args[arg_categories][i]
|
||||
}
|
||||
});
|
||||
description += `\n> ${args[arg_emoji][i]} | ${cat_row.name}`;
|
||||
}
|
||||
|
||||
embed.setDescription(args[arg_description] + '\n' + description);
|
||||
panel_message = await panel_channel.send({
|
||||
embeds: [
|
||||
embed
|
||||
]
|
||||
});
|
||||
|
||||
for (const emoji of args[arg_emoji]) {
|
||||
await panel_message.react(emoji);
|
||||
await wait(1000); // 1 reaction per second rate-limit
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.client.log.info(`${message.author.tag} has created a new panel`);
|
||||
this.client.log.info(`${interaction.user.tag} has created a new button panel`);
|
||||
} else {
|
||||
// multi category
|
||||
const rows = await this.client.db.models.Category.findAll({ where: { guild: interaction.guild.id } });
|
||||
await panel_channel.send({
|
||||
components: [
|
||||
new MessageActionRow()
|
||||
.addComponents(
|
||||
new MessageSelectMenu()
|
||||
.setCustomId(`panel.multiple:${panel_channel.id}`)
|
||||
.setPlaceholder('Select a category')
|
||||
.addOptions(rows.map(row => ({
|
||||
label: row.name,
|
||||
value: row.id
|
||||
})))
|
||||
)
|
||||
],
|
||||
embeds: [embed]
|
||||
});
|
||||
this.client.log.info(`${interaction.user.tag} has created a new select panel`);
|
||||
}
|
||||
}
|
||||
|
||||
message.channel.send({ content: `✅ ${panel_channel}` });
|
||||
interaction.reply({
|
||||
content: `✅ ${panel_channel}`,
|
||||
ephemeral: true
|
||||
});
|
||||
|
||||
await this.client.db.models.Panel.create({
|
||||
categories: categories_map,
|
||||
category: categories.length === 1 ? categories[0] : null,
|
||||
channel: panel_channel.id,
|
||||
guild: message.guild.id,
|
||||
message: panel_message.id
|
||||
guild: interaction.guild.id
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@@ -1,6 +1,6 @@
|
||||
const Command = require('../modules/commands/command');
|
||||
const {
|
||||
Message, // eslint-disable-line no-unused-vars
|
||||
Interaction, // eslint-disable-line no-unused-vars
|
||||
MessageEmbed
|
||||
} = require('discord.js');
|
||||
|
||||
@@ -8,106 +8,104 @@ module.exports = class RemoveCommand extends Command {
|
||||
constructor(client) {
|
||||
const i18n = client.i18n.getLocale(client.config.locale);
|
||||
super(client, {
|
||||
aliases: [],
|
||||
args: [
|
||||
{
|
||||
description: i18n('commands.remove.args.member.description'),
|
||||
example: i18n('commands.remove.args.member.example'),
|
||||
name: i18n('commands.remove.args.member.name'),
|
||||
required: true
|
||||
},
|
||||
{
|
||||
description: i18n('commands.remove.args.ticket.description'),
|
||||
example: i18n('commands.remove.args.ticket.example'),
|
||||
name: i18n('commands.remove.args.ticket.name'),
|
||||
required: false
|
||||
}
|
||||
],
|
||||
description: i18n('commands.remove.description'),
|
||||
internal: true,
|
||||
name: i18n('commands.remove.name'),
|
||||
process_args: false
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.remove.options.member.description'),
|
||||
name: i18n('commands.remove.options.member.name'),
|
||||
required: true,
|
||||
type: Command.option_types.USER
|
||||
},
|
||||
{
|
||||
description: i18n('commands.remove.options.ticket.description'),
|
||||
name: i18n('commands.remove.options.ticket.name'),
|
||||
required: false,
|
||||
type: Command.option_types.CHANNEL
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Message} message
|
||||
* @param {string} args
|
||||
* @param {Interaction} interaction
|
||||
* @returns {Promise<void|any>}
|
||||
*/
|
||||
async execute(message, args) {
|
||||
const settings = await this.client.utils.getSettings(message.guild);
|
||||
async execute(interaction) {
|
||||
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
||||
const default_i18n = this.client.i18n.getLocale(this.client.config.defaults.locale); // command properties could be in a different locale
|
||||
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);
|
||||
const channel = interaction.options.getChannel(default_i18n('commands.remove.options.channel.name')) ?? interaction.channel;
|
||||
const t_row = await this.client.tickets.resolve(channel.id, interaction.guild.id);
|
||||
|
||||
if (!t_row) {
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setTitle(i18n('commands.remove.response.not_a_channel.title'))
|
||||
.setDescription(i18n('commands.remove.response.not_a_channel.description'))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
const member = message.mentions.members.first() ?? message.guild.members.cache.get(args);
|
||||
const member = interaction.options.getMember(default_i18n('commands.remove.options.member.name'));
|
||||
|
||||
if (!member) {
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
if (t_row.creator !== message.author.id && !await this.client.utils.isStaff(message.member)) {
|
||||
return await message.channel.send({
|
||||
if (t_row.creator !== interaction.user.id && !await this.client.utils.isStaff(interaction.member)) {
|
||||
return await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
if (message.channel.id !== ticket.id) {
|
||||
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 interaction.reply({
|
||||
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(), channel.toString()))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
|
||||
await ticket.send({
|
||||
await channel.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())
|
||||
.setDescription(i18n('ticket.member_removed.description', member.toString(), interaction.user.toString()))
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
]
|
||||
});
|
||||
|
||||
await ticket.permissionOverwrites
|
||||
.get(member.user.id)
|
||||
?.delete(`${message.author.tag} removed ${member.user.tag} from the ticket`);
|
||||
await channel.permissionOverwrites.delete(member.user.id, `${interaction.user.tag} removed ${member.user.tag} from the ticket`);
|
||||
|
||||
this.client.log.info(`${message.author.tag} removed ${member.user.tag} from ${ticket.id}`);
|
||||
this.client.log.info(`${interaction.user.tag} removed ${member.user.tag} from ${channel.id}`);
|
||||
}
|
||||
};
|
||||
|
@@ -1,201 +1,350 @@
|
||||
/* eslint-disable max-lines */
|
||||
const Command = require('../modules/commands/command');
|
||||
const fetch = require('node-fetch');
|
||||
const {
|
||||
Message, // eslint-disable-line no-unused-vars
|
||||
MessageAttachment
|
||||
Interaction, // eslint-disable-line no-unused-vars
|
||||
MessageEmbed
|
||||
} = require('discord.js');
|
||||
const { Validator } = require('jsonschema');
|
||||
|
||||
module.exports = class SettingsCommand extends Command {
|
||||
constructor(client) {
|
||||
const i18n = client.i18n.getLocale(client.config.locale);
|
||||
super(client, {
|
||||
aliases: [
|
||||
i18n('commands.settings.aliases.config')
|
||||
],
|
||||
args: [],
|
||||
description: i18n('commands.settings.description'),
|
||||
internal: true,
|
||||
name: i18n('commands.settings.name'),
|
||||
permissions: ['MANAGE_GUILD'],
|
||||
process_args: false
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.description'),
|
||||
name: i18n('commands.settings.options.categories.name'),
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.create.description'),
|
||||
name: i18n('commands.settings.options.categories.options.create.name'),
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.create.options.name.description'),
|
||||
name: i18n('commands.settings.options.categories.options.create.options.name.name'),
|
||||
required: true,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.create.options.roles.description'),
|
||||
name: i18n('commands.settings.options.categories.options.create.options.roles.name'),
|
||||
required: true,
|
||||
type: Command.option_types.STRING
|
||||
}
|
||||
],
|
||||
type: Command.option_types.SUB_COMMAND
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.delete.description'),
|
||||
name: i18n('commands.settings.options.categories.options.delete.name'),
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.delete.options.id.description'),
|
||||
name: i18n('commands.settings.options.categories.options.delete.options.id.name'),
|
||||
required: true,
|
||||
type: Command.option_types.STRING
|
||||
}
|
||||
],
|
||||
type: Command.option_types.SUB_COMMAND
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.edit.description'),
|
||||
name: i18n('commands.settings.options.categories.options.edit.name'),
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.edit.options.id.description'),
|
||||
name: i18n('commands.settings.options.categories.options.edit.options.id.name'),
|
||||
required: true,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.edit.options.claiming.description'),
|
||||
name: i18n('commands.settings.options.categories.options.edit.options.claiming.name'),
|
||||
required: false,
|
||||
type: Command.option_types.BOOLEAN
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.edit.options.image.description'),
|
||||
name: i18n('commands.settings.options.categories.options.edit.options.image.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.edit.options.max_per_member.description'),
|
||||
name: i18n('commands.settings.options.categories.options.edit.options.max_per_member.name'),
|
||||
required: false,
|
||||
type: Command.option_types.INTEGER
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.edit.options.name.description'),
|
||||
name: i18n('commands.settings.options.categories.options.edit.options.name.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.edit.options.name_format.description'),
|
||||
name: i18n('commands.settings.options.categories.options.edit.options.name_format.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.edit.options.opening_message.description'),
|
||||
name: i18n('commands.settings.options.categories.options.edit.options.opening_message.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.edit.options.ping.description'),
|
||||
name: i18n('commands.settings.options.categories.options.edit.options.ping.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.edit.options.require_topic.description'),
|
||||
name: i18n('commands.settings.options.categories.options.edit.options.require_topic.name'),
|
||||
required: false,
|
||||
type: Command.option_types.BOOLEAN
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.edit.options.roles.description'),
|
||||
name: i18n('commands.settings.options.categories.options.edit.options.roles.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.edit.options.survey.description'),
|
||||
name: i18n('commands.settings.options.categories.options.edit.options.survey.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
}
|
||||
],
|
||||
type: Command.option_types.SUB_COMMAND
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.categories.options.list.description'),
|
||||
name: i18n('commands.settings.options.categories.options.list.name'),
|
||||
type: Command.option_types.SUB_COMMAND
|
||||
}
|
||||
],
|
||||
type: Command.option_types.SUB_COMMAND_GROUP
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.set.description'),
|
||||
name: i18n('commands.settings.options.set.name'),
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.settings.options.set.options.close_button.description'),
|
||||
name: i18n('commands.settings.options.set.options.close_button.name'),
|
||||
required: false,
|
||||
type: Command.option_types.BOOLEAN
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.set.options.colour.description'),
|
||||
name: i18n('commands.settings.options.set.options.colour.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.set.options.error_colour.description'),
|
||||
name: i18n('commands.settings.options.set.options.error_colour.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.set.options.footer.description'),
|
||||
name: i18n('commands.settings.options.set.options.footer.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.set.options.locale.description'),
|
||||
name: i18n('commands.settings.options.set.options.locale.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.set.options.log_messages.description'),
|
||||
name: i18n('commands.settings.options.set.options.log_messages.name'),
|
||||
required: false,
|
||||
type: Command.option_types.BOOLEAN
|
||||
},
|
||||
{
|
||||
description: i18n('commands.settings.options.set.options.success_colour.description'),
|
||||
name: i18n('commands.settings.options.set.options.success_colour.name'),
|
||||
required: false,
|
||||
type: Command.option_types.STRING
|
||||
}
|
||||
],
|
||||
type: Command.option_types.SUB_COMMAND
|
||||
}
|
||||
],
|
||||
permissions: ['MANAGE_GUILD']
|
||||
});
|
||||
|
||||
this.schema = require('./extra/settings.schema.json');
|
||||
this.v = new Validator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Message} message
|
||||
* @param {string} args
|
||||
* @param {Interaction} interaction
|
||||
* @returns {Promise<void|any>}
|
||||
*/
|
||||
async execute(message) {
|
||||
const settings = await this.client.utils.getSettings(message.guild);
|
||||
async execute(interaction) {
|
||||
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
||||
const default_i18n = this.client.i18n.getLocale(this.client.config.defaults.locale); // command properties could be in a different locale
|
||||
const i18n = this.client.i18n.getLocale(settings.locale);
|
||||
|
||||
const attachments = [...message.attachments.values()];
|
||||
|
||||
if (attachments.length >= 1) {
|
||||
|
||||
// load settings from json
|
||||
this.client.log.info(`Downloading settings for "${message.guild.name}"`);
|
||||
const data = await (await fetch(attachments[0].url)).json();
|
||||
|
||||
const {
|
||||
valid, errors
|
||||
} = this.v.validate(data, this.schema);
|
||||
|
||||
if (!valid) {
|
||||
this.client.log.warn('Settings validation error');
|
||||
return await message.channel.send({ content: i18n('commands.settings.response.invalid', errors.map(error => `\`${error.stack}\``).join(',\n')) });
|
||||
}
|
||||
|
||||
settings.colour = data.colour;
|
||||
settings.command_prefix = data.command_prefix;
|
||||
settings.error_colour = data.error_colour;
|
||||
settings.footer = data.footer;
|
||||
settings.locale = data.locale;
|
||||
settings.log_messages = data.log_messages;
|
||||
settings.success_colour = data.success_colour;
|
||||
settings.tags = data.tags;
|
||||
await settings.save();
|
||||
|
||||
for (const c of data.categories) {
|
||||
if (c.id) {
|
||||
// existing category
|
||||
const cat_row = await this.client.db.models.Category.findOne({ where: { id: c.id } });
|
||||
cat_row.claiming = c.claiming;
|
||||
cat_row.image = c.image;
|
||||
cat_row.max_per_member = c.max_per_member;
|
||||
cat_row.name = c.name;
|
||||
cat_row.name_format = c.name_format;
|
||||
cat_row.opening_message = c.opening_message;
|
||||
cat_row.opening_questions = c.opening_questions;
|
||||
cat_row.ping = c.ping;
|
||||
cat_row.require_topic = c.require_topic;
|
||||
cat_row.roles = c.roles;
|
||||
cat_row.survey = c.survey;
|
||||
cat_row.save();
|
||||
|
||||
const cat_channel = await this.client.channels.fetch(c.id);
|
||||
|
||||
if (cat_channel) {
|
||||
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.permissionOverwrites.edit(r, {
|
||||
ATTACH_FILES: true,
|
||||
READ_MESSAGE_HISTORY: true,
|
||||
SEND_MESSAGES: true,
|
||||
VIEW_CHANNEL: true
|
||||
}, `Tickets category updated by ${message.author.tag}`);
|
||||
switch (interaction.options.getSubcommand()) {
|
||||
case default_i18n('commands.settings.options.categories.options.create.name'): {
|
||||
const name = interaction.options.getString(default_i18n('commands.settings.options.categories.options.create.options.name.name'));
|
||||
const roles = interaction.options.getString(default_i18n('commands.settings.options.categories.options.create.options.roles.name'))?.replace(/\s/g, '').split(',');
|
||||
const allowed_permissions = ['VIEW_CHANNEL', 'READ_MESSAGE_HISTORY', 'SEND_MESSAGES', 'EMBED_LINKS', 'ATTACH_FILES'];
|
||||
const cat_channel = await interaction.guild.channels.create(name, {
|
||||
permissionOverwrites: [
|
||||
...[
|
||||
{
|
||||
deny: ['VIEW_CHANNEL'],
|
||||
id: interaction.guild.roles.everyone
|
||||
},
|
||||
{
|
||||
allow: allowed_permissions,
|
||||
id: this.client.user.id
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// create a new category
|
||||
const allowed_permissions = ['VIEW_CHANNEL', 'READ_MESSAGE_HISTORY', 'SEND_MESSAGES', 'EMBED_LINKS', 'ATTACH_FILES'];
|
||||
const cat_channel = await message.guild.channels.create(c.name, {
|
||||
permissionOverwrites: [
|
||||
...[
|
||||
{
|
||||
deny: ['VIEW_CHANNEL'],
|
||||
id: message.guild.roles.everyone
|
||||
},
|
||||
{
|
||||
allow: allowed_permissions,
|
||||
id: this.client.user.id
|
||||
}
|
||||
],
|
||||
...c.roles.map(r => ({
|
||||
allow: allowed_permissions,
|
||||
id: r
|
||||
}))
|
||||
],
|
||||
position: 1,
|
||||
reason: `Tickets category created by ${message.author.tag}`,
|
||||
type: 'GUILD_CATEGORY'
|
||||
});
|
||||
|
||||
await this.client.db.models.Category.create({
|
||||
claiming: c.claiming,
|
||||
guild: message.guild.id,
|
||||
id: cat_channel.id,
|
||||
image: c.image,
|
||||
max_per_member: c.max_per_member,
|
||||
name: c.name,
|
||||
name_format: c.name_format,
|
||||
opening_message: c.opening_message,
|
||||
opening_questions: c.opening_questions,
|
||||
ping: c.ping,
|
||||
require_topic: c.require_topic,
|
||||
roles: c.roles,
|
||||
survey: c.survey
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (const survey in data.surveys) {
|
||||
const survey_data = {
|
||||
guild: message.guild.id,
|
||||
name: survey
|
||||
};
|
||||
const [s_row] = await this.client.db.models.Survey.findOrCreate({
|
||||
defaults: survey_data,
|
||||
where: survey_data
|
||||
],
|
||||
...roles.map(r => ({
|
||||
allow: allowed_permissions,
|
||||
id: r
|
||||
}))
|
||||
],
|
||||
position: 1,
|
||||
reason: `Tickets category created by ${interaction.user.tag}`,
|
||||
type: 'GUILD_CATEGORY'
|
||||
});
|
||||
await this.client.db.models.Category.create({
|
||||
guild: interaction.guild.id,
|
||||
id: cat_channel.id,
|
||||
name,
|
||||
roles
|
||||
});
|
||||
await this.client.commands.updatePermissions(interaction.guild);
|
||||
interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.success_colour)
|
||||
.setTitle(i18n('commands.settings.response.category_created', name))
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
break;
|
||||
}
|
||||
case default_i18n('commands.settings.options.categories.options.delete.name'): {
|
||||
const category = await this.client.db.models.Category.findOne({ where: { id: interaction.options.getString(default_i18n('commands.settings.options.categories.options.delete.options.id.name')) } });
|
||||
if (category) {
|
||||
const channel = this.client.channels.cache.get(interaction.options.getString(default_i18n('commands.settings.options.categories.options.delete.options.id.name')));
|
||||
if (channel) channel.delete();
|
||||
await category.destroy();
|
||||
interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.success_colour)
|
||||
.setTitle(i18n('commands.settings.response.category_deleted', category.name))
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
} else {
|
||||
interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setTitle(i18n('commands.settings.response.category_does_not_exist'))
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
s_row.questions = data.surveys[survey];
|
||||
await s_row.save();
|
||||
}
|
||||
|
||||
this.client.log.success(`Updated guild settings for "${message.guild.name}"`);
|
||||
return await message.channel.send({ content: i18n('commands.settings.response.updated') });
|
||||
} else {
|
||||
// upload settings as json to be edited
|
||||
|
||||
const categories = await this.client.db.models.Category.findAll({ where: { guild: message.guild.id } });
|
||||
|
||||
const surveys = await this.client.db.models.Survey.findAll({ where: { guild: message.guild.id } });
|
||||
|
||||
const data = {
|
||||
categories: categories.map(c => ({
|
||||
claiming: c.claiming,
|
||||
id: c.id,
|
||||
image: c.image,
|
||||
max_per_member: c.max_per_member,
|
||||
name: c.name,
|
||||
name_format: c.name_format,
|
||||
opening_message: c.opening_message,
|
||||
opening_questions: c.opening_questions,
|
||||
ping: c.ping,
|
||||
require_topic: c.require_topic,
|
||||
roles: c.roles,
|
||||
survey: c.survey
|
||||
})),
|
||||
colour: settings.colour,
|
||||
command_prefix: settings.command_prefix,
|
||||
error_colour: settings.error_colour,
|
||||
footer: settings.footer,
|
||||
locale: settings.locale,
|
||||
log_messages: settings.log_messages,
|
||||
success_colour: settings.success_colour,
|
||||
surveys: {},
|
||||
tags: settings.tags
|
||||
};
|
||||
|
||||
for (const survey in surveys) {
|
||||
const {
|
||||
name, questions
|
||||
} = surveys[survey];
|
||||
data.surveys[name] = questions;
|
||||
break;
|
||||
}
|
||||
case default_i18n('commands.settings.options.categories.options.edit.name'): {
|
||||
const category = await this.client.db.models.Category.findOne({ where: { id: interaction.options.getString(default_i18n('commands.settings.options.categories.options.delete.options.id.name')) } });
|
||||
if (!category) {
|
||||
return interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.error_colour)
|
||||
.setTitle(i18n('commands.settings.response.category_does_not_exist'))
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
const attachment = new MessageAttachment(
|
||||
Buffer.from(JSON.stringify(data, null, 2)),
|
||||
`Settings for ${message.guild.name}.json`
|
||||
);
|
||||
|
||||
return await message.channel.send({ files: [attachment] });
|
||||
const claiming = interaction.options.getBoolean(default_i18n('commands.settings.options.categories.options.edit.options.claiming.name'));
|
||||
const image = interaction.options.getString(default_i18n('commands.settings.options.categories.options.edit.options.image.name'));
|
||||
const max_per_member = interaction.options.getInteger(default_i18n('commands.settings.options.categories.options.edit.options.max_per_member.name'));
|
||||
const name = interaction.options.getString(default_i18n('commands.settings.options.categories.options.edit.options.name.name'));
|
||||
const name_format = interaction.options.getString(default_i18n('commands.settings.options.categories.options.edit.options.name_format.name'));
|
||||
const opening_message = interaction.options.getString(default_i18n('commands.settings.options.categories.options.edit.options.opening_message.name'));
|
||||
const ping = interaction.options.getString(default_i18n('commands.settings.options.categories.options.edit.options.ping.name'));
|
||||
const require_topic = interaction.options.getBoolean(default_i18n('commands.settings.options.categories.options.edit.options.require_topic.name'));
|
||||
const roles = interaction.options.getString(default_i18n('commands.settings.options.categories.options.edit.options.roles.name'));
|
||||
const survey = interaction.options.getString(default_i18n('commands.settings.options.categories.options.edit.options.survey.name'));
|
||||
if (claiming !== null) category.set('claiming', claiming);
|
||||
if (max_per_member !== null) category.set('max_per_member', max_per_member);
|
||||
if (image !== null) category.set('image', image);
|
||||
if (name !== null) category.set('name', name);
|
||||
if (name_format !== null) category.set('name_format', name_format);
|
||||
if (opening_message !== null) category.set('opening_message', opening_message);
|
||||
if (ping !== null) category.set('ping', ping.replace(/\s/g, '').split(','));
|
||||
if (require_topic !== null) category.set('require_topic', require_topic);
|
||||
if (roles !== null) category.set('roles', roles.replace(/\s/g, '').split(','));
|
||||
if (survey !== null) category.set('survey', survey);
|
||||
await category.save();
|
||||
interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.success_colour)
|
||||
.setTitle(i18n('commands.settings.response.category_updated', category.name))
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
break;
|
||||
}
|
||||
case default_i18n('commands.settings.options.categories.options.list.name'): {
|
||||
const categories = await this.client.db.models.Category.findAll({ where: { guild: interaction.guild.id } });
|
||||
await interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.colour)
|
||||
.setTitle(i18n('commands.settings.response.category_list'))
|
||||
.setDescription(categories.map(c => `- ${c.name} (\`${c.id}\`)`).join('\n'))
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
break;
|
||||
}
|
||||
case default_i18n('commands.settings.options.set.name'): {
|
||||
const close_button = interaction.options.getBoolean(default_i18n('commands.settings.options.set.options.close_button.name'));
|
||||
const colour = interaction.options.getString(default_i18n('commands.settings.options.set.options.colour.name'));
|
||||
const error_colour = interaction.options.getString(default_i18n('commands.settings.options.set.options.error_colour.name'));
|
||||
const footer = interaction.options.getString(default_i18n('commands.settings.options.set.options.footer.name'));
|
||||
const locale = interaction.options.getString(default_i18n('commands.settings.options.set.options.locale.name'));
|
||||
const log_messages = interaction.options.getBoolean(default_i18n('commands.settings.options.set.options.log_messages.name'));
|
||||
const success_colour = interaction.options.getString(default_i18n('commands.settings.options.set.options.success_colour.name'));
|
||||
if (close_button !== null) settings.set('close_button', close_button);
|
||||
if (colour !== null) settings.set('colour', colour.toUpperCase());
|
||||
if (error_colour !== null) settings.set('error_colour', error_colour.toUpperCase());
|
||||
if (footer !== null) settings.set('footer', footer);
|
||||
if (locale !== null) settings.set('locale', locale);
|
||||
if (log_messages !== null) settings.set('log_messages', log_messages);
|
||||
if (success_colour !== null) settings.set('success_colour', success_colour.toUpperCase());
|
||||
await settings.save();
|
||||
interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.success_colour)
|
||||
.setTitle(i18n('commands.settings.response.settings_updated'))
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@@ -1,7 +1,7 @@
|
||||
const Command = require('../modules/commands/command');
|
||||
const Keyv = require('keyv');
|
||||
const {
|
||||
Message, // eslint-disable-line no-unused-vars
|
||||
Interaction, // eslint-disable-line no-unused-vars
|
||||
MessageEmbed
|
||||
} = require('discord.js');
|
||||
|
||||
@@ -9,12 +9,9 @@ module.exports = class StatsCommand extends Command {
|
||||
constructor(client) {
|
||||
const i18n = client.i18n.getLocale(client.config.locale);
|
||||
super(client, {
|
||||
aliases: [],
|
||||
args: [],
|
||||
description: i18n('commands.stats.description'),
|
||||
internal: true,
|
||||
name: i18n('commands.stats.name'),
|
||||
process_args: false,
|
||||
staff_only: true
|
||||
});
|
||||
|
||||
@@ -22,25 +19,24 @@ module.exports = class StatsCommand extends Command {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Message} message
|
||||
* @param {string} args
|
||||
* @param {Interaction} interaction
|
||||
* @returns {Promise<void|any>}
|
||||
*/
|
||||
async execute(message) {
|
||||
const settings = await this.client.utils.getSettings(message.guild);
|
||||
async execute(interaction) {
|
||||
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
||||
const i18n = this.client.i18n.getLocale(settings.locale);
|
||||
|
||||
const messages = await this.client.db.models.Message.findAndCountAll();
|
||||
|
||||
let stats = await this.cache.get(message.guild.id);
|
||||
let stats = await this.cache.get(interaction.guild.id);
|
||||
|
||||
if (!stats) {
|
||||
const tickets = await this.client.db.models.Ticket.findAndCountAll({ where: { guild: message.guild.id } });
|
||||
const tickets = await this.client.db.models.Ticket.findAndCountAll({ where: { guild: interaction.guild.id } });
|
||||
stats = { // maths
|
||||
messages: settings.log_messages
|
||||
? await messages.rows
|
||||
.reduce(async (acc, row) => (await this.client.db.models.Ticket.findOne({ where: { id: row.ticket } }))
|
||||
.guild === message.guild.id
|
||||
.guild === interaction.guild.id
|
||||
? await acc + 1
|
||||
: await acc, 0)
|
||||
: null,
|
||||
@@ -49,38 +45,51 @@ module.exports = class StatsCommand extends Command {
|
||||
: acc, 0) / tickets.count),
|
||||
tickets: tickets.count
|
||||
};
|
||||
await this.cache.set(message.guild.id, stats, 60 * 60 * 1000); // cache for an hour
|
||||
await this.cache.set(interaction.guild.id, stats, 60 * 60 * 1000); // cache for an hour
|
||||
}
|
||||
|
||||
const guild_embed = new MessageEmbed()
|
||||
.setColor(settings.colour)
|
||||
.setTitle(i18n('commands.stats.response.guild.title'))
|
||||
.setDescription(i18n('commands.stats.response.guild.description'))
|
||||
.addField(i18n('commands.stats.fields.tickets'), stats.tickets, true)
|
||||
.addField(i18n('commands.stats.fields.tickets'), String(stats.tickets), true)
|
||||
.addField(i18n('commands.stats.fields.response_time.title'), i18n('commands.stats.fields.response_time.minutes', stats.response_time), true)
|
||||
.setFooter(settings.footer, message.guild.iconURL());
|
||||
.setFooter(settings.footer, interaction.guild.iconURL());
|
||||
|
||||
if (stats.messages) guild_embed.addField(i18n('commands.stats.fields.messages'), stats.messages, true);
|
||||
if (stats.messages) guild_embed.addField(i18n('commands.stats.fields.messages'), String(stats.messages), true);
|
||||
|
||||
await message.channel.send({
|
||||
embeds: [
|
||||
guild_embed
|
||||
]
|
||||
});
|
||||
const embeds = [guild_embed];
|
||||
|
||||
if (this.client.guilds.cache.size > 1) {
|
||||
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())
|
||||
]
|
||||
});
|
||||
let global = await this.cache.get('global');
|
||||
|
||||
if (!global) {
|
||||
const tickets = await this.client.db.models.Ticket.findAndCountAll();
|
||||
global = { // maths
|
||||
messages: settings.log_messages
|
||||
? await messages.count
|
||||
: null,
|
||||
response_time: Math.floor(tickets.rows.reduce((acc, row) => row.first_response
|
||||
? acc + ((Math.abs(new Date(row.createdAt) - new Date(row.first_response)) / 1000) / 60)
|
||||
: acc, 0) / tickets.count),
|
||||
tickets: tickets.count
|
||||
};
|
||||
await this.cache.set('global', global, 60 * 60 * 1000); // cache for an hour
|
||||
}
|
||||
|
||||
const global_embed = 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'), String(global.tickets), true)
|
||||
.addField(i18n('commands.stats.fields.response_time.title'), i18n('commands.stats.fields.response_time.minutes', global.response_time), true)
|
||||
.setFooter(settings.footer, interaction.guild.iconURL());
|
||||
|
||||
if (stats.messages) global_embed.addField(i18n('commands.stats.fields.messages'), String(global.messages), true);
|
||||
|
||||
embeds.push(global_embed);
|
||||
}
|
||||
|
||||
await interaction.reply({ embeds });
|
||||
}
|
||||
};
|
||||
|
@@ -13,38 +13,44 @@ module.exports = class SurveyCommand extends Command {
|
||||
constructor(client) {
|
||||
const i18n = client.i18n.getLocale(client.config.locale);
|
||||
super(client, {
|
||||
aliases: [
|
||||
i18n('commands.survey.aliases.surveys')
|
||||
],
|
||||
args: [
|
||||
{
|
||||
description: i18n('commands.survey.args.survey.description'),
|
||||
example: i18n('commands.survey.args.survey.example'),
|
||||
name: i18n('commands.survey.args.survey.name'),
|
||||
required: false
|
||||
}
|
||||
],
|
||||
description: i18n('commands.survey.description'),
|
||||
internal: true,
|
||||
name: i18n('commands.survey.name'),
|
||||
process_args: false,
|
||||
options: async guild => {
|
||||
const surveys = await this.client.db.models.Survey.findAll({ where: { guild: guild.id } });
|
||||
return [
|
||||
{
|
||||
choices: surveys.map(survey => ({
|
||||
name: survey.name,
|
||||
value: survey.name
|
||||
})),
|
||||
description: i18n('commands.survey.options.survey.description'),
|
||||
name: i18n('commands.survey.options.survey.name'),
|
||||
required: true,
|
||||
type: Command.option_types.STRING
|
||||
}
|
||||
];
|
||||
},
|
||||
staff_only: true
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Message} message
|
||||
* @param {string} args
|
||||
* @param {Interaction} interaction
|
||||
* @returns {Promise<void|any>}
|
||||
*/
|
||||
async execute(message, args) {
|
||||
const settings = await this.client.utils.getSettings(message.guild);
|
||||
async execute(interaction) {
|
||||
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
||||
const default_i18n = this.client.i18n.getLocale(this.client.config.defaults.locale); // command properties could be in a different locale
|
||||
const i18n = this.client.i18n.getLocale(settings.locale);
|
||||
|
||||
const name = interaction.options.getString(default_i18n('commands.survey.options.survey.name'));
|
||||
|
||||
const survey = await this.client.db.models.Survey.findOne({
|
||||
where: {
|
||||
guild: message.guild.id,
|
||||
name: args
|
||||
guild: interaction.guild.id,
|
||||
name
|
||||
}
|
||||
});
|
||||
|
||||
@@ -55,7 +61,6 @@ module.exports = class SurveyCommand extends Command {
|
||||
|
||||
const users = new Set();
|
||||
|
||||
|
||||
for (const i in responses) {
|
||||
const ticket = await this.client.db.models.Ticket.findOne({ where: { id: responses[i].ticket } });
|
||||
users.add(ticket.creator);
|
||||
@@ -85,19 +90,23 @@ module.exports = class SurveyCommand extends Command {
|
||||
`${survey.name}.html`
|
||||
);
|
||||
|
||||
return await message.channel.send({ files: [attachment] });
|
||||
return await interaction.reply({
|
||||
ephemeral: true,
|
||||
files: [attachment]
|
||||
});
|
||||
} else {
|
||||
const surveys = await this.client.db.models.Survey.findAll({ where: { guild: message.guild.id } });
|
||||
const surveys = await this.client.db.models.Survey.findAll({ where: { guild: interaction.guild.id } });
|
||||
|
||||
const list = surveys.map(s => `❯ **\`${s.name}\`**`);
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.colour)
|
||||
.setTitle(i18n('commands.survey.response.list.title'))
|
||||
.setDescription(list.join('\n'))
|
||||
.setFooter(settings.footer, message.guild.iconURL())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -1,132 +1,72 @@
|
||||
const Command = require('../modules/commands/command');
|
||||
const {
|
||||
Message, // eslint-disable-line no-unused-vars
|
||||
Interaction, // eslint-disable-line no-unused-vars
|
||||
MessageEmbed
|
||||
} = require('discord.js');
|
||||
const { parseArgsStringToArgv: argv } = require('string-argv');
|
||||
const parseArgs = require('command-line-args');
|
||||
|
||||
module.exports = class TagCommand extends Command {
|
||||
constructor(client) {
|
||||
const i18n = client.i18n.getLocale(client.config.locale);
|
||||
super(client, {
|
||||
aliases: [
|
||||
i18n('commands.tag.aliases.faq'),
|
||||
i18n('commands.tag.aliases.t'),
|
||||
i18n('commands.tag.aliases.tags')
|
||||
],
|
||||
args: [
|
||||
{
|
||||
description: i18n('commands.tag.args.command.description'),
|
||||
example: i18n('commands.tag.args.tag.example'),
|
||||
name: i18n('commands.tag.args.tag.name'),
|
||||
required: false
|
||||
}
|
||||
],
|
||||
description: i18n('commands.tag.description'),
|
||||
internal: true,
|
||||
name: i18n('commands.tag.name'),
|
||||
process_args: false,
|
||||
options: async guild => {
|
||||
const settings = await client.utils.getSettings(guild.id);
|
||||
return Object.keys(settings.tags).map(tag => ({
|
||||
description: settings.tags[tag].substring(0, 100),
|
||||
name: tag,
|
||||
options: [...settings.tags[tag].matchAll(/(?<!\\){{1,2}\s?([A-Za-z0-9._:]+)\s?(?<!\\)}{1,2}/gi)]
|
||||
.map(match => ({
|
||||
description: match[1],
|
||||
name: match[1],
|
||||
required: true,
|
||||
type: Command.option_types.STRING
|
||||
})),
|
||||
required: false,
|
||||
type: Command.option_types.SUB_COMMAND
|
||||
}));
|
||||
},
|
||||
staff_only: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Message} message
|
||||
* @param {string} args
|
||||
* @param {Interaction} interaction
|
||||
* @returns {Promise<void|any>}
|
||||
*/
|
||||
async execute(message, args) {
|
||||
const settings = await this.client.utils.getSettings(message.guild);
|
||||
async execute(interaction) {
|
||||
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
||||
const i18n = this.client.i18n.getLocale(settings.locale);
|
||||
|
||||
const t_row = await this.client.db.models.Ticket.findOne({ where: { id: message.channel.id } });
|
||||
const tag_name = interaction.options.getSubcommand();
|
||||
const tag = settings.tags[tag_name];
|
||||
const args = interaction.options.data[0]?.options;
|
||||
|
||||
args = args.split(/\s/g); // convert to an array
|
||||
const tag_name = args.shift(); // shift the first element
|
||||
args = args.join(' '); // convert back to a string with the first word removed
|
||||
|
||||
if (tag_name && settings.tags[tag_name]) {
|
||||
const tag = settings.tags[tag_name];
|
||||
const placeholders = [...tag.matchAll(/(?<!\\){{1,2}\s?([A-Za-z0-9._:]+)\s?(?<!\\)}{1,2}/gi)].map(p => p[1]);
|
||||
const requires_ticket = placeholders.some(p => p.startsWith('ticket.'));
|
||||
|
||||
if (requires_ticket && !t_row) {
|
||||
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
|
||||
.filter(p => p.startsWith(':'))
|
||||
.map(p => ({
|
||||
name: p.substr(1, p.length),
|
||||
type: String
|
||||
}));
|
||||
|
||||
if (expected.length >= 1) {
|
||||
try {
|
||||
args = parseArgs(expected, { argv: argv(args) });
|
||||
} catch (error) {
|
||||
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 = {};
|
||||
}
|
||||
|
||||
for (const p of expected) {
|
||||
if (!args[p.name]) {
|
||||
const list = expected.map(p => `\`${p.name}\``);
|
||||
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())
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (requires_ticket) {
|
||||
args.ticket = t_row.toJSON();
|
||||
args.ticket.topic = t_row.topic ? this.client.cryptr.decrypt(t_row.topic) : null;
|
||||
}
|
||||
|
||||
// note that this regex is slightly different to the other
|
||||
const text = tag.replace(/(?<!\\){{1,2}\s?:?([A-Za-z0-9._]+)\s?(?<!\\)}{1,2}/gi, (_$, $1) => this.client.i18n.resolve(args, $1));
|
||||
return await message.channel.send({
|
||||
if (tag) {
|
||||
const text = tag.replace(/(?<!\\){{1,2}\s?([A-Za-z0-9._:]+)\s?(?<!\\)}{1,2}/gi, ($, $1) => {
|
||||
const arg = args.find(arg => arg.name === $1);
|
||||
return arg ? arg.value : $;
|
||||
});
|
||||
return await interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.colour)
|
||||
.setDescription(text)
|
||||
]
|
||||
],
|
||||
ephemeral: false
|
||||
});
|
||||
} else {
|
||||
const list = Object.keys(settings.tags).map(t => `❯ **\`${t}\`**`);
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.colour)
|
||||
.setTitle(i18n('commands.tag.response.list.title'))
|
||||
.setDescription(list.join('\n'))
|
||||
.setFooter(settings.footer, message.guild.iconURL())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
const Command = require('../modules/commands/command');
|
||||
const {
|
||||
Message, // eslint-disable-line no-unused-vars
|
||||
Interaction, // eslint-disable-line no-unused-vars
|
||||
MessageEmbed
|
||||
} = require('discord.js');
|
||||
|
||||
@@ -8,55 +8,56 @@ module.exports = class TopicCommand extends Command {
|
||||
constructor(client) {
|
||||
const i18n = client.i18n.getLocale(client.config.locale);
|
||||
super(client, {
|
||||
aliases: [],
|
||||
args: [
|
||||
{
|
||||
description: i18n('commands.topic.args.new_topic.description'),
|
||||
example: i18n('commands.topic.args.new_topic.example'),
|
||||
name: i18n('commands.topic.args.new_topic.name'),
|
||||
required: true
|
||||
}
|
||||
],
|
||||
description: i18n('commands.topic.description'),
|
||||
internal: true,
|
||||
name: i18n('commands.topic.name'),
|
||||
process_args: false
|
||||
options: [
|
||||
{
|
||||
description: i18n('commands.topic.options.new_topic.description'),
|
||||
name: i18n('commands.topic.options.new_topic.name'),
|
||||
required: true,
|
||||
type: Command.option_types.STRING
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Message} message
|
||||
* @param {string} args
|
||||
* @param {Interaction} interaction
|
||||
* @returns {Promise<void|any>}
|
||||
*/
|
||||
async execute(message, args) {
|
||||
const settings = await this.client.utils.getSettings(message.guild);
|
||||
async execute(interaction) {
|
||||
const settings = await this.client.utils.getSettings(interaction.guild.id);
|
||||
const default_i18n = this.client.i18n.getLocale(this.client.config.defaults.locale); // command properties could be in a different locale
|
||||
const i18n = this.client.i18n.getLocale(settings.locale);
|
||||
|
||||
const t_row = await this.client.db.models.Ticket.findOne({ where: { id: message.channel.id } });
|
||||
const topic = interaction.options.getString(default_i18n('commands.topic.options.new_topic.name'));
|
||||
|
||||
const t_row = await this.client.db.models.Ticket.findOne({ where: { id: interaction.channel.id } });
|
||||
|
||||
if (!t_row) {
|
||||
return await message.channel.send({
|
||||
return await interaction.reply({
|
||||
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())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: true
|
||||
});
|
||||
}
|
||||
|
||||
await t_row.update({ topic: this.client.cryptr.encrypt(args) });
|
||||
await t_row.update({ topic: this.client.cryptr.encrypt(topic) });
|
||||
|
||||
const member = await message.guild.members.fetch(t_row.creator);
|
||||
/* await */message.channel.setTopic(`${member} | ${args}`, { reason: 'User updated ticket topic' });
|
||||
const member = await interaction.guild.members.fetch(t_row.creator);
|
||||
interaction.channel.setTopic(`${member} | ${topic}`, { reason: 'User updated ticket topic' });
|
||||
|
||||
const cat_row = await this.client.db.models.Category.findOne({ where: { id: t_row.category } });
|
||||
const description = cat_row.opening_message
|
||||
.replace(/{+\s?(user)?name\s?}+/gi, member.displayName)
|
||||
.replace(/{+\s?(tag|ping|mention)?\s?}+/gi, member.user.toString());
|
||||
const opening_message = await message.channel.messages.fetch(t_row.opening_message);
|
||||
const opening_message = await interaction.channel.messages.fetch(t_row.opening_message);
|
||||
|
||||
await opening_message.edit({
|
||||
embeds: [
|
||||
@@ -64,22 +65,23 @@ module.exports = class TopicCommand extends Command {
|
||||
.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())
|
||||
.addField(i18n('ticket.opening_message.fields.topic'), topic)
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
]
|
||||
});
|
||||
|
||||
await message.channel.send({
|
||||
await interaction.reply({
|
||||
embeds: [
|
||||
new MessageEmbed()
|
||||
.setColor(settings.success_colour)
|
||||
.setAuthor(message.author.username, message.author.displayAvatarURL())
|
||||
.setAuthor(interaction.user.username, interaction.user.displayAvatarURL())
|
||||
.setTitle(i18n('commands.topic.response.changed.title'))
|
||||
.setDescription(i18n('commands.topic.response.changed.description'))
|
||||
.setFooter(settings.footer, message.guild.iconURL())
|
||||
]
|
||||
.setFooter(settings.footer, interaction.guild.iconURL())
|
||||
],
|
||||
ephemeral: false
|
||||
});
|
||||
|
||||
this.client.log.info(`${message.author.tag} changed the topic of ${message.channel.id}`);
|
||||
this.client.log.info(`${interaction.user.tag} changed the topic of #${interaction.channel.name}`);
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user