mirror of
https://github.com/Hessenuk/DiscordTickets.git
synced 2024-09-12 15:54:47 +03:00
commit
4b10e483a9
@ -32,6 +32,9 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
'no-control-regex': [
|
'no-control-regex': [
|
||||||
'off'
|
'off'
|
||||||
|
],
|
||||||
|
'no-console': [
|
||||||
|
'off'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -9,10 +9,10 @@ DiscordTickets is a Discord bot for managing support ticket channels, to allow y
|
|||||||
- Highly customisable
|
- Highly customisable
|
||||||
- Ticket "panel" / "widget" (react to embed to create ticket)
|
- Ticket "panel" / "widget" (react to embed to create ticket)
|
||||||
- Simple commands
|
- Simple commands
|
||||||
- SQLite (easy, default) **or** MySQL (recommend) storage
|
- Supports multiple databases: SQLite (easy, default), MySQL (recommend) storage, MariaDB, PostgresSQL and Microsoft SQL Server
|
||||||
- Most (all of the best) features of the premium bots, for free
|
- Most (all of the best) features of the premium bots, for free
|
||||||
- Self-hosted with your bot application, your logo and guild name
|
- Self-hosted with your bot application, your logo and guild name
|
||||||
- Optional express.js server for web archvies: [DiscordTickets-Portal](https://github.com/eartharoid/DiscordTickets-Portal/)
|
- Optional express.js server for web archives: [DiscordTickets-Portal](https://github.com/eartharoid/DiscordTickets-Portal/)
|
||||||
|
|
||||||
## Screenshot
|
## Screenshot
|
||||||
|
|
||||||
@ -31,4 +31,4 @@ For installation, configuration, usage, and other information, **go to the [wiki
|
|||||||
|
|
||||||
## Donate
|
## Donate
|
||||||
|
|
||||||
[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/B0B214BHI)
|
[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/eartharoid)
|
||||||
|
@ -19,7 +19,10 @@
|
|||||||
"sqlite3": "^5.0.0"
|
"sqlite3": "^5.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"mysql2": "2.x"
|
"mysql2": "2.x",
|
||||||
|
"mariadb": "2.x",
|
||||||
|
"pg": "8.x",
|
||||||
|
"tedious": "9.x"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^7.10.0",
|
"eslint": "^7.10.0",
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { MessageEmbed } = require('discord.js');
|
const { MessageEmbed } = require('discord.js');
|
||||||
@ -18,7 +18,6 @@ module.exports = {
|
|||||||
example: 'add @member to #ticket-23',
|
example: 'add @member to #ticket-23',
|
||||||
args: true,
|
args: true,
|
||||||
async execute(client, message, args, {config, Ticket}) {
|
async execute(client, message, args, {config, Ticket}) {
|
||||||
|
|
||||||
const guild = client.guilds.cache.get(config.guild);
|
const guild = client.guilds.cache.get(config.guild);
|
||||||
|
|
||||||
const notTicket = new MessageEmbed()
|
const notTicket = new MessageEmbed()
|
||||||
@ -34,17 +33,14 @@ module.exports = {
|
|||||||
|
|
||||||
let channel = message.mentions.channels.first();
|
let channel = message.mentions.channels.first();
|
||||||
|
|
||||||
if(!channel) {
|
if (!channel) {
|
||||||
|
|
||||||
channel = message.channel;
|
channel = message.channel;
|
||||||
ticket = await Ticket.findOne({ where: { channel: message.channel.id } });
|
ticket = await Ticket.findOne({ where: { channel: message.channel.id } });
|
||||||
if(!ticket)
|
if (!ticket) return message.channel.send(notTicket);
|
||||||
return message.channel.send(notTicket);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ticket = await Ticket.findOne({ where: { channel: channel.id } });
|
ticket = await Ticket.findOne({ where: { channel: channel.id } });
|
||||||
if(!ticket) {
|
if (!ticket) {
|
||||||
notTicket
|
notTicket
|
||||||
.setTitle(':x: **Channel is not a ticket**')
|
.setTitle(':x: **Channel is not a ticket**')
|
||||||
.setDescription(`${channel} is not a ticket channel.`);
|
.setDescription(`${channel} is not a ticket channel.`);
|
||||||
@ -52,7 +48,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(message.author.id !== ticket.creator && !message.member.roles.cache.has(config.staff_role))
|
if (message.author.id !== ticket.creator && !message.member.roles.cache.has(config.staff_role)) {
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -63,12 +59,11 @@ module.exports = {
|
|||||||
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
|
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
let member = guild.member(message.mentions.users.first() || guild.members.cache.get(args[0]));
|
let member = guild.member(message.mentions.users.first() || guild.members.cache.get(args[0]));
|
||||||
|
|
||||||
if(!member)
|
if (!member) {
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -79,6 +74,7 @@ module.exports = {
|
|||||||
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
|
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
channel.updateOverwrite(member.user, {
|
channel.updateOverwrite(member.user, {
|
||||||
@ -88,7 +84,7 @@ module.exports = {
|
|||||||
READ_MESSAGE_HISTORY: true
|
READ_MESSAGE_HISTORY: true
|
||||||
});
|
});
|
||||||
|
|
||||||
if(channel.id !== message.channel.id)
|
if (channel.id !== message.channel.id) {
|
||||||
channel.send(
|
channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.colour)
|
.setColor(config.colour)
|
||||||
@ -97,9 +93,8 @@ module.exports = {
|
|||||||
.setDescription(`${member} has been added by ${message.author}`)
|
.setDescription(`${member} has been added by ${message.author}`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
message.channel.send(
|
message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.colour)
|
.setColor(config.colour)
|
||||||
@ -108,7 +103,7 @@ module.exports = {
|
|||||||
.setDescription(`${member} has been added to <#${ticket.channel}>`)
|
.setDescription(`${member} has been added to <#${ticket.channel}>`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
|
||||||
log.info(`${message.author.tag} added a user to a ticket (#${message.channel.id})`);
|
log.info(`${message.author.tag} added a user to a ticket (#${message.channel.id})`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -21,11 +21,7 @@ module.exports = {
|
|||||||
aliases: ['none'],
|
aliases: ['none'],
|
||||||
example: 'close #ticket-17',
|
example: 'close #ticket-17',
|
||||||
args: false,
|
args: false,
|
||||||
async execute(client, message, args, {
|
async execute(client, message, args, { config, Ticket }) {
|
||||||
config,
|
|
||||||
Ticket
|
|
||||||
}) {
|
|
||||||
|
|
||||||
const guild = client.guilds.cache.get(config.guild);
|
const guild = client.guilds.cache.get(config.guild);
|
||||||
|
|
||||||
const notTicket = new MessageEmbed()
|
const notTicket = new MessageEmbed()
|
||||||
@ -49,11 +45,8 @@ module.exports = {
|
|||||||
channel: channel.id
|
channel: channel.id
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!ticket)
|
if (!ticket) return channel.send(notTicket);
|
||||||
return channel.send(notTicket);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ticket = await Ticket.findOne({
|
ticket = await Ticket.findOne({
|
||||||
where: {
|
where: {
|
||||||
channel: channel.id
|
channel: channel.id
|
||||||
@ -102,7 +95,7 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
collector.on('collect', async () => {
|
collector.on('collect', async () => {
|
||||||
if (channel.id !== message.channel.id)
|
if (channel.id !== message.channel.id) {
|
||||||
channel.send(
|
channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.colour)
|
.setColor(config.colour)
|
||||||
@ -111,6 +104,7 @@ module.exports = {
|
|||||||
.setDescription(`Ticket closed by ${message.author}`)
|
.setDescription(`Ticket closed by ${message.author}`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
confirm.reactions.removeAll();
|
confirm.reactions.removeAll();
|
||||||
confirm.edit(
|
confirm.edit(
|
||||||
@ -149,16 +143,13 @@ module.exports = {
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (fs.existsSync(`user/transcripts/raw/${ticket.get('channel')}.log`) && fs.existsSync(`user/transcripts/raw/entities/${ticket.get('channel')}.json`)) {
|
||||||
fs.existsSync(`user/transcripts/raw/${ticket.get('channel')}.log`)
|
|
||||||
&&
|
|
||||||
fs.existsSync(`user/transcripts/raw/entities/${ticket.get('channel')}.json`)
|
|
||||||
)
|
|
||||||
embed.addField('Web archive', await archive.export(Ticket, channel));
|
embed.addField('Web archive', await archive.export(Ticket, channel));
|
||||||
|
}
|
||||||
|
|
||||||
if (embed.fields.length < 1)
|
if (embed.fields.length < 1) {
|
||||||
embed.setDescription(`No text transcripts or archive data exists for ticket ${ticket.id}`);
|
embed.setDescription(`No text transcripts or archive data exists for ticket ${ticket.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
res.embed = embed;
|
res.embed = embed;
|
||||||
|
|
||||||
@ -166,7 +157,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// update database
|
// update database
|
||||||
success = true;
|
success = true;
|
||||||
ticket.update({
|
ticket.update({
|
||||||
@ -187,7 +177,7 @@ module.exports = {
|
|||||||
|
|
||||||
log.info(`${message.author.tag} closed a ticket (#ticket-${ticket.id})`);
|
log.info(`${message.author.tag} closed a ticket (#ticket-${ticket.id})`);
|
||||||
|
|
||||||
if (config.logs.discord.enabled)
|
if (config.logs.discord.enabled) {
|
||||||
client.channels.cache.get(config.logs.discord.channel).send(
|
client.channels.cache.get(config.logs.discord.channel).send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.colour)
|
.setColor(config.colour)
|
||||||
@ -198,6 +188,7 @@ module.exports = {
|
|||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
.setTimestamp()
|
.setTimestamp()
|
||||||
);
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -24,7 +24,6 @@ module.exports = {
|
|||||||
config,
|
config,
|
||||||
Ticket
|
Ticket
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
const guild = client.guilds.cache.get(config.guild);
|
const guild = client.guilds.cache.get(config.guild);
|
||||||
|
|
||||||
const notTicket = new MessageEmbed()
|
const notTicket = new MessageEmbed()
|
||||||
@ -48,11 +47,9 @@ module.exports = {
|
|||||||
channel: channel.id
|
channel: channel.id
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!ticket)
|
if (!ticket) return channel.send(notTicket);
|
||||||
return channel.send(notTicket);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ticket = await Ticket.findOne({
|
ticket = await Ticket.findOne({
|
||||||
where: {
|
where: {
|
||||||
channel: channel.id
|
channel: channel.id
|
||||||
@ -65,7 +62,7 @@ module.exports = {
|
|||||||
return message.channel.send(notTicket);
|
return message.channel.send(notTicket);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.author.id !== ticket.creator && !message.member.roles.cache.has(config.staff_role))
|
if (message.author.id !== ticket.creator && !message.member.roles.cache.has(config.staff_role)) {
|
||||||
return channel.send(
|
return channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -76,6 +73,7 @@ module.exports = {
|
|||||||
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
|
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let success;
|
let success;
|
||||||
@ -124,14 +122,9 @@ module.exports = {
|
|||||||
raw = `user/transcripts/raw/${ticket.get('channel')}.log`,
|
raw = `user/transcripts/raw/${ticket.get('channel')}.log`,
|
||||||
json = `user/transcripts/raw/entities/${ticket.get('channel')}.json`;
|
json = `user/transcripts/raw/entities/${ticket.get('channel')}.json`;
|
||||||
|
|
||||||
if (fs.existsSync(txt))
|
if (fs.existsSync(txt)) fs.unlinkSync(txt);
|
||||||
fs.unlinkSync(txt);
|
if (fs.existsSync(raw)) fs.unlinkSync(raw);
|
||||||
|
if (fs.existsSync(json)) fs.unlinkSync(json);
|
||||||
if (fs.existsSync(raw))
|
|
||||||
fs.unlinkSync(raw);
|
|
||||||
|
|
||||||
if (fs.existsSync(json))
|
|
||||||
fs.unlinkSync(json);
|
|
||||||
|
|
||||||
// update database
|
// update database
|
||||||
success = true;
|
success = true;
|
||||||
@ -147,7 +140,7 @@ module.exports = {
|
|||||||
|
|
||||||
log.info(`${message.author.tag} deleted a ticket (#ticket-${ticket.id})`);
|
log.info(`${message.author.tag} deleted a ticket (#ticket-${ticket.id})`);
|
||||||
|
|
||||||
if (config.logs.discord.enabled)
|
if (config.logs.discord.enabled) {
|
||||||
client.channels.cache.get(config.logs.discord.channel).send(
|
client.channels.cache.get(config.logs.discord.channel).send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.colour)
|
.setColor(config.colour)
|
||||||
@ -158,6 +151,7 @@ module.exports = {
|
|||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
.setTimestamp()
|
.setTimestamp()
|
||||||
);
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -18,27 +18,23 @@ module.exports = {
|
|||||||
example: 'help new',
|
example: 'help new',
|
||||||
args: false,
|
args: false,
|
||||||
execute(client, message, args, {config}) {
|
execute(client, message, args, {config}) {
|
||||||
|
|
||||||
const guild = client.guilds.cache.get(config.guild);
|
const guild = client.guilds.cache.get(config.guild);
|
||||||
|
|
||||||
const commands = Array.from(client.commands.values());
|
const commands = Array.from(client.commands.values());
|
||||||
|
|
||||||
if (!args.length) {
|
if (!args.length) {
|
||||||
let cmds = [];
|
let cmds = [];
|
||||||
|
|
||||||
for (let command of commands) {
|
for (let command of commands) {
|
||||||
if (command.hide)
|
if (command.hide) continue;
|
||||||
continue;
|
if (command.permission && !message.member.hasPermission(command.permission)) continue;
|
||||||
if (command.permission && !message.member.hasPermission(command.permission))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
let desc = command.description;
|
let desc = command.description;
|
||||||
|
|
||||||
if (desc.length > 50)
|
if (desc.length > 50) desc = desc.substring(0, 50) + '...';
|
||||||
desc = desc.substring(0, 50) + '...';
|
|
||||||
cmds.push(`**${config.prefix}${command.name}** **·** ${desc}`);
|
cmds.push(`**${config.prefix}${command.name}** **·** ${desc}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
message.channel.send(
|
message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setTitle('Commands')
|
.setTitle('Commands')
|
||||||
@ -58,24 +54,22 @@ module.exports = {
|
|||||||
const name = args[0].toLowerCase();
|
const name = args[0].toLowerCase();
|
||||||
const command = client.commands.get(name) || client.commands.find(c => c.aliases && c.aliases.includes(name));
|
const command = client.commands.get(name) || client.commands.find(c => c.aliases && c.aliases.includes(name));
|
||||||
|
|
||||||
if (!command)
|
if (!command)
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
.setDescription(`:x: **Invalid command name** (\`${config.prefix}help\`)`)
|
.setDescription(`:x: **Invalid command name** (\`${config.prefix}help\`)`)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const cmd = new MessageEmbed()
|
const cmd = new MessageEmbed()
|
||||||
.setColor(config.colour)
|
.setColor(config.colour)
|
||||||
.setTitle(command.name);
|
.setTitle(command.name);
|
||||||
|
|
||||||
|
|
||||||
if (command.long) {
|
if (command.long) cmd.setDescription(command.long);
|
||||||
cmd.setDescription(command.long);
|
else cmd.setDescription(command.description);
|
||||||
} else {
|
|
||||||
cmd.setDescription(command.description);
|
|
||||||
}
|
|
||||||
if (command.aliases) cmd.addField('Aliases', `\`${command.aliases.join(', ')}\``, true);
|
if (command.aliases) cmd.addField('Aliases', `\`${command.aliases.join(', ')}\``, true);
|
||||||
|
|
||||||
if (command.usage) cmd.addField('Usage', `\`${config.prefix}${command.name} ${command.usage}\``, false);
|
if (command.usage) cmd.addField('Usage', `\`${config.prefix}${command.name} ${command.usage}\``, false);
|
||||||
@ -85,12 +79,9 @@ module.exports = {
|
|||||||
|
|
||||||
if (command.permission && !message.member.hasPermission(command.permission)) {
|
if (command.permission && !message.member.hasPermission(command.permission)) {
|
||||||
cmd.addField('Required Permission', `\`${command.permission}\` :exclamation: You don't have permission to use this command`, true);
|
cmd.addField('Required Permission', `\`${command.permission}\` :exclamation: You don't have permission to use this command`, true);
|
||||||
} else {
|
} else cmd.addField('Required Permission', `\`${command.permission || 'none'}\``, true);
|
||||||
cmd.addField('Required Permission', `\`${command.permission || 'none'}\``, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
message.channel.send(cmd);
|
|
||||||
|
|
||||||
|
message.channel.send(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// command ends here
|
// command ends here
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -19,9 +19,8 @@ module.exports = {
|
|||||||
example: 'new my server won\'t start',
|
example: 'new my server won\'t start',
|
||||||
args: false,
|
args: false,
|
||||||
async execute(client, message, args, {config, Ticket}) {
|
async execute(client, message, args, {config, Ticket}) {
|
||||||
|
|
||||||
const guild = client.guilds.cache.get(config.guild);
|
const guild = client.guilds.cache.get(config.guild);
|
||||||
|
|
||||||
const supportRole = guild.roles.cache.get(config.staff_role);
|
const supportRole = guild.roles.cache.get(config.staff_role);
|
||||||
if (!supportRole)
|
if (!supportRole)
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
@ -43,12 +42,12 @@ module.exports = {
|
|||||||
|
|
||||||
if (tickets.count >= config.tickets.max) {
|
if (tickets.count >= config.tickets.max) {
|
||||||
let ticketList = [];
|
let ticketList = [];
|
||||||
for (let t in tickets.rows) {
|
for (let t in tickets.rows) {
|
||||||
let desc = tickets.rows[t].topic.substring(0, 30);
|
let desc = tickets.rows[t].topic.substring(0, 30);
|
||||||
ticketList
|
ticketList
|
||||||
.push(`<#${tickets.rows[t].channel}>: \`${desc}${desc.length > 30 ? '...' : ''}\``);
|
.push(`<#${tickets.rows[t].channel}>: \`${desc}${desc.length > 30 ? '...' : ''}\``);
|
||||||
}
|
}
|
||||||
|
|
||||||
let m = await message.channel.send(
|
let m = await message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -63,7 +62,7 @@ module.exports = {
|
|||||||
await m.delete();
|
await m.delete();
|
||||||
}, 15000);
|
}, 15000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let topic = args.join(' ');
|
let topic = args.join(' ');
|
||||||
if (topic.length > 256)
|
if (topic.length > 256)
|
||||||
@ -75,9 +74,7 @@ module.exports = {
|
|||||||
.setDescription('Please limit your ticket topic to less than 256 characters. A short sentence will do.')
|
.setDescription('Please limit your ticket topic to less than 256 characters. A short sentence will do.')
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
else if (topic.length < 1)
|
else if (topic.length < 1) topic = 'No topic given';
|
||||||
topic = 'No topic given';
|
|
||||||
|
|
||||||
|
|
||||||
let ticket = await Ticket.create({
|
let ticket = await Ticket.create({
|
||||||
channel: '',
|
channel: '',
|
||||||
@ -100,7 +97,7 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
id: client.user,
|
id: client.user,
|
||||||
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY']
|
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: message.member,
|
id: message.member,
|
||||||
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY']
|
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY']
|
||||||
@ -134,7 +131,7 @@ module.exports = {
|
|||||||
await message.delete();
|
await message.delete();
|
||||||
await m.delete();
|
await m.delete();
|
||||||
}, 15000);
|
}, 15000);
|
||||||
|
|
||||||
// require('../modules/archive').create(client, c); // create files
|
// require('../modules/archive').create(client, c); // create files
|
||||||
|
|
||||||
let ping;
|
let ping;
|
||||||
@ -175,9 +172,8 @@ module.exports = {
|
|||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
|
||||||
if (config.tickets.pin)
|
if (config.tickets.pin) await w.pin();
|
||||||
await w.pin();
|
// await w.pin().then(m => m.delete()); // oopsie, this deletes the pinned message
|
||||||
// await w.pin().then(m => m.delete()); // oopsie, this deletes the pinned message
|
|
||||||
|
|
||||||
if (config.logs.discord.enabled)
|
if (config.logs.discord.enabled)
|
||||||
client.channels.cache.get(config.logs.discord.channel).send(
|
client.channels.cache.get(config.logs.discord.channel).send(
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -18,21 +18,21 @@ module.exports = {
|
|||||||
example: '',
|
example: '',
|
||||||
args: false,
|
args: false,
|
||||||
permission: 'MANAGE_GUILD',
|
permission: 'MANAGE_GUILD',
|
||||||
async execute(client, message, args, {config, Setting}) {
|
async execute(client, message, _args, {config, Setting}) {
|
||||||
|
|
||||||
const guild = client.guilds.cache.get(config.guild);
|
const guild = client.guilds.cache.get(config.guild);
|
||||||
|
|
||||||
let msgID = await Setting.findOne({ where: { key: 'panel_msg_id' } });
|
let msgID = await Setting.findOne({ where: { key: 'panel_msg_id' } });
|
||||||
let chanID = await Setting.findOne({ where: { key: 'panel_chan_id' } });
|
let chanID = await Setting.findOne({ where: { key: 'panel_chan_id' } });
|
||||||
let panel;
|
let panel;
|
||||||
|
|
||||||
if(!chanID)
|
if (!chanID) {
|
||||||
chanID = await Setting.create({
|
chanID = await Setting.create({
|
||||||
key: 'panel_chan_id',
|
key: 'panel_chan_id',
|
||||||
value: message.channel.id,
|
value: message.channel.id,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if(!msgID) {
|
if (!msgID) {
|
||||||
msgID = await Setting.create({
|
msgID = await Setting.create({
|
||||||
key: 'panel_msg_id',
|
key: 'panel_msg_id',
|
||||||
value: '',
|
value: '',
|
||||||
@ -40,12 +40,12 @@ module.exports = {
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
panel = await client.channels.cache.get(chanID.get('value')).messages.fetch(msgID.get('value')); // get old panel message
|
panel = await client.channels.cache.get(chanID.get('value')).messages.fetch(msgID.get('value')); // get old panel message
|
||||||
if (panel)
|
if (panel) {
|
||||||
panel.delete({ reason: 'Creating new panel/widget' }).then(() => log.info('Deleted old panel')).catch(e => log.warn(e)); // delete old panel
|
panel.delete({ reason: 'Creating new panel/widget' }).then(() => log.info('Deleted old panel')).catch(e => log.warn(e)); // delete old panel
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.warn('Couldn\'t delete old panel');
|
log.warn('Couldn\'t delete old panel');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message.delete();
|
message.delete();
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { MessageEmbed } = require('discord.js');
|
const { MessageEmbed } = require('discord.js');
|
||||||
@ -18,7 +18,6 @@ module.exports = {
|
|||||||
example: 'remove @member from #ticket-23',
|
example: 'remove @member from #ticket-23',
|
||||||
args: true,
|
args: true,
|
||||||
async execute(client, message, args, {config, Ticket}) {
|
async execute(client, message, args, {config, Ticket}) {
|
||||||
|
|
||||||
const guild = client.guilds.cache.get(config.guild);
|
const guild = client.guilds.cache.get(config.guild);
|
||||||
|
|
||||||
const notTicket = new MessageEmbed()
|
const notTicket = new MessageEmbed()
|
||||||
@ -34,17 +33,17 @@ module.exports = {
|
|||||||
|
|
||||||
let channel = message.mentions.channels.first();
|
let channel = message.mentions.channels.first();
|
||||||
|
|
||||||
if(!channel) {
|
if (!channel) {
|
||||||
|
|
||||||
channel = message.channel;
|
channel = message.channel;
|
||||||
ticket = await Ticket.findOne({ where: { channel: message.channel.id } });
|
ticket = await Ticket.findOne({ where: { channel: message.channel.id } });
|
||||||
if(!ticket)
|
if (!ticket)
|
||||||
return message.channel.send(notTicket);
|
return message.channel.send(notTicket);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ticket = await Ticket.findOne({ where: { channel: channel.id } });
|
ticket = await Ticket.findOne({ where: { channel: channel.id } });
|
||||||
if(!ticket) {
|
if (!ticket) {
|
||||||
notTicket
|
notTicket
|
||||||
.setTitle(':x: **Channel is not a ticket**')
|
.setTitle(':x: **Channel is not a ticket**')
|
||||||
.setDescription(`${channel} is not a ticket channel.`);
|
.setDescription(`${channel} is not a ticket channel.`);
|
||||||
@ -52,7 +51,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(message.author.id !== ticket.creator && !message.member.roles.cache.has(config.staff_role))
|
if (message.author.id !== ticket.creator && !message.member.roles.cache.has(config.staff_role)) {
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -63,12 +62,11 @@ module.exports = {
|
|||||||
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
|
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
let member = guild.member(message.mentions.users.first() || guild.members.cache.get(args[0]));
|
let member = guild.member(message.mentions.users.first() || guild.members.cache.get(args[0]));
|
||||||
|
|
||||||
if(!member || member.id === message.author.id || member.id === guild.me.id)
|
if (!member || member.id === message.author.id || member.id === guild.me.id)
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -88,7 +86,7 @@ module.exports = {
|
|||||||
READ_MESSAGE_HISTORY: false
|
READ_MESSAGE_HISTORY: false
|
||||||
});
|
});
|
||||||
|
|
||||||
if(channel.id !== message.channel.id)
|
if (channel.id !== message.channel.id) {
|
||||||
channel.send(
|
channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.colour)
|
.setColor(config.colour)
|
||||||
@ -97,9 +95,8 @@ module.exports = {
|
|||||||
.setDescription(`${member} has been removed by ${message.author}`)
|
.setDescription(`${member} has been removed by ${message.author}`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
message.channel.send(
|
message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.colour)
|
.setColor(config.colour)
|
||||||
@ -108,7 +105,7 @@ module.exports = {
|
|||||||
.setDescription(`${member} has been removed from <#${ticket.channel}>`)
|
.setDescription(`${member} has been removed from <#${ticket.channel}>`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
|
||||||
log.info(`${message.author.tag} removed a user from a ticket (#${message.channel.id})`);
|
log.info(`${message.author.tag} removed a user from a ticket (#${message.channel.id})`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { MessageEmbed } = require('discord.js');
|
const { MessageEmbed } = require('discord.js');
|
||||||
@ -15,8 +15,7 @@ module.exports = {
|
|||||||
aliases: ['data', 'statistics'],
|
aliases: ['data', 'statistics'],
|
||||||
example: '',
|
example: '',
|
||||||
args: false,
|
args: false,
|
||||||
async execute(client, message, args, {config, Ticket}) {
|
async execute(client, message, _args, {config, Ticket}) {
|
||||||
|
|
||||||
const guild = client.guilds.cache.get(config.guild);
|
const guild = client.guilds.cache.get(config.guild);
|
||||||
|
|
||||||
let open = await Ticket.count({ where: { open: true } });
|
let open = await Ticket.count({ where: { open: true } });
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { MessageEmbed } = require('discord.js');
|
const { MessageEmbed } = require('discord.js');
|
||||||
@ -17,11 +17,10 @@ module.exports = {
|
|||||||
example: '',
|
example: '',
|
||||||
args: false,
|
args: false,
|
||||||
async execute(client, message, args, {config, Ticket}) {
|
async execute(client, message, args, {config, Ticket}) {
|
||||||
|
|
||||||
const guild = client.guilds.cache.get(config.guild);
|
const guild = client.guilds.cache.get(config.guild);
|
||||||
|
|
||||||
const supportRole = guild.roles.cache.get(config.staff_role);
|
const supportRole = guild.roles.cache.get(config.staff_role);
|
||||||
if (!supportRole)
|
if (!supportRole) {
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -29,12 +28,13 @@ module.exports = {
|
|||||||
.setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``)
|
.setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let context = 'self';
|
let context = 'self';
|
||||||
let user = message.mentions.users.first() || guild.members.cache.get(args[0]);
|
let user = message.mentions.users.first() || guild.members.cache.get(args[0]);
|
||||||
|
|
||||||
if(user) {
|
if (user) {
|
||||||
if(!message.member.roles.cache.has(config.staff_role))
|
if (!message.member.roles.cache.has(config.staff_role)) {
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -45,12 +45,10 @@ module.exports = {
|
|||||||
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
|
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
context = 'staff';
|
context = 'staff';
|
||||||
} else {
|
} else user = message.author;
|
||||||
user = message.author;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let openTickets = await Ticket.findAndCountAll({
|
let openTickets = await Ticket.findAndCountAll({
|
||||||
where: {
|
where: {
|
||||||
@ -74,33 +72,34 @@ module.exports = {
|
|||||||
.setTitle(`${context === 'self' ? 'Your' : user.username + '\'s'} tickets`)
|
.setTitle(`${context === 'self' ? 'Your' : user.username + '\'s'} tickets`)
|
||||||
.setFooter(guild.name + ' | This message will be deleted in 60 seconds', guild.iconURL());
|
.setFooter(guild.name + ' | This message will be deleted in 60 seconds', guild.iconURL());
|
||||||
|
|
||||||
if(config.transcripts.web.enabled)
|
if (config.transcripts.web.enabled) {
|
||||||
embed.setDescription(`You can access all of your ticket archives on the [web portal](${config.transcripts.web.server}/${user.id}).`);
|
embed.setDescription(`You can access all of your ticket archives on the [web portal](${config.transcripts.web.server}/${user.id}).`);
|
||||||
|
}
|
||||||
|
|
||||||
let open = [],
|
let open = [],
|
||||||
closed = [];
|
closed = [];
|
||||||
|
|
||||||
|
|
||||||
for (let t in openTickets.rows) {
|
for (let t in openTickets.rows) {
|
||||||
let desc = openTickets.rows[t].topic.substring(0, 30);
|
let desc = openTickets.rows[t].topic.substring(0, 30);
|
||||||
open.push(`> <#${openTickets.rows[t].channel}>: \`${desc}${desc.length > 20 ? '...' : ''}\``);
|
open.push(`> <#${openTickets.rows[t].channel}>: \`${desc}${desc.length > 20 ? '...' : ''}\``);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let t in closedTickets.rows) {
|
for (let t in closedTickets.rows) {
|
||||||
let desc = closedTickets.rows[t].topic.substring(0, 30);
|
let desc = closedTickets.rows[t].topic.substring(0, 30);
|
||||||
let transcript = '';
|
let transcript = '';
|
||||||
let c = closedTickets.rows[t].channel;
|
let c = closedTickets.rows[t].channel;
|
||||||
if(fs.existsSync(`user/transcripts/text/${c}.txt`) || config.transcripts.web.enabled)
|
if (fs.existsSync(`user/transcripts/text/${c}.txt`) || config.transcripts.web.enabled) {
|
||||||
transcript = `\n> Type \`${config.prefix}transcript ${closedTickets.rows[t].id}\` to view.`;
|
transcript = `\n> Type \`${config.prefix}transcript ${closedTickets.rows[t].id}\` to view.`;
|
||||||
|
}
|
||||||
|
|
||||||
closed.push(`> **#${closedTickets.rows[t].id}**: \`${desc}${desc.length > 20 ? '...' : ''}\`${transcript}`);
|
closed.push(`> **#${closedTickets.rows[t].id}**: \`${desc}${desc.length > 20 ? '...' : ''}\`${transcript}`);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let pre = context === 'self' ? 'You have' : user.username + ' has';
|
let pre = context === 'self' ? 'You have' : user.username + ' has';
|
||||||
embed.addField('Open tickets', openTickets.count === 0 ? `${pre} no open tickets.` : open.join('\n\n'), false);
|
embed.addField('Open tickets', openTickets.count === 0 ? `${pre} no open tickets.` : open.join('\n\n'), false);
|
||||||
embed.addField('Closed tickets', closedTickets.count === 0 ? `${pre} no old tickets` : closed.join('\n\n'), false);
|
embed.addField('Closed tickets', closedTickets.count === 0 ? `${pre} no old tickets` : closed.join('\n\n'), false);
|
||||||
|
|
||||||
message.delete({timeout: 15000});
|
message.delete({timeout: 15000});
|
||||||
|
|
||||||
let channel;
|
let channel;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { MessageEmbed } = require('discord.js');
|
const { MessageEmbed } = require('discord.js');
|
||||||
@ -16,7 +16,6 @@ module.exports = {
|
|||||||
example: 'topic need help error',
|
example: 'topic need help error',
|
||||||
args: true,
|
args: true,
|
||||||
async execute(client, message, args, {config, Ticket}) {
|
async execute(client, message, args, {config, Ticket}) {
|
||||||
|
|
||||||
const guild = client.guilds.cache.get(config.guild);
|
const guild = client.guilds.cache.get(config.guild);
|
||||||
|
|
||||||
let ticket = await Ticket.findOne({
|
let ticket = await Ticket.findOne({
|
||||||
@ -25,7 +24,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!ticket)
|
if (!ticket) {
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -36,10 +35,10 @@ module.exports = {
|
|||||||
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
|
.addField('Help', `Type \`${config.prefix}help ${this.name}\` for more information`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let topic = args.join(' ');
|
let topic = args.join(' ');
|
||||||
if (topic.length > 256)
|
if (topic.length > 256) {
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -47,10 +46,11 @@ module.exports = {
|
|||||||
.setTitle(':x: **Description too long**')
|
.setTitle(':x: **Description too long**')
|
||||||
.setDescription('Please limit your ticket topic to less than 256 characters. A short sentence will do.')
|
.setDescription('Please limit your ticket topic to less than 256 characters. A short sentence will do.')
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
message.channel.setTopic(`<@${ticket.creator}> | ` + topic);
|
message.channel.setTopic(`<@${ticket.creator}> | ` + topic);
|
||||||
|
|
||||||
Ticket.update({
|
Ticket.update({
|
||||||
topic: topic
|
topic: topic
|
||||||
}, {
|
}, {
|
||||||
@ -59,7 +59,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
message.channel.send(
|
message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.colour)
|
.setColor(config.colour)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
@ -19,7 +19,6 @@ module.exports = {
|
|||||||
example: 'transcript 57',
|
example: 'transcript 57',
|
||||||
args: true,
|
args: true,
|
||||||
async execute(client, message, args, {config, Ticket}) {
|
async execute(client, message, args, {config, Ticket}) {
|
||||||
|
|
||||||
const guild = client.guilds.cache.get(config.guild);
|
const guild = client.guilds.cache.get(config.guild);
|
||||||
const id = args[0];
|
const id = args[0];
|
||||||
|
|
||||||
@ -31,7 +30,7 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (!ticket)
|
if (!ticket) {
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -40,8 +39,9 @@ module.exports = {
|
|||||||
.setDescription('Couldn\'t find a closed ticket with that ID')
|
.setDescription('Couldn\'t find a closed ticket with that ID')
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (message.author.id !== ticket.creator && !message.member.roles.cache.has(config.staff_role))
|
if (message.author.id !== ticket.creator && !message.member.roles.cache.has(config.staff_role)) {
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -50,6 +50,8 @@ module.exports = {
|
|||||||
.setDescription(`You don't have permission to view ticket ${id} as it does not belong to you and you are not staff.`)
|
.setDescription(`You don't have permission to view ticket ${id} as it does not belong to you and you are not staff.`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let res = {};
|
let res = {};
|
||||||
const embed = new MessageEmbed()
|
const embed = new MessageEmbed()
|
||||||
.setColor(config.colour)
|
.setColor(config.colour)
|
||||||
@ -66,14 +68,12 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const BASE_URL = config.transcripts.web.server;
|
const BASE_URL = config.transcripts.web.server;
|
||||||
if (config.transcripts.web.enabled)
|
if (config.transcripts.web.enabled) embed.addField('Web archive', `${BASE_URL}/${ticket.creator}/${ticket.channel}`);
|
||||||
embed.addField('Web archive', `${BASE_URL}/${ticket.creator}/${ticket.channel}`);
|
|
||||||
|
|
||||||
if (embed.fields.length < 1)
|
if (embed.fields.length < 1) embed.setDescription(`No text transcripts or archive data exists for ticket ${id}`);
|
||||||
embed.setDescription(`No text transcripts or archive data exists for ticket ${id}`);
|
|
||||||
|
|
||||||
res.embed = embed;
|
res.embed = embed;
|
||||||
|
|
||||||
@ -83,10 +83,9 @@ module.exports = {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
channel = message.channel;
|
channel = message.channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel.send(res).then(m => {
|
channel.send(res).then(m => {
|
||||||
if (channel.id === message.channel.id)
|
if (channel.id === message.channel.id) m.delete({timeout: 15000});
|
||||||
m.delete({timeout: 15000});
|
|
||||||
});
|
});
|
||||||
message.delete({timeout: 1500});
|
message.delete({timeout: 1500});
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -11,7 +11,7 @@ const log = new ChildLogger();
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
event: 'debug',
|
event: 'debug',
|
||||||
execute(client, [e]) {
|
execute(_client, [e]) {
|
||||||
log.debug(e);
|
log.debug(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -11,7 +11,7 @@ const log = new ChildLogger();
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
event: 'error',
|
event: 'error',
|
||||||
execute(client, [e]) {
|
execute(_client, [e]) {
|
||||||
log.error(e);
|
log.error(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { Collection, MessageEmbed } = require('discord.js');
|
const { Collection, MessageEmbed } = require('discord.js');
|
||||||
@ -23,19 +23,18 @@ module.exports = {
|
|||||||
I am the support bot for **${guild}**.
|
I am the support bot for **${guild}**.
|
||||||
Type \`${config.prefix}new\` on the server to create a new ticket.`);
|
Type \`${config.prefix}new\` on the server to create a new ticket.`);
|
||||||
} // stop here if is DM
|
} // stop here if is DM
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ticket transcripts
|
* Ticket transcripts
|
||||||
* (bots currently still allowed)
|
* (bots currently still allowed)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let ticket = await Ticket.findOne({ where: { channel: message.channel.id } });
|
let ticket = await Ticket.findOne({ where: { channel: message.channel.id } });
|
||||||
if(ticket)
|
if (ticket) archive.add(message); // add message to archive
|
||||||
archive.add(message); // add message to archive
|
|
||||||
|
|
||||||
if (message.author.bot || message.author.id === client.user.id) return; // goodbye bots
|
if (message.author.bot || message.author.id === client.user.id) return; // goodbye bots
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command handler
|
* Command handler
|
||||||
* (no bots / self)
|
* (no bots / self)
|
||||||
@ -49,11 +48,10 @@ Type \`${config.prefix}new\` on the server to create a new ticket.`);
|
|||||||
const commandName = args.shift().toLowerCase();
|
const commandName = args.shift().toLowerCase();
|
||||||
const command = client.commands.get(commandName)
|
const command = client.commands.get(commandName)
|
||||||
|| client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName));
|
|| client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName));
|
||||||
|
|
||||||
if (!command || commandName === 'none') return; // not an existing command
|
if (!command || commandName === 'none') return; // not an existing command
|
||||||
|
|
||||||
if (message.guild.id !== guild.id)
|
if (message.guild.id !== guild.id) return message.reply(`This bot can only be used within the "${guild}" server`); // not in this server
|
||||||
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)) {
|
if (command.permission && !message.member.hasPermission(command.permission)) {
|
||||||
log.console(`${message.author.tag} tried to use the '${command.name}' command without permission`);
|
log.console(`${message.author.tag} tried to use the '${command.name}' command without permission`);
|
||||||
@ -66,7 +64,7 @@ Type \`${config.prefix}new\` on the server to create a new ticket.`);
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.args && !args.length)
|
if (command.args && !args.length) {
|
||||||
return message.channel.send(
|
return message.channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -74,9 +72,10 @@ Type \`${config.prefix}new\` on the server to create a new ticket.`);
|
|||||||
.addField('Help', `Type \`${config.prefix}help ${command.name}\` for more information`)
|
.addField('Help', `Type \`${config.prefix}help ${command.name}\` for more information`)
|
||||||
.setFooter(guild.name, guild.iconURL())
|
.setFooter(guild.name, guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!client.cooldowns.has(command.name)) client.cooldowns.set(command.name, new Collection());
|
if (!client.cooldowns.has(command.name)) client.cooldowns.set(command.name, new Collection());
|
||||||
|
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const timestamps = client.cooldowns.get(command.name);
|
const timestamps = client.cooldowns.get(command.name);
|
||||||
const cooldownAmount = (command.cooldown || config.cooldown) * 1000;
|
const cooldownAmount = (command.cooldown || config.cooldown) * 1000;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -12,11 +12,10 @@ const fs = require('fs');
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
event: 'messageDelete',
|
event: 'messageDelete',
|
||||||
async execute(client, [message], {config, Ticket}) {
|
async execute(_client, [message], {config, Ticket}) {
|
||||||
|
if (!config.transcripts.web.enabled) return;
|
||||||
|
|
||||||
if(!config.transcripts.web.enabled) return;
|
if (message.partial) {
|
||||||
|
|
||||||
if (message.partial)
|
|
||||||
try {
|
try {
|
||||||
await message.fetch();
|
await message.fetch();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -24,15 +23,15 @@ module.exports = {
|
|||||||
log.error(err.message);
|
log.error(err.message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let ticket = await Ticket.findOne({ where: { channel: message.channel.id } });
|
let ticket = await Ticket.findOne({ where: { channel: message.channel.id } });
|
||||||
if(!ticket) return;
|
if (!ticket) return;
|
||||||
|
|
||||||
|
|
||||||
let path = `user/transcripts/raw/${message.channel.id}.log`;
|
let path = `user/transcripts/raw/${message.channel.id}.log`;
|
||||||
let embeds = [];
|
let embeds = [];
|
||||||
for (let embed in message.embeds)
|
for (let embed in message.embeds) embeds.push(message.embeds[embed].toJSON());
|
||||||
embeds.push(message.embeds[embed].toJSON());
|
|
||||||
|
|
||||||
fs.appendFileSync(path, JSON.stringify({
|
fs.appendFileSync(path, JSON.stringify({
|
||||||
id: message.id,
|
id: message.id,
|
||||||
@ -44,6 +43,5 @@ module.exports = {
|
|||||||
edited: message.edits.length > 1,
|
edited: message.edits.length > 1,
|
||||||
deleted: true // delete the message
|
deleted: true // delete the message
|
||||||
}) + '\n');
|
}) + '\n');
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -14,28 +14,28 @@ const fs = require('fs');
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
event: 'messageReactionAdd',
|
event: 'messageReactionAdd',
|
||||||
async execute(client, [r, u], {config, Ticket, Setting}) {
|
async execute(client, [r, u], {config, Ticket, Setting}) {
|
||||||
|
if (r.partial) {
|
||||||
if (r.partial)
|
|
||||||
try {
|
try {
|
||||||
await r.fetch();
|
await r.fetch();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error(err);
|
log.error(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let panelID = await Setting.findOne({ where: { key: 'panel_msg_id' } });
|
let panelID = await Setting.findOne({ where: { key: 'panel_msg_id' } });
|
||||||
if (!panelID) return;
|
if (!panelID) return;
|
||||||
|
|
||||||
if(r.message.id !== panelID.get('value')) return;
|
if (r.message.id !== panelID.get('value')) return;
|
||||||
|
|
||||||
if(u.id === client.user.id) return;
|
if (u.id === client.user.id) return;
|
||||||
|
|
||||||
if (r.emoji.name !== config.panel.reaction && r.emoji.id !== config.panel.reaction) return;
|
if (r.emoji.name !== config.panel.reaction && r.emoji.id !== config.panel.reaction) return;
|
||||||
|
|
||||||
let channel = r.message.channel;
|
let channel = r.message.channel;
|
||||||
|
|
||||||
const supportRole = channel.guild.roles.cache.get(config.staff_role);
|
const supportRole = channel.guild.roles.cache.get(config.staff_role);
|
||||||
if (!supportRole)
|
if (!supportRole) {
|
||||||
return channel.send(
|
return channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -43,7 +43,7 @@ module.exports = {
|
|||||||
.setDescription(`${config.name} has not been set up correctly. Could not find a 'support team' role with the id \`${config.staff_role}\``)
|
.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())
|
.setFooter(channel.guild.name, channel.guild.iconURL())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// everything is cool
|
// everything is cool
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
limit: config.tickets.max
|
limit: config.tickets.max
|
||||||
});
|
});
|
||||||
|
|
||||||
if (tickets.count >= config.tickets.max) {
|
if (tickets.count >= config.tickets.max) {
|
||||||
let ticketList = [];
|
let ticketList = [];
|
||||||
for (let t in tickets.rows) {
|
for (let t in tickets.rows) {
|
||||||
@ -67,7 +67,6 @@ module.exports = {
|
|||||||
let dm = u.dmChannel || await u.createDM();
|
let dm = u.dmChannel || await u.createDM();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
return dm.send(
|
return dm.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -76,10 +75,7 @@ module.exports = {
|
|||||||
.setDescription(`Use \`${config.prefix}close\` in a server channel to close unneeded tickets.\n\n${ticketList.join(',\n')}`)
|
.setDescription(`Use \`${config.prefix}close\` in a server channel to close unneeded tickets.\n\n${ticketList.join(',\n')}`)
|
||||||
.setFooter(channel.guild.name, channel.guild.iconURL())
|
.setFooter(channel.guild.name, channel.guild.iconURL())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
||||||
let m = await channel.send(
|
let m = await channel.send(
|
||||||
new MessageEmbed()
|
new MessageEmbed()
|
||||||
.setColor(config.err_colour)
|
.setColor(config.err_colour)
|
||||||
@ -88,11 +84,8 @@ module.exports = {
|
|||||||
.setDescription(`Use \`${config.prefix}close\` to close unneeded tickets.\n\n${ticketList.join(',\n')}`)
|
.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())
|
.setFooter(channel.guild.name + ' | This message will be deleted in 15 seconds', channel.guild.iconURL())
|
||||||
);
|
);
|
||||||
|
|
||||||
return m.delete({ timeout: 15000 });
|
return m.delete({ timeout: 15000 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let topic = 'No topic given (created via panel)';
|
let topic = 'No topic given (created via panel)';
|
||||||
@ -130,7 +123,6 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
reason: 'User requested a new support ticket channel'
|
reason: 'User requested a new support ticket channel'
|
||||||
}).then(async c => {
|
}).then(async c => {
|
||||||
|
|
||||||
Ticket.update({
|
Ticket.update({
|
||||||
channel: c.id
|
channel: c.id
|
||||||
}, {
|
}, {
|
||||||
@ -179,9 +171,8 @@ module.exports = {
|
|||||||
.setFooter(channel.guild.name, channel.guild.iconURL())
|
.setFooter(channel.guild.name, channel.guild.iconURL())
|
||||||
);
|
);
|
||||||
|
|
||||||
if (config.tickets.pin)
|
if (config.tickets.pin) await w.pin();
|
||||||
await w.pin();
|
// await w.pin().then(m => m.delete()); // oopsie, this deletes the pinned message
|
||||||
// await w.pin().then(m => m.delete()); // oopsie, this deletes the pinned message
|
|
||||||
|
|
||||||
if (config.logs.discord.enabled)
|
if (config.logs.discord.enabled)
|
||||||
client.channels.cache.get(config.logs.discord.channel).send(
|
client.channels.cache.get(config.logs.discord.channel).send(
|
||||||
@ -197,8 +188,6 @@ module.exports = {
|
|||||||
);
|
);
|
||||||
|
|
||||||
log.info(`${u.tag} created a new ticket (#${name}) via panel`);
|
log.info(`${u.tag} created a new ticket (#${name}) via panel`);
|
||||||
|
|
||||||
|
|
||||||
}).catch(log.error);
|
}).catch(log.error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -12,33 +12,33 @@ const fs = require('fs');
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
event: 'messageUpdate',
|
event: 'messageUpdate',
|
||||||
async execute(client, [o, n], {config, Ticket}) {
|
async execute(_client, [o, n], {config, Ticket}) {
|
||||||
|
if (!config.transcripts.web.enabled) return;
|
||||||
|
|
||||||
if(!config.transcripts.web.enabled) return;
|
if (o.partial) {
|
||||||
|
|
||||||
if (o.partial)
|
|
||||||
try {
|
try {
|
||||||
await o.fetch();
|
await o.fetch();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error(err);
|
log.error(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (n.partial)
|
if (n.partial) {
|
||||||
try {
|
try {
|
||||||
await n.fetch();
|
await n.fetch();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error(err);
|
log.error(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let ticket = await Ticket.findOne({ where: { channel: n.channel.id } });
|
let ticket = await Ticket.findOne({ where: { channel: n.channel.id } });
|
||||||
if(!ticket) return;
|
if (!ticket) return;
|
||||||
|
|
||||||
let path = `user/transcripts/raw/${n.channel.id}.log`;
|
let path = `user/transcripts/raw/${n.channel.id}.log`;
|
||||||
let embeds = [];
|
let embeds = [];
|
||||||
for (let embed in n.embeds)
|
for (let embed in n.embeds) embeds.push({ ...n.embeds[embed] });
|
||||||
embeds.push({ ...n.embeds[embed] });
|
|
||||||
|
|
||||||
fs.appendFileSync(path, JSON.stringify({
|
fs.appendFileSync(path, JSON.stringify({
|
||||||
id: n.id,
|
id: n.id,
|
||||||
@ -49,7 +49,6 @@ module.exports = {
|
|||||||
attachments: [...n.attachments.values()],
|
attachments: [...n.attachments.values()],
|
||||||
edited: true
|
edited: true
|
||||||
}) + '\n');
|
}) + '\n');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -11,7 +11,7 @@ const log = new ChildLogger();
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
event: 'rateLimit',
|
event: 'rateLimit',
|
||||||
execute(client, [limit]) {
|
execute(_client, [limit]) {
|
||||||
log.warn('Rate-limited! (Enable debug mode in config for details)');
|
log.warn('Rate-limited! (Enable debug mode in config for details)');
|
||||||
log.debug(limit);
|
log.debug(limit);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -13,9 +13,8 @@ const config = require('../../user/' + require('../').config);
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
event: 'ready',
|
event: 'ready',
|
||||||
execute(client) {
|
execute(client) {
|
||||||
|
|
||||||
log.success(`Authenticated as ${client.user.tag}`);
|
log.success(`Authenticated as ${client.user.tag}`);
|
||||||
|
|
||||||
const updatePresence = () => {
|
const updatePresence = () => {
|
||||||
let num = Math.floor(Math.random() * config.activities.length);
|
let num = Math.floor(Math.random() * config.activities.length);
|
||||||
client.user.setPresence({
|
client.user.setPresence({
|
||||||
@ -26,17 +25,15 @@ module.exports = {
|
|||||||
}).catch(log.error);
|
}).catch(log.error);
|
||||||
log.debug(`Updated presence: ${config.activity_types[num]} ${config.activities[num]}`);
|
log.debug(`Updated presence: ${config.activity_types[num]} ${config.activities[num]}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
updatePresence();
|
updatePresence();
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
updatePresence();
|
updatePresence();
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
|
|
||||||
if (client.guilds.cache.get(config.guild).member(client.user).hasPermission('ADMINISTRATOR', false))
|
if (client.guilds.cache.get(config.guild).member(client.user).hasPermission('ADMINISTRATOR', false)) {
|
||||||
log.success('\'ADMINISTRATOR\' permission has been granted');
|
log.success('\'ADMINISTRATOR\' permission has been granted');
|
||||||
else
|
} else log.warn('Bot does not have \'ADMINISTRATOR\' permission');
|
||||||
log.warn('Bot does not have \'ADMINISTRATOR\' permission');
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -11,7 +11,7 @@ const log = new ChildLogger();
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
event: 'warn',
|
event: 'warn',
|
||||||
execute(client, [e]) {
|
execute(_client, [e]) {
|
||||||
log.warn(e);
|
log.warn(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
44
src/index.js
44
src/index.js
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
@ -40,7 +40,6 @@ log.multi(log); // required to allow other files to access the logger
|
|||||||
|
|
||||||
require('./modules/updater')(); // check for updates
|
require('./modules/updater')(); // check for updates
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* storage
|
* storage
|
||||||
*/
|
*/
|
||||||
@ -48,14 +47,40 @@ const { Sequelize, Model, DataTypes } = require('sequelize');
|
|||||||
|
|
||||||
let sequelize;
|
let sequelize;
|
||||||
|
|
||||||
if(config.storage.type === 'mysql') {
|
switch (config.storage.type) {
|
||||||
|
case 'mysql':
|
||||||
log.info('Connecting to MySQL database...');
|
log.info('Connecting to MySQL database...');
|
||||||
sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASS, {
|
sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASS, {
|
||||||
dialect: 'mysql',
|
dialect: 'mysql',
|
||||||
host: process.env.DB_HOST,
|
host: process.env.DB_HOST,
|
||||||
logging: log.debug
|
logging: log.debug
|
||||||
});
|
});
|
||||||
} else {
|
break;
|
||||||
|
case 'mariadb':
|
||||||
|
log.info('Connecting to MariaDB database...');
|
||||||
|
sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASS, {
|
||||||
|
dialect: 'mariadb',
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
logging: log.debug
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'postgres':
|
||||||
|
log.info('Connecting to PostgresSQL database...');
|
||||||
|
sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASS, {
|
||||||
|
dialect: 'postgres',
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
logging: log.debug
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'microsoft':
|
||||||
|
log.info('Connecting to Microsoft SQL Server database...');
|
||||||
|
sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASS, {
|
||||||
|
dialect: 'mssql',
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
logging: log.debug
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
log.info('Using SQLite storage');
|
log.info('Using SQLite storage');
|
||||||
sequelize = new Sequelize({
|
sequelize = new Sequelize({
|
||||||
dialect: 'sqlite',
|
dialect: 'sqlite',
|
||||||
@ -90,7 +115,7 @@ Setting.sync();
|
|||||||
/**
|
/**
|
||||||
* event loader
|
* event loader
|
||||||
*/
|
*/
|
||||||
const events = fs.readdirSync('src/events').filter(file => file.endsWith('.js'));
|
const events = fs.readdirSync('src/events').filter(file => file.endsWith('.js'));
|
||||||
for (const file of events) {
|
for (const file of events) {
|
||||||
const event = require(`./events/${file}`);
|
const event = require(`./events/${file}`);
|
||||||
client.events.set(event.event, event);
|
client.events.set(event.event, event);
|
||||||
@ -102,12 +127,12 @@ for (const file of events) {
|
|||||||
/**
|
/**
|
||||||
* command loader
|
* command loader
|
||||||
*/
|
*/
|
||||||
const commands = fs.readdirSync('src/commands').filter(file => file.endsWith('.js'));
|
const commands = fs.readdirSync('src/commands').filter(file => file.endsWith('.js'));
|
||||||
for (const file of commands) {
|
for (const file of commands) {
|
||||||
const command = require(`./commands/${file}`);
|
const command = require(`./commands/${file}`);
|
||||||
client.commands.set(command.name, command);
|
client.commands.set(command.name, command);
|
||||||
log.console(log.format(`> Loaded &7${config.prefix}${command.name}&f command`));
|
log.console(log.format(`> Loaded &7${config.prefix}${command.name}&f command`));
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info(`Loaded ${events.length} events and ${commands.length} commands`);
|
log.info(`Loaded ${events.length} events and ${commands.length} commands`);
|
||||||
|
|
||||||
@ -123,8 +148,7 @@ const clean = () => {
|
|||||||
total++;
|
total++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (total > 0)
|
if (total > 0) log.info(`Deleted ${total} old text ${utils.plural('transcript', total)}`);
|
||||||
log.info(`Deleted ${total} old text ${utils.plural('transcript', total)}`);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (config.transcripts.text.enabled) {
|
if (config.transcripts.text.enabled) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ const fetch = require('node-fetch');
|
|||||||
|
|
||||||
module.exports.add = (message) => {
|
module.exports.add = (message) => {
|
||||||
|
|
||||||
if(message.type !== 'DEFAULT') return;
|
if (message.type !== 'DEFAULT') return;
|
||||||
|
|
||||||
if (config.transcripts.text.enabled) { // text transcripts
|
if (config.transcripts.text.enabled) { // text transcripts
|
||||||
let path = `user/transcripts/text/${message.channel.id}.txt`,
|
let path = `user/transcripts/text/${message.channel.id}.txt`,
|
||||||
@ -33,8 +33,7 @@ module.exports.add = (message) => {
|
|||||||
json = `user/transcripts/raw/entities/${message.channel.id}.json`;
|
json = `user/transcripts/raw/entities/${message.channel.id}.json`;
|
||||||
|
|
||||||
let embeds = [];
|
let embeds = [];
|
||||||
for (let embed in message.embeds)
|
for (let embed in message.embeds) embeds.push({ ...message.embeds[embed] });
|
||||||
embeds.push({ ...message.embeds[embed] });
|
|
||||||
|
|
||||||
// message
|
// message
|
||||||
fs.appendFileSync(raw, JSON.stringify({
|
fs.appendFileSync(raw, JSON.stringify({
|
||||||
@ -100,15 +99,14 @@ module.exports.export = (Ticket, channel) => new Promise((resolve, reject) => {
|
|||||||
channel: channel.id
|
channel: channel.id
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let raw = `user/transcripts/raw/${channel.id}.log`,
|
let raw = `user/transcripts/raw/${channel.id}.log`,
|
||||||
json = `user/transcripts/raw/entities/${channel.id}.json`;
|
json = `user/transcripts/raw/entities/${channel.id}.json`;
|
||||||
|
|
||||||
if (!config.transcripts.web.enabled || !fs.existsSync(raw) || !fs.existsSync(json))
|
if (!config.transcripts.web.enabled || !fs.existsSync(raw) || !fs.existsSync(json)) return reject(false);
|
||||||
return reject(false);
|
|
||||||
|
|
||||||
let data = JSON.parse(fs.readFileSync(json));
|
let data = JSON.parse(fs.readFileSync(json));
|
||||||
|
|
||||||
data.ticket = {
|
data.ticket = {
|
||||||
id: ticket.id,
|
id: ticket.id,
|
||||||
name: channel.name,
|
name: channel.name,
|
||||||
@ -122,15 +120,12 @@ module.exports.export = (Ticket, channel) => new Promise((resolve, reject) => {
|
|||||||
lineReader.eachLine(raw, line => {
|
lineReader.eachLine(raw, line => {
|
||||||
let message = JSON.parse(line);
|
let message = JSON.parse(line);
|
||||||
let index = data.messages.findIndex(m => m.id === message.id);
|
let index = data.messages.findIndex(m => m.id === message.id);
|
||||||
if (index === -1)
|
if (index === -1) data.messages.push(message);
|
||||||
data.messages.push(message);
|
else data.messages[index] = message;
|
||||||
else
|
|
||||||
data.messages[index] = message;
|
|
||||||
}, () => {
|
}, () => {
|
||||||
let endpoint = config.transcripts.web.server;
|
let endpoint = config.transcripts.web.server;
|
||||||
|
|
||||||
if (endpoint[endpoint.length - 1] === '/')
|
if (endpoint[endpoint.length - 1] === '/') endpoint = endpoint.slice(0, -1);
|
||||||
endpoint = endpoint.slice(0, -1);
|
|
||||||
|
|
||||||
endpoint += `/${data.ticket.creator}/${data.ticket.channel}/?key=${process.env.ARCHIVES_KEY}`;
|
endpoint += `/${data.ticket.creator}/${data.ticket.channel}/?key=${process.env.ARCHIVES_KEY}`;
|
||||||
|
|
||||||
@ -156,8 +151,6 @@ module.exports.export = (Ticket, channel) => new Promise((resolve, reject) => {
|
|||||||
log.warn(e);
|
log.warn(e);
|
||||||
return resolve(e);
|
return resolve(e);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { version, homepage } = require('../../package.json');
|
const { version, homepage } = require('../../package.json');
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildLogger = require('leekslazylogger').ChildLogger;
|
const ChildLogger = require('leekslazylogger').ChildLogger;
|
||||||
@ -15,32 +15,27 @@ version = 'v' + version;
|
|||||||
const boxen = require('boxen');
|
const boxen = require('boxen');
|
||||||
const link = require('terminal-link');
|
const link = require('terminal-link');
|
||||||
|
|
||||||
module.exports = () => {
|
module.exports = async () => {
|
||||||
if(!config.updater)
|
if (!config.updater) return;
|
||||||
return;
|
const json = await (await fetch('https://api.github.com/repos/eartharoid/DiscordTickets/releases')).json();
|
||||||
|
const update = json[0];
|
||||||
fetch('https://api.github.com/repos/eartharoid/DiscordTickets/releases')
|
let notice = [];
|
||||||
.then(res => res.json())
|
|
||||||
.then(json => {
|
|
||||||
const update = json[0];
|
|
||||||
let notice = [];
|
|
||||||
|
|
||||||
if (version !== update.tag_name) {
|
if (version !== update.tag_name) {
|
||||||
log.notice(log.f(`There is an update available for Discord Tickets (${version} -> ${update.tag_name})`));
|
log.notice(log.f(`There is an update available for Discord Tickets (${version} -> ${update.tag_name})`));
|
||||||
|
|
||||||
notice.push(`&6You are currently using &c${version}&6, the latest is &a${update.tag_name}&6.`);
|
notice.push(`&6You are currently using &c${version}&6, the latest is &a${update.tag_name}&6.`);
|
||||||
notice.push(`&6Download "&f${update.name}&6" from`);
|
notice.push(`&6Download "&f${update.name}&6" from`);
|
||||||
notice.push(link('&6the GitHub releases page', 'https://github.com/eartharoid/DiscordTickets/releases/'));
|
notice.push(link('&6the GitHub releases page', 'https://github.com/eartharoid/DiscordTickets/releases/'));
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
boxen(log.f(notice.join('\n')), {
|
boxen(log.f(notice.join('\n')), {
|
||||||
padding: 1,
|
padding: 1,
|
||||||
margin: 1,
|
margin: 1,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
borderColor: 'yellow',
|
borderColor: 'yellow',
|
||||||
borderStyle: 'round'
|
borderStyle: 'round'
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
};
|
};
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @name DiscordTickets
|
* @name DiscordTickets
|
||||||
* @author eartharoid <contact@eartharoid.me>
|
* @author eartharoid <contact@eartharoid.me>
|
||||||
* @license GNU-GPLv3
|
* @license GNU-GPLv3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -5,24 +5,24 @@
|
|||||||
* | | | | | | / __| / __| / _ \ | '__| / _` | | | | | / __| | |/ / / _ \ | __| / __|
|
* | | | | | | / __| / __| / _ \ | '__| / _` | | | | | / __| | |/ / / _ \ | __| / __|
|
||||||
* | |_| | | | \__ \ | (__ | (_) | | | | (_| | | | | | | (__ | < | __/ | |_ \__ \
|
* | |_| | | | \__ \ | (__ | (_) | | | | (_| | | | | | | (__ | < | __/ | |_ \__ \
|
||||||
* |____/ |_| |___/ \___| \___/ |_| \__,_| |_| |_| \___| |_|\_\ \___| \__| |___/
|
* |____/ |_| |___/ \___| \___/ |_| \__,_| |_| |_| \___| |_|\_\ \___| \__| |___/
|
||||||
*
|
*
|
||||||
* ---------------------
|
* ---------------------
|
||||||
* Quick Start
|
* Quick Start
|
||||||
* ---------------------
|
* ---------------------
|
||||||
*
|
*
|
||||||
* > For detailed instructions, visit the GitHub repository and read the documentation:
|
* > For detailed instructions, visit the GitHub repository and read the documentation:
|
||||||
* https://github.com/eartharoid/DiscordTickets/wiki
|
* https://github.com/eartharoid/DiscordTickets/wiki
|
||||||
*
|
*
|
||||||
* > IMPORTANT: Also edit the TOKEN in 'user/.env'
|
* > IMPORTANT: Also edit the TOKEN in 'user/.env'
|
||||||
*
|
*
|
||||||
* ---------------------
|
* ---------------------
|
||||||
* Support
|
* Support
|
||||||
* ---------------------
|
* ---------------------
|
||||||
*
|
*
|
||||||
* > Information: https://github.com/eartharoid/DiscordTickets/#readme
|
* > Information: https://github.com/eartharoid/DiscordTickets/#readme
|
||||||
* > Discord Support Server: https://go.eartharoid.me/discord
|
* > Discord Support Server: https://go.eartharoid.me/discord
|
||||||
* > Wiki: https://github.com/eartharoid/DiscordTickets/wiki
|
* > Wiki: https://github.com/eartharoid/DiscordTickets/wiki
|
||||||
*
|
*
|
||||||
* ###############################################################################################
|
* ###############################################################################################
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ module.exports = {
|
|||||||
channel: '' // ID of your log channel
|
channel: '' // ID of your log channel
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
debug: false,
|
debug: false,
|
||||||
updater: true
|
updater: true
|
||||||
};
|
};
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 698 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 577 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.3 MiB |
Loading…
Reference in New Issue
Block a user