diff --git a/.gitignore b/.gitignore index 83149be..a90948e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ user/.env user/storage.db user/transcripts/text/*.txt user/transcripts/raw/*.log -user/transcripts/raw/*.json \ No newline at end of file +user/transcripts/raw/entities/*.json \ No newline at end of file diff --git a/src/commands/add.js b/src/commands/add.js index b04ad24..1f661b0 100644 --- a/src/commands/add.js +++ b/src/commands/add.js @@ -6,7 +6,7 @@ * */ -const Discord = require('discord.js'); +const { MessageEmbed } = require('discord.js'); const config = require('../../user/config.js'); const ChildLogger = require('leekslazylogger').ChildLogger; const log = new ChildLogger(); @@ -15,14 +15,14 @@ module.exports = { name: 'add', description: 'Add a member to a ticket channel', usage: '<@member> [... #channel]', - aliases: ['+'], + aliases: ['none'], example: 'add @member to #ticket-23', args: true, async execute(client, message, args, Ticket) { const guild = client.guilds.cache.get(config.guild); - const notTicket = new Discord.MessageEmbed() + const notTicket = new MessageEmbed() .setColor(config.err_colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':x: **This isn\'t a ticket channel**') @@ -55,7 +55,7 @@ module.exports = { if(message.author.id !== ticket.get('creator') && !message.member.roles.cache.has(config.staff_role)) return message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':x: **No permission**') @@ -71,7 +71,7 @@ module.exports = { if(!member) return message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':x: **Unknown member**') @@ -91,7 +91,7 @@ module.exports = { if(channel.id !== message.channel.id) channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(member.user.username, member.user.displayAvatarURL()) .setTitle('**Member added**') @@ -102,7 +102,7 @@ module.exports = { message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(member.user.username, member.user.displayAvatarURL()) .setTitle(':white_check_mark: **Member added**') diff --git a/src/commands/close.js b/src/commands/close.js index b513432..cc3cf5d 100644 --- a/src/commands/close.js +++ b/src/commands/close.js @@ -8,7 +8,7 @@ const ChildLogger = require('leekslazylogger').ChildLogger; const log = new ChildLogger(); -const Discord = require('discord.js'); +const { MessageEmbed } = require('discord.js'); const config = require('../../user/config'); const fs = require('fs'); @@ -23,7 +23,7 @@ module.exports = { const guild = client.guilds.cache.get(config.guild); - const notTicket = new Discord.MessageEmbed() + const notTicket = new MessageEmbed() .setColor(config.err_colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':x: **This isn\'t a ticket channel**') @@ -55,7 +55,7 @@ module.exports = { if(message.author.id !== ticket.get('creator') && !message.member.roles.cache.has(config.staff_role)) return channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':x: **No permission**') @@ -73,7 +73,7 @@ module.exports = { : ''; let confirm = await message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':grey_question: Are you sure?') @@ -90,7 +90,7 @@ module.exports = { collector.on('collect', () => { if (channel.id !== message.channel.id) channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle('**Ticket closed**') @@ -100,7 +100,7 @@ module.exports = { confirm.reactions.removeAll(); confirm.edit( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(`:white_check_mark: **Ticket ${ticket.id} closed**`) @@ -121,7 +121,7 @@ module.exports = { if (config.logs.discord.enabled) client.channels.cache.get(config.logs.discord.channel).send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle('Ticket closed') @@ -137,7 +137,7 @@ module.exports = { if(!success) { confirm.reactions.removeAll(); confirm.edit( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':x: **Expired**') diff --git a/src/commands/help.js b/src/commands/help.js index c8a99d8..56dd859 100644 --- a/src/commands/help.js +++ b/src/commands/help.js @@ -8,7 +8,7 @@ const ChildLogger = require('leekslazylogger').ChildLogger; const log = new ChildLogger(); -const Discord = require('discord.js'); +const { MessageEmbed } = require('discord.js'); const config = require('../../user/config'); module.exports = { @@ -41,7 +41,7 @@ module.exports = { } message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setTitle('Commands') .setColor(config.colour) .setDescription( @@ -50,7 +50,6 @@ module.exports = { \nPlease contact a member of staff if you require assistance.` ) .setFooter(guild.name, guild.iconURL()) - .setTimestamp() ).catch((error) => { log.warn('Could not send help menu'); log.error(error); @@ -62,13 +61,13 @@ module.exports = { if (!command) return message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setDescription(`:x: **Invalid command name** (\`${config.prefix}help\`)`) ); - const cmd = new Discord.MessageEmbed() + const cmd = new MessageEmbed() .setColor(config.colour) .setTitle(command.name); diff --git a/src/commands/new.js b/src/commands/new.js index 7df3749..849882c 100644 --- a/src/commands/new.js +++ b/src/commands/new.js @@ -8,7 +8,7 @@ const ChildLogger = require('leekslazylogger').ChildLogger; const log = new ChildLogger(); -const Discord = require('discord.js'); +const { MessageEmbed } = require('discord.js'); const fs = require('fs'); const config = require('../../user/config'); @@ -26,7 +26,7 @@ module.exports = { const supportRole = guild.roles.cache.get(config.staff_role); if (!supportRole) return message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setTitle(':x: **Error**') .setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``) @@ -51,7 +51,7 @@ module.exports = { } let m = await message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(`:x: **You already have ${tickets.count} or more open tickets**`) @@ -69,7 +69,7 @@ module.exports = { let topic = args.join(' '); if (topic.length > 256) return message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':x: **Description too long**') @@ -119,7 +119,7 @@ module.exports = { }); let m = await message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':white_check_mark: **Ticket created**') @@ -164,7 +164,7 @@ module.exports = { let w = await c.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setDescription(text) @@ -178,7 +178,7 @@ module.exports = { if (config.logs.discord.enabled) client.channels.cache.get(config.logs.discord.channel).send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle('New ticket') diff --git a/src/commands/panel.js b/src/commands/panel.js index 3cd56a2..8e59577 100644 --- a/src/commands/panel.js +++ b/src/commands/panel.js @@ -8,7 +8,7 @@ const ChildLogger = require('leekslazylogger').ChildLogger; const log = new ChildLogger(); -const Discord = require('discord.js'); +const { MessageEmbed } = require('discord.js'); const config = require('../../user/config'); module.exports = { @@ -47,12 +47,11 @@ module.exports = { message.delete(); panel = await message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setTitle(config.panel.title) .setDescription(config.panel.description) .setFooter(guild.name, guild.iconURL()) - .setTimestamp() ); // send new panel panel.react(config.panel.reaction); // add reaction diff --git a/src/commands/remove.js b/src/commands/remove.js index c88be01..7d605e1 100644 --- a/src/commands/remove.js +++ b/src/commands/remove.js @@ -6,7 +6,7 @@ * */ -const Discord = require('discord.js'); +const { MessageEmbed } = require('discord.js'); const config = require('../../user/config.js'); const ChildLogger = require('leekslazylogger').ChildLogger; const log = new ChildLogger(); @@ -15,14 +15,14 @@ module.exports = { name: 'remove', description: 'Remove a member from ticket channel', usage: '<@member> [... #channel]', - aliases: ['-'], + aliases: ['none'], example: 'remove @member from #ticket-23', args: true, async execute(client, message, args, Ticket) { const guild = client.guilds.cache.get(config.guild); - const notTicket = new Discord.MessageEmbed() + const notTicket = new MessageEmbed() .setColor(config.err_colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':x: **This isn\'t a ticket channel**') @@ -55,7 +55,7 @@ module.exports = { if(message.author.id !== ticket.get('creator') && !message.member.roles.cache.has(config.staff_role)) return message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':x: **No permission**') @@ -71,7 +71,7 @@ module.exports = { if(!member) return message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':x: **Unknown member**') @@ -91,7 +91,7 @@ module.exports = { if(channel.id !== message.channel.id) channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(member.user.username, member.user.displayAvatarURL()) .setTitle('**Member remove**') @@ -102,7 +102,7 @@ module.exports = { message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(member.user.username, member.user.displayAvatarURL()) .setTitle(':white_check_mark: **Member removed**') diff --git a/src/commands/tickets.js b/src/commands/tickets.js index f70d4fd..6c9427a 100644 --- a/src/commands/tickets.js +++ b/src/commands/tickets.js @@ -6,7 +6,7 @@ * */ -const Discord = require('discord.js'); +const { MessageEmbed } = require('discord.js'); const fs = require('fs'); const config = require('../../user/config'); @@ -24,7 +24,7 @@ module.exports = { const supportRole = guild.roles.cache.get(config.staff_role); if (!supportRole) return message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setTitle(':x: **Error**') .setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``) @@ -37,7 +37,7 @@ module.exports = { if(user) { if(!message.member.roles.cache.has(config.staff_role)) return message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setAuthor(message.author.username, message.author.displayAvatarURL()) .setTitle(':x: **No permission**') @@ -69,7 +69,7 @@ module.exports = { closedTickets.rows = closedTickets.rows.slice(-10); // get most recent 10 - let embed = new Discord.MessageEmbed() + let embed = new MessageEmbed() .setColor(config.colour) .setAuthor(user.username, user.displayAvatarURL()) .setTitle(`${context === 'self' ? 'Your' : user.username + '\'s'} tickets`) diff --git a/src/events/message.js b/src/events/message.js index de96009..4d41e8e 100644 --- a/src/events/message.js +++ b/src/events/message.js @@ -6,85 +6,60 @@ * */ -const Discord = require('discord.js'); +const { Collection, MessageEmbed } = require('discord.js'); const ChildLogger = require('leekslazylogger').ChildLogger; const log = new ChildLogger(); const config = require('../../user/config'); -const fs = require('fs'); -const dtf = require('@eartharoid/dtf'); +const archive = require('../utils/archive'); module.exports = { event: 'message', async execute(client, [message], {Ticket, Setting}) { const guild = client.guilds.cache.get(config.guild); - - if (message.author.bot || message.author.id === client.user.id) return; - if (message.channel.type === 'dm') { + if (message.channel.type === 'dm' && !message.author.bot) { log.console(`Received a DM from ${message.author.tag}: ${message.cleanContent}`); return message.channel.send(`Hello there, ${message.author.username}! I am the support bot for **${guild}**. Type \`${config.prefix}new\` on the server to create a new ticket.`); - } + } // stop here if is DM + + /** + * Ticket transcripts + * (bots currently still allowed) + */ + + let ticket = await Ticket.findOne({ where: { channel: message.channel.id } }); + if(ticket) + archive.addMessage(client, message); + + if (message.author.bot || message.author.id === client.user.id) return; // if bot, fuck off + + + /** + * Command handler + * (no bots / self) + */ + + const regex = new RegExp(`^(<@!?${client.user.id}>|\\${config.prefix})\\s*`); + if (!regex.test(message.content)) return; // not a command + + const [, prefix] = message.content.match(regex); + const args = message.content.slice(prefix.length).trim().split(/ +/); + const commandName = args.shift().toLowerCase(); + const command = client.commands.get(commandName) + || client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName)); + + if (!command || commandName === 'none') return; // not an existing command if (message.guild.id !== guild.id) - return message.reply(`This bot can only be used within the "${guild}" server`); - - - - /** - * - * Ticket transcripts - * - */ - let ticket = await Ticket.findOne({ where: { channel: message.channel.id } }); - if(ticket) { - if(config.transcripts.text.enabled) { - let path = `user/transcripts/text/${message.channel.id}.txt`; - let time = dtf('HH:mm:ss n_D MMM YY', message.createdAt), - name = message.author.tag, - msg = message.cleanContent; - let string = `[${time}] [${name}] :> ${msg}`; - fs.appendFileSync(path, string + '\n'); - } - - if(config.transcripts.web.enabled) { - let path = `user/transcripts/raw/${message.channel.id}.log`; - let embeds = []; - for (let embed in message.embeds) - embeds.push(message.embeds[embed].toJSON()); - fs.appendFileSync(path, JSON.stringify({ - id: message.id, - type: 'UNKNOWN', - author: message.author.id, - content: message.content, - // deleted: false, - time: message.createdTimestamp, - embeds: embeds, - attachments: [...message.attachments] - }) + ', \n'); - } - } - - /** - * - * Command handler - * - */ - - const prefixRegex = new RegExp(`^(<@!?${client.user.id}>|\\${config.prefix})\\s*`); - if (!prefixRegex.test(message.content)) return; - const [, matchedPrefix] = message.content.match(prefixRegex); - const args = message.content.slice(matchedPrefix.length).trim().split(/ +/); - const commandName = args.shift().toLowerCase(); - const command = client.commands.get(commandName) || client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName)); - if (!command || commandName === 'none') return; + return message.reply(`This bot can only be used within the "${guild}" server`); // not in this server if (command.permission && !message.member.hasPermission(command.permission)) { log.console(`${message.author.tag} tried to use the '${command.name}' command without permission`); return message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setTitle(':x: No permission') .setDescription(`**You do not have permission to use the \`${command.name}\` command** (requires \`${command.permission}\`).`) @@ -94,14 +69,14 @@ Type \`${config.prefix}new\` on the server to create a new ticket.`); if (command.args && !args.length) return message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .addField('Usage', `\`${config.prefix}${command.name} ${command.usage}\`\n`) .addField('Help', `Type \`${config.prefix}help ${command.name}\` for more information`) .setFooter(guild.name, guild.iconURL()) ); - if (!client.cooldowns.has(command.name)) client.cooldowns.set(command.name, new Discord.Collection()); + if (!client.cooldowns.has(command.name)) client.cooldowns.set(command.name, new Collection()); const now = Date.now(); const timestamps = client.cooldowns.get(command.name); @@ -114,7 +89,7 @@ Type \`${config.prefix}new\` on the server to create a new ticket.`); const timeLeft = (expirationTime - now) / 1000; log.console(`${message.author.tag} attempted to use the '${command.name}' command before the cooldown was over`); return message.channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setDescription(`:x: Please wait ${timeLeft.toFixed(1)} second(s) before reusing the \`${command.name}\` command.`) .setFooter(guild.name, guild.iconURL()) @@ -131,7 +106,7 @@ Type \`${config.prefix}new\` on the server to create a new ticket.`); } catch (error) { log.warn(`An error occurred whilst executing the '${command.name}' command`); log.error(error); - message.channel.send(`:x: An error occurred whilst executing the \`${command.name}\` command.\nThe issue has been reported.`); + message.channel.send(`:x: An error occurred whilst executing the \`${command.name}\` command.`); } } }; \ No newline at end of file diff --git a/src/events/messageDelete.js b/src/events/messageDelete.js new file mode 100644 index 0000000..893d966 --- /dev/null +++ b/src/events/messageDelete.js @@ -0,0 +1,50 @@ +/** + * + * @name DiscordTickets + * @author eartharoid + * @license GNU-GPLv3 + * + */ + +const Discord = require('discord.js'); +const ChildLogger = require('leekslazylogger').ChildLogger; +const log = new ChildLogger(); +const config = require('../../user/config'); +const fs = require('fs'); +const dtf = require('@eartharoid/dtf'); + +module.exports = { + event: 'messageDelete', + async execute(client, [message], {Ticket}) { + + if(!config.transcripts.web.enabled) return; + + if (message.partial) + try { + await message.fetch(); + } catch (err) { + log.error(err); + return; + } + + let ticket = await Ticket.findOne({ where: { channel: message.channel.id } }); + if(!ticket) return; + + + let path = `user/transcripts/raw/${message.channel.id}.log`; + let embeds = []; + for (let embed in message.embeds) + embeds.push(message.embeds[embed].toJSON()); + + fs.appendFileSync(path, JSON.stringify({ + id: message.id, + author: message.author.id, + content: message.content, // do not use cleanContent! + time: message.createdTimestamp, + embeds: embeds, + attachments: [...message.attachments.values()], + deleted: true + }) + '\n'); + + } +}; \ No newline at end of file diff --git a/src/events/messageReactionAdd.js b/src/events/messageReactionAdd.js index 6db382f..e77a1c4 100644 --- a/src/events/messageReactionAdd.js +++ b/src/events/messageReactionAdd.js @@ -8,7 +8,7 @@ const ChildLogger = require('leekslazylogger').ChildLogger; const log = new ChildLogger(); -const Discord = require('discord.js'); +const { MessageEmbed } = require('discord.js'); const config = require('../../user/config'); const fs = require('fs'); @@ -36,7 +36,7 @@ module.exports = { const supportRole = channel.guild.roles.cache.get(config.staff_role); if (!supportRole) return channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setTitle(':x: **Error**') .setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``) @@ -68,7 +68,7 @@ module.exports = { try { return dm.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setAuthor(u.username, u.displayAvatarURL()) .setTitle(`:x: **You already have ${tickets.count} or more open tickets**`) @@ -80,7 +80,7 @@ module.exports = { } catch (e) { let m = await channel.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.err_colour) .setAuthor(u.username, u.displayAvatarURL()) .setTitle(`:x: **You already have ${tickets.count} or more open tickets**`) @@ -166,7 +166,7 @@ module.exports = { let w = await c.send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(u.username, u.displayAvatarURL()) .setDescription(text) @@ -180,7 +180,7 @@ module.exports = { if (config.logs.discord.enabled) client.channels.cache.get(config.logs.discord.channel).send( - new Discord.MessageEmbed() + new MessageEmbed() .setColor(config.colour) .setAuthor(u.username, u.displayAvatarURL()) .setTitle('New ticket (via panel)') diff --git a/src/events/messageUpdate.js b/src/events/messageUpdate.js index 6705f93..f765e7b 100644 --- a/src/events/messageUpdate.js +++ b/src/events/messageUpdate.js @@ -14,14 +14,47 @@ const fs = require('fs'); const dtf = require('@eartharoid/dtf'); module.exports = { - event: 'messageUpdate', - async execute(client, [o, n], {Ticket, Setting}) { - /** - * CHECK IF O === N - */ - console.log(o.author.tag); - // https://discord.js.org/#/docs/main/stable/class/Client?scrollTo=e-messageUpdate - // append new to raw + event: 'oUpdate', + async execute(client, [o, n], {Ticket}) { + + if(!config.transcripts.web.enabled) return; + + if (o.partial) + try { + await o.fetch(); + } catch (err) { + log.error(err); + return; + } + + if (n.partial) + try { + await o.fetch(); + } catch (err) { + log.error(err); + return; + } + + if(o === n) return; + + let ticket = await Ticket.findOne({ where: { channel: o.channel.id } }); + if(!ticket) return; + + let path = `user/transcripts/raw/${o.channel.id}.log`; + let embeds = []; + for (let embed in o.embeds) + embeds.push(o.embeds[embed].toJSON()); + + fs.appendFileSync(path, JSON.stringify({ + id: o.id, + author: o.author.id, + content: o.content, // do not use cleanContent! + time: o.createdTimestamp, + embeds: embeds, + attachments: [...o.attachments.values()], + edited: true + }) + '\n'); + } }; \ No newline at end of file diff --git a/src/index.js b/src/index.js index f4305ae..16e3366 100644 --- a/src/index.js +++ b/src/index.js @@ -12,7 +12,7 @@ const fs = require('fs'); const leeks = require('leeks.js'); const client = new Discord.Client({ autoReconnect: true, - partials: ['MESSAGE', 'CHANNEL', 'REACTION'] + partials: ['MESSAGE', 'CHANNEL', 'REACTION'], }); client.events = new Discord.Collection(); client.commands = new Discord.Collection(); diff --git a/src/utils/archive.js b/src/utils/archive.js index b022425..f81869e 100644 --- a/src/utils/archive.js +++ b/src/utils/archive.js @@ -10,6 +10,7 @@ const ChildLogger = require('leekslazylogger').ChildLogger; const log = new ChildLogger(); const lineReader = require('line-reader'); const fs = require('fs'); +const dtf = require('@eartharoid/dtf'); const config = require('../../user/config'); module.exports.create = (client, channel) => { @@ -27,24 +28,73 @@ module.exports.create = (client, channel) => { }; -module.exports.addMessage = (client, channel, message) => { - // if !entities.users.user, add +module.exports.addMessage = async (client, message) => { + + if(config.transcripts.text.enabled) { // text transcripts + let path = `user/transcripts/text/${message.channel.id}.txt`, + time = dtf('HH:mm:ss n_D MMM YY', message.createdAt), + msg = message.cleanContent; + message.attachments.each(a => msg += '\n' + a.url); + let string = `[${time}] [${message.author.tag}] :> ${msg}`; + fs.appendFileSync(path, string + '\n'); + } + + if(config.transcripts.web.enabled) { // web archives + let raw = `user/transcripts/raw/${message.channel.id}.log`, + json = `user/transcripts/raw/entities/${message.channel.id}.json`; + + let embeds = []; + for (let embed in message.embeds) + embeds.push(message.embeds[embed].toJSON()); + + // message + fs.appendFileSync(raw, JSON.stringify({ + id: message.id, + author: message.author.id, + content: message.content, // do not use cleanContent! + time: message.createdTimestamp, + embeds: embeds, + attachments: [...message.attachments.values()] + }) + '\n'); + + // channel entities + if(!fs.existsSync(json)) + await fs.writeFileSync(json, '{}'); + + let entities = await JSON.parse(fs.readFileSync(json)); + + if(!entities.users[message.author.id]) { + entities.users[message.author.id] = { + avatar: message.author.avatarURL(), + username: message.author.username, + discriminator: message.author.discriminator, + displayName: message.member.displayName, + color: message.member.displayColor, + badge: message.author.bot ? 'bot' : null + }; + } + + message.mentions.channels.each(c => entities.channels[c.id].name = c.name); + + message.mentions.roles.each(r => entities.roles[r.id] = { + name: r.name, + color: r.color + }); + + } }; module.exports.export = (client, channel) => { let path = `user/transcripts/raw/${channel.id}.log`; - if(config.transcripts.web.enabled && fs.existsSync(path)) { + + return new Promise((resolve, reject) => { + if(!config.transcripts.web.enabled || !fs.existsSync(path)) + return reject(false); + lineReader.eachLine(path, (line, last) => { console.log(line); - //if raw id exists, overwrite previous + // if raw id exists, overwrite previous + // also: channel_name }); - } - - - - - /** - * @TODO users, roles, etc - * check channel.members again! - * */ + }); }; \ No newline at end of file diff --git a/src/utils/panel.js b/src/utils/panel.js deleted file mode 100644 index c705a7a..0000000 --- a/src/utils/panel.js +++ /dev/null @@ -1,180 +0,0 @@ -/** - * - * @name DiscordTickets - * @author eartharoid - * @license GNU-GPLv3 - * - */ - -const ChildLogger = require('leekslazylogger').ChildLogger; -const log = new ChildLogger(); -const Discord = require('discord.js'); -const fs = require('fs'); -const config = require('../../user/config'); - -module.exports = async (client, Ticket, Setting) => { - - let panelID = await Setting.findOne({ where: { key: 'panel_msg_id' } }); - if (!panelID) return; - - let chanID = await Setting.findOne({ where: { key: 'panel_chan_id' } }); - if (!chanID) return; - - let channel = client.channels.cache.get(chanID.get('value')); - if (!channel) - return Setting.destroy({ where: { key: 'panel_chan_id' } }); - - let panel = channel.messages.cache.get(panelID.get('value')); - if(!panel) - return Setting.destroy({ where: { key: 'panel_msg_id' } }); - - - const collector = panel.createReactionCollector( - (r, u) => r.emoji.name === config.panel.reaction && u.id !== client.user.id); - - collector.on('collect', async (r, u) => { - await r.users.remove(u.id); // effectively cancel reaction - - const supportRole = channel.guild.roles.cache.get(config.staff_role); - if (!supportRole) - return channel.send( - new Discord.MessageEmbed() - .setColor(config.err_colour) - .setTitle(':x: **Error**') - .setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``) - .setFooter(channel.guild.name, channel.guild.iconURL()) - ); - - let tickets = await Ticket.findAndCountAll({ - where: { - creator: u.id, - open: true - }, - limit: config.tickets.max - }); - - if (tickets.count >= config.tickets.max) { - let ticketList = []; - for (let t in tickets.rows) { - let desc = tickets.rows[t].topic.substring(0, 30); - ticketList - .push(`<#${tickets.rows[t].channel}>: \`${desc}${desc.length > 30 ? '...' : ''}\``); - } - let dm = u.dmChannel || await u.createDM(); - - let m = await dm.send( - new Discord.MessageEmbed() - .setColor(config.err_colour) - .setAuthor(u.username, u.displayAvatarURL()) - .setTitle(`:x: **You already have ${tickets.count} or more open tickets**`) - .setDescription(`Use \`${config.prefix}close\` to close unneeded tickets.\n\n${ticketList.join(',\n')}`) - .setFooter(channel.guild.name + ' | This message will be deleted in 15 seconds', channel.guild.iconURL()) - ); - - return m.delete({ timeout: 15000 }); - } - - let topic = 'No topic given (created via panel)'; - - let ticket = await Ticket.create({ - channel: '', - creator: u.id, - open: true, - archived: false, - topic: topic - }); - - let name = 'ticket-' + ticket.get('id'); - - channel.guild.channels.create(name, { - type: 'text', - topic: `${u} | ${topic}`, - parent: config.tickets.category, - permissionOverwrites: [{ - id: channel.guild.roles.everyone, - deny: ['VIEW_CHANNEL', 'SEND_MESSAGES'] - }, - { - id: channel.guild.member(u), - allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY'] - }, - { - id: supportRole, - allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY'] - } - ], - reason: 'User requested a new support ticket channel' - }).then(async c => { - - Ticket.update({ - channel: c.id - }, { - where: { - id: ticket.id - } - }); - - let ping; - switch (config.tickets.ping) { - case 'staff': - ping = `<@&${config.staff_role}>,\n`; - break; - case false: - ping = ''; - break; - default: - ping = `@${config.tickets.ping},\n`; - } - - await c.send(ping + `${u} has created a new ticket`); - - if (config.tickets.send_img) { - const images = fs.readdirSync('user/images'); - await c.send({ - files: [ - 'user/images/' + - images[Math.floor(Math.random() * images.length)] - ] - }); - } - - let text = config.tickets.text - .replace('{{ name }}', u.username) - .replace('{{ tag }}', u); - - - let w = await c.send( - new Discord.MessageEmbed() - .setColor(config.colour) - .setAuthor(u.username, u.displayAvatarURL()) - .setDescription(text) - .addField('Topic', `\`${topic}\``) - .setFooter(channel.guild.name, channel.guild.iconURL()) - ); - - if (config.tickets.pin) - await w.pin(); - // await w.pin().then(m => m.delete()); // oopsie, this deletes the pinned message - - if (config.logs.discord.enabled) - client.channels.cache.get(config.logs.discord.channel).send( - new Discord.MessageEmbed() - .setColor(config.colour) - .setAuthor(u.username, u.displayAvatarURL()) - .setTitle('New ticket (via panel)') - .setDescription(`\`${topic}\``) - .addField('Creator', u, true) - .addField('Channel', c, true) - .setFooter(channel.guild.name, channel.guild.iconURL()) - .setTimestamp() - ); - - log.info(`${u.tag} created a new ticket (#${name}) via panel`); - - - }).catch(log.error); - - - }); - -}; \ No newline at end of file diff --git a/user/config.js b/user/config.js index c3c0a86..9928f9b 100644 --- a/user/config.js +++ b/user/config.js @@ -11,7 +11,7 @@ * --------------------- * * > For detailed instructions, visit the GitHub repository and read the documentation: - * https://github.com/eartharoid/DiscordTickets/#readme + * https://github.com/eartharoid/DiscordTickets/wiki * * > IMPORTANT: Also rename 'user/example.env' to 'user/.env' and edit the TOKEN * @@ -33,6 +33,7 @@ module.exports = { activity_types: ['PLAYING', 'PLAYING', 'WATCHING'], /** @INFO paired */ colour: '#009999', err_colour: '#E74C3C', + cooldown: 3, guild: '451745464480432129', // ID of your guild staff_role: '451745586564169728', // ID of your Support Team role @@ -50,7 +51,7 @@ module.exports = { transcripts: { text: { - enabled: true, + enabled: false, keep_for: 90, }, web: { diff --git a/user/transcripts/raw/entities/.gitkeep b/user/transcripts/raw/entities/.gitkeep new file mode 100644 index 0000000..e69de29