Ticket message storage, added entity stuff

This commit is contained in:
Isaac 2021-04-01 21:33:08 +01:00
parent 2e9217f30d
commit 1a4a3c1a33
10 changed files with 209 additions and 97 deletions

View File

@ -18,7 +18,7 @@ module.exports = class NewCommand extends Command {
name: i18n('commands.new.args.topic.name'),
description: i18n('commands.new.args.topic.description'),
example: i18n('commands.new.args.topic.example'),
required: true,
required: false,
}
]
});

View File

@ -66,7 +66,7 @@ const { selectPresence } = require('./utils/discord');
const I18n = require('@eartharoid/i18n');
const CommandManager = require('./modules/commands/manager');
const PluginManager = require('./modules/plugins/manager');
const TicketManager = require('./modules/tickets');
const TicketManager = require('./modules/tickets/manager');
require('./modules/structures')(); // load extended structures before creating the client

View File

@ -4,32 +4,9 @@ module.exports = {
let settings = await message.guild?.settings;
// message collection for t_row archiving
if (settings?.log_messages) {
if (message.system) return;
let t_row = await client.db.models.Ticket.findOne({
where: {
id: message.channel.id
}
});
if (t_row) {
let embeds = [];
for (let embed in message.embeds) embeds.push({ ...message.embeds[embed] });
await client.db.models.Message.create({
id: message.id,
ticket: t_row.id,
author: message.author.id,
data: {
content: message.content,
// time: message.createdTimestamp,
embeds,
attachments: [...message.attachments.values()]
}
});
}
client.tickets.archives.addMessage(message);
}
client.commands.handle(message);

View File

@ -6,17 +6,7 @@ module.exports = {
if (settings?.log_messages) {
if (message.system) return;
let msg = await client.db.models.Message.findOne({
where: {
id: message.id
}
});
if (msg) {
msg.deleted = true;
await msg.save(); // save changes to message row
}
client.tickets.archives.deleteMessage(message);
}
}
};

View File

@ -14,30 +14,7 @@ module.exports = {
if (settings?.log_messages) {
if (newm.system) return;
let m_row = await client.db.models.Message.findOne({
where: {
id: newm.id
}
});
if (m_row) {
let embeds = [];
for (let embed in newm.embeds) embeds.push({ ...newm.embeds[embed] });
m_row.data = {
content: newm.content,
// time: newm.editedTimestamp,
embeds: newm.embeds.map(embed => {
return { ...newm.embeds[embed] };
}),
attachments: [...newm.attachments.values()]
};
if (newm.editedTimestamp) m_row.edited = true;
await m_row.save(); // save changes
}
client.tickets.archives.updateMessage(newm);
}
}
};

View File

@ -8,7 +8,7 @@
"example": "**Example:**"
},
"description": "**Usage:**\n`%s`\n\n**Example:**\n`%s`\n\nRequired arguments are prefixed with `❗`.",
"named_args_description": "This command uses named arguments.\n\n",
"named_args": "This command uses named arguments.\n\n",
"title": "`%s` command usage"
},
"commands": {

View File

@ -99,7 +99,7 @@ module.exports = class CommandManager {
let embed = new MessageEmbed()
.setColor(settings.error_colour)
.setTitle(i18n('cmd_usage.title', cmd_name))
.setDescription(i18n('cmd_usage.named_args_description') + i18n('cmd_usage.description', usage, example));
.setDescription(i18n('cmd_usage.named_args') + i18n('cmd_usage.description', usage, example));
cmd.args.forEach(a => addArgs(embed, a));
return message.channel.send(embed);
}

View File

@ -0,0 +1,165 @@
/** Manages ticket archiving */
module.exports = class TicketArchives {
/**
* Create a TicketArchives instance
* @param {Client} client
*/
constructor(client) {
/** The Discord Client */
this.client = client;
}
async addMessage(message) {
let t_row = await this.client.db.models.Ticket.findOne({
where: {
id: message.channel.id
}
});
if (t_row) {
let embeds = [];
for (let embed in message.embeds) embeds.push({ ...message.embeds[embed] });
await this.client.db.models.Message.create({
id: message.id,
ticket: t_row.id,
author: message.author.id,
data: {
content: message.content,
// time: message.createdTimestamp,
embeds,
attachments: [...message.attachments.values()]
}
});
this.updateEntities(message);
}
}
async updateMessage(message) {
let m_row = await this.client.db.models.Message.findOne({
where: {
id: message.id
}
});
if (m_row) {
let embeds = [];
for (let embed in message.embeds) embeds.push({ ...message.embeds[embed] });
m_row.data = {
content: message.content,
// time: message.editedTimestamp,
embeds: message.embeds.map(embed => {
return { ...message.embeds[embed] };
}),
attachments: [...message.attachments.values()]
};
if (message.editedTimestamp) {
m_row.edited = true;
this.updateEntities(message);
}
await m_row.save(); // save changes
}
}
async deleteMessage(message) {
let msg = await this.client.db.models.Message.findOne({
where: {
id: message.id
}
});
if (msg) {
msg.deleted = true;
await msg.save(); // save changes to message row
}
}
async updateEntities(message) {
let m_row = await this.client.db.models.Message.findOne({
where: {
id: message.id
}
});
if (m_row) {
// message author
let u_model_data = {
user: message.author.id,
ticket: message.channel.id
};
let [u_row] = await this.client.db.models.UserEntity.findOrCreate({
where: u_model_data,
defaults: u_model_data
});
await u_row.update({
avatar: message.author.displayAvatarURL(),
username: message.author.username,
discriminator: message.author.discriminator,
display_name: message.member.displayName,
colour: message.member.displayColor === 0 ? null : message.member.displayColor,
bot: message.author.bot
});
// mentioned members
message.mentions.members.forEach(async member => {
let m_model_data = {
user: member.user.id,
ticket: message.channel.id
};
let [m_row] = await this.client.db.models.UserEntity.findOrCreate({
where: m_model_data,
defaults: m_model_data
});
await m_row.update({
avatar: member.user.displayAvatarURL(),
username: member.user.username,
discriminator: member.user.discriminator,
display_name: member.displayName,
colour: member.displayColor === 0 ? null : member.displayColor,
bot: member.user.bot
});
});
// mentioned channels
message.mentions.channels.forEach(async channel => {
let c_model_data = {
channel: channel.id,
ticket: message.channel.id
};
let [c_row] = await this.client.db.models.ChannelEntity.findOrCreate({
where: c_model_data,
defaults: c_model_data
});
await c_row.update({
name: channel.name
});
});
// mentioned roles
message.mentions.roles.forEach(async role => {
let r_model_data = {
role: role.id,
ticket: message.channel.id
};
let [r_row] = await this.client.db.models.RoleEntity.findOrCreate({
where: r_model_data,
defaults: r_model_data
});
await r_row.update({
name: role.name,
colour: role.color === 0 ? 7506394 : role.color
});
});
}
}
};

View File

@ -1,12 +1,11 @@
const EventEmitter = require('events');
// eslint-disable-next-line no-unused-vars
const { Client } = require('discord.js');
const TicketArchives = require('./archives');
/** Manages tickets */
module.exports = class TicketManager extends EventEmitter {
/**
* Create a TicketManager instance
* @param {Client} client
* @param {Client} client
*/
constructor(client) {
super();
@ -15,6 +14,8 @@ module.exports = class TicketManager extends EventEmitter {
this.client = client;
this.setMaxListeners(this.client.config.max_listeners);
this.archives = new TicketArchives(this.client);
}
/**
@ -55,6 +56,13 @@ module.exports = class TicketManager extends EventEmitter {
reason: `${member.tag} requested a new ticket channel`
});
await t_channel.updateOverwrite(creator_id, {
VIEW_CHANNEL: true,
READ_MESSAGE_HISTORY: true,
SEND_MESSAGES: true,
ATTACH_FILES: true
}, `Ticket channel created by ${member.user.tag}`);
let t_row = await this.client.db.models.Ticket.create({
id: t_channel.id,
number,
@ -69,60 +77,54 @@ module.exports = class TicketManager extends EventEmitter {
/**
* Get a ticket
* @param {(string|number)} ticket - The channel ID, or the ticket number
* @param {(string|number)} ticket_id - The channel ID, or the ticket number
* @param {string} guild_id - The ID of the ticket's guild (used if a ticket number is provided instead of ID)
*/
async get(ticket, guild_id) {
let row = await this.resolveTicket(ticket, guild_id);
if (!row) throw new Error(`Could not find a ticket with ID ${ticket}`);
async get(ticket_id, guild_id) {
return await this.resolve(ticket_id, guild_id);
}
/**
* Close a ticket
* @param {(string|number)} ticket - The channel ID, or the ticket number
* @param {(string|null)} closer_id - ID of the member who is closing the ticket, or null
* @param {(string|number)} ticket_id - The channel ID, or the ticket number
* @param {string?} closer_id - ID of the member who is closing the ticket, or null
* @param {string} [guild_id] - The ID of the ticket's guild (used if a ticket number is provided instead of ID)
*/
async close(ticket, closer_id, guild_id) {
let row = await this.resolveTicket(ticket, guild_id);
if (!row) throw new Error(`Could not find a ticket with ID ${ticket}`);
async close(ticket_id, closer_id, guild_id) {
let t_row = await this.resolve(ticket_id, guild_id);
if (!t_row) throw new Error(`Could not find a ticket with ID ${ticket_id}`);
ticket_id = t_row.id;
this.emit('beforeClose', ticket, closer_id);
this.emit('beforeClose', ticket_id, closer_id);
/**
*
*
* for each message of ticket, create entities
*
*
*/
// ...
this.emit('close', ticket, closer_id);
this.emit('close', ticket_id, closer_id);
}
/**
*
* @param {(string|number)} ticket - ID or number of the ticket
* @param {(string|number)} ticket_id - ID or number of the ticket
* @param {string} [guild_id] - The ID of the ticket's guild (used if a ticket number is provided instead of ID)
*/
async resolve(ticket, guild_id) {
if (!this.client.channels.resolve(ticket)) {
let row = await this.client.db.models.Ticket.findOne({
async resolve(ticket_id, guild_id) {
if (!this.client.channels.resolve(ticket_id)) {
let t_row = await this.client.db.models.Ticket.findOne({
where: {
number: ticket,
number: ticket_id,
guild_id
}
});
ticket = row?.id;
ticket_id = t_row?.id;
}
let row = await this.client.db.models.Ticket.findOne({
let t_row = await this.client.db.models.Ticket.findOne({
where: {
id: ticket
id: ticket_id
}
});
return row;
return t_row;
}
};

View File

@ -16,11 +16,13 @@
* ###############################################################################################
*/
const prefix = '-';
module.exports = {
debug: false,
defaults: {
colour: '#009999', // https://discord.js.org/#/docs/main/stable/typedef/ColorResolvable
command_prefix: 'tickets/',
command_prefix: prefix,
log_messages: true, // transcripts/archives will be empty if false
name_format: 'ticket-{number}',
ticket_welcome: 'Hello {name}, thank you for creating a ticket. A member of staff will soon be available to assist you.\n\n__All messages in this channel are stored for future reference.__',
@ -36,9 +38,8 @@ module.exports = {
presence: {
presences: [
{
activity: '/new',
type: 'PLAYING',
status: 'online'
activity: `${prefix}new`,
type: 'PLAYING'
},
{
activity: 'with tickets',