Panel creation

This commit is contained in:
Isaac 2021-05-11 23:12:06 +01:00
parent da7188d923
commit 8903f10305
No known key found for this signature in database
GPG Key ID: F6812DBC6719B4E3
7 changed files with 173 additions and 18 deletions

View File

@ -36,6 +36,7 @@
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"leeks.js": "^0.0.9", "leeks.js": "^0.0.9",
"leekslazylogger-fastify": "^0.1.0", "leekslazylogger-fastify": "^0.1.0",
"node-emoji": "^1.10.0",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"semver": "^7.3.4", "semver": "^7.3.4",
"sequelize": "^6.5.0", "sequelize": "^6.5.0",

View File

@ -12,6 +12,7 @@ specifiers:
leekslazylogger-fastify: ^0.1.0 leekslazylogger-fastify: ^0.1.0
mariadb: ^2.5.2 mariadb: ^2.5.2
mysql2: ^2.2.5 mysql2: ^2.2.5
node-emoji: ^1.10.0
node-fetch: ^2.6.1 node-fetch: ^2.6.1
nodemon: ^2.0.7 nodemon: ^2.0.7
pg: ^8.5.1 pg: ^8.5.1
@ -32,6 +33,7 @@ dependencies:
dotenv: 8.2.0 dotenv: 8.2.0
leeks.js: 0.0.9 leeks.js: 0.0.9
leekslazylogger-fastify: 0.1.0 leekslazylogger-fastify: 0.1.0
node-emoji: 1.10.0
node-fetch: 2.6.1 node-fetch: 2.6.1
semver: 7.3.4 semver: 7.3.4
sequelize: 6.5.0_fb66e8c649bde1be622cc06164c9e22d sequelize: 6.5.0_fb66e8c649bde1be622cc06164c9e22d
@ -1481,6 +1483,10 @@ packages:
resolution: {integrity: sha1-soqmKIorn8ZRA1x3EfZathkDMaY=} resolution: {integrity: sha1-soqmKIorn8ZRA1x3EfZathkDMaY=}
dev: false dev: false
/lodash.toarray/4.4.0:
resolution: {integrity: sha1-JMS/zWsvuji/0FlNsRedjptlZWE=}
dev: false
/lodash/4.17.20: /lodash/4.17.20:
resolution: {integrity: sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==} resolution: {integrity: sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==}
@ -1648,6 +1654,12 @@ packages:
dev: false dev: false
optional: true optional: true
/node-emoji/1.10.0:
resolution: {integrity: sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==}
dependencies:
lodash.toarray: 4.4.0
dev: false
/node-fetch/2.6.1: /node-fetch/2.6.1:
resolution: {integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==} resolution: {integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==}
engines: {node: 4.x || >=6.0.0} engines: {node: 4.x || >=6.0.0}

View File

@ -1,5 +1,7 @@
const Command = require('../modules/commands/command'); const Command = require('../modules/commands/command');
const { MessageEmbed } = require('discord.js'); const { MessageEmbed } = require('discord.js');
const { some, wait } = require('../utils');
const { emojify } = require('node-emoji');
module.exports = class PanelCommand extends Command { module.exports = class PanelCommand extends Command {
constructor(client) { constructor(client) {
@ -40,12 +42,12 @@ module.exports = class PanelCommand extends Command {
multiple: true, multiple: true,
}, },
{ {
name: i18n('commands.panel.args.category.name'), name: i18n('commands.panel.args.categories.name'),
description: i18n('commands.panel.args.category.description'), description: i18n('commands.panel.args.categories.description'),
example: i18n('commands.panel.args.category.example'), example: i18n('commands.panel.args.categories.example'),
required: true, required: true,
// for arg parsing // for arg parsing
alias: i18n('commands.panel.args.category.alias'), alias: i18n('commands.panel.args.categories.alias'),
type: String, type: String,
multiple: true, multiple: true,
} }
@ -55,30 +57,145 @@ module.exports = class PanelCommand extends Command {
} }
async execute(message, args) { async execute(message, args) {
// localised command and arg names are a pain
const arg_title = this.args[0].name; const arg_title = this.args[0].name;
const arg_description = this.args[1].name; const arg_description = this.args[1].name;
const arg_emoji = this.args[2].name; const arg_emoji = this.args[2].name;
const arg_category = this.args[3].name; const arg_categories = this.args[3].name;
let settings = await message.guild.settings; let settings = await message.guild.settings;
const i18n = this.client.i18n.getLocale(settings.locale); const i18n = this.client.i18n.getLocale(settings.locale);
console.log(args) if (!args[arg_emoji])
message.channel.send(Object.keys(args).map(arg => `${arg}: \`${args[arg]}\``).join('\n')) args[arg_emoji] = [];
console.log(args.category)
if (!args[arg_emoji]) { args[arg_emoji] = args[arg_emoji].map(emoji => emojify(emoji.replace(/\\/g, '')));
const invalid_category = await some(args[arg_categories], async id => {
let cat_row = await this.client.db.models.Category.findOne({
where: {
id: id,
guild: message.guild.id
}
});
return !cat_row;
});
if (invalid_category) {
return await message.channel.send(
new MessageEmbed()
.setColor(settings.error_colour)
.setTitle(i18n('commands.panel.response.invalid_category.title'))
.setDescription(i18n('commands.panel.response.invalid_category.description'))
.setFooter(settings.footer, message.guild.iconURL())
);
}
let panel_channel,
panel_message;
let embed = new MessageEmbed()
.setColor(settings.colour)
.setFooter(settings.footer, message.guild.iconURL());
if (args[arg_title])
embed.setTitle(args[arg_title]);
if (args[arg_emoji].length === 0) {
// reaction-less panel // reaction-less panel
panel_channel = await message.guild.channels.create('create-a-ticket', {
type: 'text',
rateLimitPerUser: 30,
permissionOverwrites: [
{
id: message.guild.roles.everyone,
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'],
deny: ['ATTACH_FILES', 'EMBED_LINKS', 'ADD_REACTIONS']
},
{
id: this.client.user.id,
allow: ['EMBED_LINKS']
}
],
position: 1,
reason: `${message.author.tag} created a new reaction-less panel`
});
embed.setDescription(args[arg_description]);
panel_message = await panel_channel.send(embed);
this.client.log.info(`${message.author.tag} has created a new reaction-less panel`);
} else { } else {
if (!args[arg_category] || args[arg_category].length !== args[arg_emoji.length]) { if (args[arg_categories].length !== args[arg_emoji].length) {
// send error // send error
return await message.channel.send(
new MessageEmbed()
.setColor(settings.error_colour)
.setTitle(i18n('commands.panel.response.mismatch.title'))
.setDescription(i18n('commands.panel.response.mismatch.description'))
.setFooter(settings.footer, message.guild.iconURL())
);
} else { } else {
panel_channel = await message.guild.channels.create('create-a-ticket', {
type: 'text',
permissionOverwrites: [
{
id: message.guild.roles.everyone,
allow: ['VIEW_CHANNEL', 'READ_MESSAGE_HISTORY'],
deny: ['SEND_MESSAGES', 'ADD_REACTIONS']
},
{
id: this.client.user.id,
allow: ['SEND_MESSAGES', 'EMBED_LINKS']
}
],
position: 1,
reason: `${message.author.tag} created a new panel`
});
if (args[arg_emoji].length === 1) { if (args[arg_emoji].length === 1) {
// single category // single category
embed.setDescription(args[arg_description]);
panel_message = await panel_channel.send(embed);
await panel_message.react(args[arg_emoji][0]);
} else { } else {
// multi category // multi category
let emoji_map = {};
let description = '';
for (let i in args[arg_emoji]) {
emoji_map[args[arg_emoji][i]] = args[arg_categories][i];
let cat_row = await this.client.db.models.Category.findOne({
where: {
id: args[arg_categories][i],
guild: message.guild.id
}
});
description += `\n> ${args[arg_emoji][i]} | ${cat_row.name}`;
}
embed.setDescription(args[arg_description] + '\n' + description);
panel_message = await panel_channel.send(embed);
for (let 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`);
} }
} }
}
message.channel.send(`${panel_channel}`);
await this.client.db.models.Panel.create({
categories: args[arg_categories],
channel: panel_channel.id,
guild: message.guild.id,
message: panel_message.id,
});
} }
}; };

View File

@ -6,6 +6,10 @@ module.exports = (client, sequelize) => {
type: DataTypes.JSON, type: DataTypes.JSON,
allowNull: false allowNull: false
}, },
channel: {
type: DataTypes.CHAR(19),
allowNull: false
},
guild: { guild: {
type: DataTypes.CHAR(19), type: DataTypes.CHAR(19),
allowNull: false, allowNull: false,
@ -17,10 +21,6 @@ module.exports = (client, sequelize) => {
message: { message: {
type: DataTypes.CHAR(19), type: DataTypes.CHAR(19),
allowNull: false allowNull: false
},
reactionless: {
type: DataTypes.BOOLEAN,
defaultValue: false
} }
}, { }, {
tableName: DB_TABLE_PREFIX + 'panels' tableName: DB_TABLE_PREFIX + 'panels'

View File

@ -23,6 +23,16 @@ module.exports = {
first_response: new Date() first_response: new Date()
}); });
} }
} else {
let p_row = await client.db.models.Panel.findOne({
where: {
channel: message.channel.id
}
});
if (p_row) {
// handle reaction-less panel
}
} }
client.commands.handle(message); // pass the message to the command handler client.commands.handle(message); // pass the message to the command handler

View File

@ -157,11 +157,11 @@
"panel": { "panel": {
"aliases": {}, "aliases": {},
"args": { "args": {
"category": { "categories": {
"alias": "c", "alias": "c",
"description": "A category ID", "description": "A category ID",
"example": "451745464954650634", "example": "451745464954650634",
"name": "category" "name": "categories"
}, },
"description": { "description": {
"alias": "d", "alias": "d",
@ -171,7 +171,7 @@
}, },
"emoji": { "emoji": {
"alias": "e", "alias": "e",
"description": "A **unicode** emoji character (escaped emoji)", "description": "An emoji",
"example": "🎫", "example": "🎫",
"name": "emoji" "name": "emoji"
}, },
@ -184,7 +184,16 @@
}, },
"description": "Create a new ticket panel", "description": "Create a new ticket panel",
"name": "panel", "name": "panel",
"response": {} "response": {
"invalid_category": {
"description": "One or more of the specified category IDs is invalid.",
"title": "❌ Invalid category"
},
"mismatch": {
"description": "Please provide the name number of emojis and category IDs.",
"title": "❌ Invalid input"
}
}
}, },
"settings": { "settings": {
"aliases": { "aliases": {

View File

@ -1,4 +1,10 @@
module.exports = { module.exports = {
int2hex: (int) => int.toString(16).toUpperCase(), int2hex: (int) => int.toString(16).toUpperCase(),
some: async (array, func) => {
for (let element of array) {
if (await func(element)) return true;
}
return false;
},
wait: (time) => new Promise(res => setTimeout(res, time)), wait: (time) => new Promise(res => setTimeout(res, time)),
}; };