mirror of
https://github.com/Hessenuk/DiscordTickets.git
synced 2024-12-23 08:13:09 +02:00
More settings, update things
This commit is contained in:
parent
393bdb6b79
commit
fff423956d
2539
pnpm-lock.yaml
2539
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -41,18 +41,21 @@ module.exports = class SettingsCommand extends Command {
|
|||||||
if (c.id) {
|
if (c.id) {
|
||||||
|
|
||||||
// existing category
|
// existing category
|
||||||
let category = await this.client.db.models.Category.findOne({
|
let cat_row = await this.client.db.models.Category.findOne({
|
||||||
where: {
|
where: {
|
||||||
id: c.id
|
id: c.id
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
category.max_per_member = c.max_per_member;
|
cat_row.image = c.image;
|
||||||
category.name = c.name;
|
cat_row.max_per_member = c.max_per_member;
|
||||||
category.name_format = c.name_format;
|
cat_row.name = c.name;
|
||||||
category.opening_message = c.opening_message;
|
cat_row.name_format = c.name_format;
|
||||||
category.require_topic = c.require_topic;
|
cat_row.opening_message = c.opening_message;
|
||||||
category.roles = c.roles;
|
cat_row.opening_questions = c.opening_questions;
|
||||||
category.save();
|
cat_row.require_topic = c.require_topic;
|
||||||
|
cat_row.roles = c.roles;
|
||||||
|
cat_row.survey = c.survey;
|
||||||
|
cat_row.save();
|
||||||
|
|
||||||
let cat_channel = await this.client.channels.fetch(c.id);
|
let cat_channel = await this.client.channels.fetch(c.id);
|
||||||
|
|
||||||
@ -95,35 +98,43 @@ module.exports = class SettingsCommand extends Command {
|
|||||||
})
|
})
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.client.db.models.Category.create({
|
await this.client.db.models.Category.create({
|
||||||
id: cat_channel.id,
|
id: cat_channel.id,
|
||||||
|
guild: message.guild.id,
|
||||||
|
image: c.image,
|
||||||
max_per_member: c.max_per_member,
|
max_per_member: c.max_per_member,
|
||||||
name: c.name,
|
name: c.name,
|
||||||
name_format: c.name_format,
|
name_format: c.name_format,
|
||||||
guild: message.guild.id,
|
|
||||||
opening_message: c.opening_message,
|
opening_message: c.opening_message,
|
||||||
|
opening_questions: c.opening_questions,
|
||||||
require_topic: c.require_topic,
|
require_topic: c.require_topic,
|
||||||
roles: c.roles,
|
roles: c.roles,
|
||||||
|
survey: c.survey
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let survey in data.surveys) {
|
||||||
|
let survey_data = {
|
||||||
|
guild: message.guild.id,
|
||||||
|
name: survey,
|
||||||
|
};
|
||||||
|
let [s_row] = await this.client.db.models.Survey.findOrCreate({
|
||||||
|
where: survey_data,
|
||||||
|
defaults: survey_data
|
||||||
|
});
|
||||||
|
s_row.questions = data.surveys[survey];
|
||||||
|
await s_row.save();
|
||||||
|
}
|
||||||
|
|
||||||
this.client.log.success(`Updated guild settings for "${message.guild.name}"`);
|
this.client.log.success(`Updated guild settings for "${message.guild.name}"`);
|
||||||
message.channel.send(i18n('commands.settings.response.updated'));
|
message.channel.send(i18n('commands.settings.response.updated'));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// upload settings as json to be modified
|
// upload settings as json to be edited
|
||||||
let data = {
|
|
||||||
categories: [],
|
|
||||||
colour: settings.colour,
|
|
||||||
command_prefix: settings.command_prefix,
|
|
||||||
error_colour: settings.error_colour,
|
|
||||||
footer: settings.footer,
|
|
||||||
locale: settings.locale,
|
|
||||||
log_messages: settings.log_messages,
|
|
||||||
success_colour: settings.success_colour,
|
|
||||||
};
|
|
||||||
|
|
||||||
let categories = await this.client.db.models.Category.findAll({
|
let categories = await this.client.db.models.Category.findAll({
|
||||||
where: {
|
where: {
|
||||||
@ -131,18 +142,41 @@ module.exports = class SettingsCommand extends Command {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
data.categories = categories.map(c =>{
|
let surveys = await this.client.db.models.Survey.findAll({
|
||||||
return {
|
where: {
|
||||||
id: c.id,
|
guild: message.guild.id
|
||||||
max_per_member: c.max_per_member,
|
}
|
||||||
name: c.name,
|
|
||||||
name_format: c.name_format,
|
|
||||||
opening_message: c.opening_message,
|
|
||||||
require_topic: c.require_topic,
|
|
||||||
roles: c.roles
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let data = {
|
||||||
|
categories: categories.map(c => {
|
||||||
|
return {
|
||||||
|
id: c.id,
|
||||||
|
image: c.image,
|
||||||
|
max_per_member: c.max_per_member,
|
||||||
|
name: c.name,
|
||||||
|
name_format: c.name_format,
|
||||||
|
opening_message: c.opening_message,
|
||||||
|
opening_questions: c.opening_questions,
|
||||||
|
require_topic: c.require_topic,
|
||||||
|
roles: c.roles,
|
||||||
|
survey: c.survey
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
colour: settings.colour,
|
||||||
|
command_prefix: settings.command_prefix,
|
||||||
|
error_colour: settings.error_colour,
|
||||||
|
footer: settings.footer,
|
||||||
|
locale: settings.locale,
|
||||||
|
log_messages: settings.log_messages,
|
||||||
|
success_colour: settings.success_colour,
|
||||||
|
surveys: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let survey in surveys) {
|
||||||
|
data.surveys[surveys[survey].name] = surveys[survey].questions;
|
||||||
|
}
|
||||||
|
|
||||||
let attachment = new MessageAttachment(
|
let attachment = new MessageAttachment(
|
||||||
Buffer.from(JSON.stringify(data, null, 2)),
|
Buffer.from(JSON.stringify(data, null, 2)),
|
||||||
`Settings for ${message.guild.name}.json`
|
`Settings for ${message.guild.name}.json`
|
||||||
|
@ -16,6 +16,10 @@ module.exports = ({ config }, sequelize) => {
|
|||||||
},
|
},
|
||||||
unique: 'name-guild'
|
unique: 'name-guild'
|
||||||
},
|
},
|
||||||
|
image: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
max_per_member: {
|
max_per_member: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
defaultValue: 1
|
defaultValue: 1
|
||||||
@ -34,6 +38,10 @@ module.exports = ({ config }, sequelize) => {
|
|||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
defaultValue: config.defaults.opening_message,
|
defaultValue: config.defaults.opening_message,
|
||||||
},
|
},
|
||||||
|
opening_questions: {
|
||||||
|
type: DataTypes.JSON,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
require_topic: {
|
require_topic: {
|
||||||
type: DataTypes.BOOLEAN,
|
type: DataTypes.BOOLEAN,
|
||||||
defaultValue: true,
|
defaultValue: true,
|
||||||
@ -42,10 +50,10 @@ module.exports = ({ config }, sequelize) => {
|
|||||||
type: DataTypes.JSON,
|
type: DataTypes.JSON,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
},
|
},
|
||||||
questions: {
|
survey: {
|
||||||
type: DataTypes.JSON,
|
type: DataTypes.STRING,
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
},
|
}
|
||||||
}, {
|
}, {
|
||||||
tableName: DB_TABLE_PREFIX + 'categories'
|
tableName: DB_TABLE_PREFIX + 'categories'
|
||||||
});
|
});
|
||||||
|
26
src/database/models/survey.model.js
Normal file
26
src/database/models/survey.model.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const { DataTypes } = require('sequelize');
|
||||||
|
module.exports = (client, sequelize) => {
|
||||||
|
const { DB_TABLE_PREFIX } = process.env;
|
||||||
|
sequelize.define('Survey', {
|
||||||
|
guild: {
|
||||||
|
type: DataTypes.CHAR(18),
|
||||||
|
allowNull: false,
|
||||||
|
references: {
|
||||||
|
model: DB_TABLE_PREFIX + 'guilds',
|
||||||
|
key: 'id'
|
||||||
|
},
|
||||||
|
unique: 'name-guild'
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
unique: 'name-guild'
|
||||||
|
},
|
||||||
|
questions: {
|
||||||
|
type: DataTypes.JSON,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
tableName: DB_TABLE_PREFIX + 'surveys'
|
||||||
|
});
|
||||||
|
};
|
29
src/database/models/survey_response.model.js
Normal file
29
src/database/models/survey_response.model.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const { DataTypes } = require('sequelize');
|
||||||
|
module.exports = (client, sequelize) => {
|
||||||
|
const { DB_TABLE_PREFIX } = process.env;
|
||||||
|
sequelize.define('SurveyResponse', {
|
||||||
|
answers: {
|
||||||
|
type: DataTypes.JSON,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
survey: {
|
||||||
|
type: DataTypes.CHAR(18),
|
||||||
|
allowNull: false,
|
||||||
|
references: {
|
||||||
|
model: DB_TABLE_PREFIX + 'surveys',
|
||||||
|
key: 'id'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ticket: {
|
||||||
|
type: DataTypes.CHAR(18),
|
||||||
|
allowNull: false,
|
||||||
|
unique: 'id-ticket',
|
||||||
|
references: {
|
||||||
|
model: DB_TABLE_PREFIX + 'tickets',
|
||||||
|
key: 'id'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
tableName: DB_TABLE_PREFIX + 'survey_responses'
|
||||||
|
});
|
||||||
|
};
|
@ -22,10 +22,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
process.title = 'Discord Tickets';
|
process.title = 'Discord Tickets';
|
||||||
|
|
||||||
const node_version = Number(process.versions.node.split('.')[0]);
|
const node_version = Number(process.versions.node.split('.')[0]);
|
||||||
if (node_version < 14)
|
if (node_version < 14)
|
||||||
return console.log(`\x07Error: Discord Tickets does not work on Node v${node_version}. Please upgrade to v14 or above.`);
|
return console.log(`\x07Error: Discord Tickets does not work on Node v${node_version}. Please upgrade to v14 or above.`);
|
||||||
|
|
||||||
|
const leeks = require('leeks.js');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { path } = require('./utils/fs');
|
const { path } = require('./utils/fs');
|
||||||
|
|
||||||
@ -61,6 +63,7 @@ if (!checkFile('./.env', './example.env')) {
|
|||||||
fs.writeFileSync(file, data);
|
fs.writeFileSync(file, data);
|
||||||
|
|
||||||
console.log('Saved.');
|
console.log('Saved.');
|
||||||
|
console.log(leeks.colours.yellow('Warning: do not lose your ENV file or encryption key; you will lose access to data in the database.'));
|
||||||
console.log('\x07Please set your bot\'s "DISCORD_TOKEN" in "./.env".');
|
console.log('\x07Please set your bot\'s "DISCORD_TOKEN" in "./.env".');
|
||||||
|
|
||||||
process.exit();
|
process.exit();
|
||||||
|
17
src/listeners/guildMemberRemove.js
Normal file
17
src/listeners/guildMemberRemove.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
module.exports = {
|
||||||
|
event: 'guildMemberRemove',
|
||||||
|
execute: async (client, member) => {
|
||||||
|
let tickets = await client.db.models.Ticket.findAndCountAll({
|
||||||
|
where: {
|
||||||
|
creator: member.id,
|
||||||
|
guild: member.guild.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let ticket of tickets.rows) {
|
||||||
|
client.tickets.close(ticket.id, null, member.guild.id, 'Member left the guild');
|
||||||
|
}
|
||||||
|
|
||||||
|
client.log.info(`Closed ${tickets.count} ticket(s) belonging to ${member.user.tag} who left "${member.guild.name}"`);
|
||||||
|
}
|
||||||
|
};
|
@ -71,8 +71,20 @@
|
|||||||
"name": "close",
|
"name": "close",
|
||||||
"response": {
|
"response": {
|
||||||
"closed": {
|
"closed": {
|
||||||
|
"title": "✅ Ticket closed",
|
||||||
|
"description": "This ticket has been closed.\nThe channel will be deleted in 5 seconds."
|
||||||
|
},
|
||||||
|
"closed_by_member": {
|
||||||
"title": "✅ Ticket closed",
|
"title": "✅ Ticket closed",
|
||||||
"description": "This ticket has been closed by %s.\nThe channel will be deleted in 5 seconds."
|
"description": "This ticket has been closed by %s.\nThe channel will be deleted in 5 seconds."
|
||||||
|
},
|
||||||
|
"closed_by_member_with_reason": {
|
||||||
|
"title": "✅ Ticket closed",
|
||||||
|
"description": "This ticket has been closed by %s: `%s`\nThe channel will be deleted in 5 seconds."
|
||||||
|
},
|
||||||
|
"closed_with_reason": {
|
||||||
|
"title": "✅ Ticket closed",
|
||||||
|
"description": "This ticket has been closed: `%s`\nThe channel will be deleted in 5 seconds."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -94,60 +94,85 @@ module.exports = class TicketManager extends EventEmitter {
|
|||||||
* @param {(string|number)} ticket_id - The channel ID, or the ticket number
|
* @param {(string|number)} ticket_id - The channel ID, or the ticket number
|
||||||
* @param {string?} closer_id - ID of the member who is closing the ticket, or null
|
* @param {string?} closer_id - ID of the member who is closing the ticket, or null
|
||||||
* @param {string} [guild_id] - The ID of the ticket's guild (used if a ticket number is provided instead of ID)
|
* @param {string} [guild_id] - The ID of the ticket's guild (used if a ticket number is provided instead of ID)
|
||||||
|
* @param {string} [reason] - The reason for closing the ticket
|
||||||
*/
|
*/
|
||||||
async close(ticket_id, closer_id, guild_id) {
|
async close(ticket_id, closer_id, guild_id, reason) {
|
||||||
let t_row = await this.resolve(ticket_id, guild_id);
|
let t_row = await this.resolve(ticket_id, guild_id);
|
||||||
if (!t_row) throw new Error(`Could not find a ticket with ID ${ticket_id}`);
|
if (!t_row) throw new Error(`Could not find a ticket with ID ${ticket_id}`);
|
||||||
ticket_id = t_row.id;
|
ticket_id = t_row.id;
|
||||||
|
|
||||||
this.emit('beforeClose', ticket_id);
|
this.emit('beforeClose', ticket_id);
|
||||||
|
|
||||||
let u_model_data = {
|
|
||||||
user: closer_id,
|
|
||||||
ticket: ticket_id
|
|
||||||
};
|
|
||||||
let [u_row] = await this.client.db.models.UserEntity.findOrCreate({
|
|
||||||
where: u_model_data,
|
|
||||||
defaults: u_model_data
|
|
||||||
});
|
|
||||||
|
|
||||||
let guild = this.client.guilds.cache.get(t_row.guild);
|
let guild = this.client.guilds.cache.get(t_row.guild);
|
||||||
let member = await guild.members.fetch(closer_id);
|
let settings = await guild.settings;
|
||||||
|
const i18n = this.client.i18n.get(settings.locale);
|
||||||
|
let channel = await this.client.channels.fetch(t_row.channel);
|
||||||
|
|
||||||
await u_row.update({
|
if (closer_id) {
|
||||||
avatar: member.user.displayAvatarURL(),
|
let u_model_data = {
|
||||||
username: member.user.username,
|
user: closer_id,
|
||||||
discriminator: member.user.discriminator,
|
ticket: ticket_id
|
||||||
display_name: member.displayName,
|
};
|
||||||
colour: member.displayColor === 0 ? null : int2hex(member.displayColor),
|
let [u_row] = await this.client.db.models.UserEntity.findOrCreate({
|
||||||
bot: member.user.bot
|
where: u_model_data,
|
||||||
});
|
defaults: u_model_data
|
||||||
|
});
|
||||||
|
|
||||||
|
let member = await guild.members.fetch(closer_id);
|
||||||
|
|
||||||
|
await u_row.update({
|
||||||
|
avatar: member.user.displayAvatarURL(),
|
||||||
|
username: member.user.username,
|
||||||
|
discriminator: member.user.discriminator,
|
||||||
|
display_name: member.displayName,
|
||||||
|
colour: member.displayColor === 0 ? null : int2hex(member.displayColor),
|
||||||
|
bot: member.user.bot
|
||||||
|
});
|
||||||
|
|
||||||
|
if (channel) {
|
||||||
|
let description = reason
|
||||||
|
? i18n('commands.close.response.closed_by_member_with_reason.description', member.user.toString(), reason)
|
||||||
|
: i18n('commands.close.response.closed_by_member.description', member.user.toString());
|
||||||
|
await channel.send(
|
||||||
|
new MessageEmbed()
|
||||||
|
.setColor(settings.success_colour)
|
||||||
|
.setTitle(i18n('commands.close.response.closed.title'))
|
||||||
|
.setDescription(description)
|
||||||
|
);
|
||||||
|
|
||||||
|
setTimeout(async () => {
|
||||||
|
await channel.delete(`Ticket channel closed by ${member.user.tag}${reason ? `: "${reason}"` : ''}`);
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client.log.info(`${member.user.tag} closed a ticket (${ticket_id})${reason ? `: "${reason}"` : ''}`);
|
||||||
|
} else {
|
||||||
|
if (channel) {
|
||||||
|
let description = reason
|
||||||
|
? i18n('commands.close.response.closed_with_reason.description')
|
||||||
|
: i18n('commands.close.response.closed.description');
|
||||||
|
await channel.send(
|
||||||
|
new MessageEmbed()
|
||||||
|
.setColor(settings.success_colour)
|
||||||
|
.setTitle(i18n('commands.close.response.closed.title'))
|
||||||
|
.setDescription(description)
|
||||||
|
);
|
||||||
|
|
||||||
|
setTimeout(async () => {
|
||||||
|
await channel.delete(`Ticket channel closed${reason ? `: "${reason}"` : ''}`);
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client.log.info(`A ticket was closed (${ticket_id})${reason ? `: "${reason}"` : ''}`);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
await t_row.update({
|
await t_row.update({
|
||||||
open: false,
|
open: false,
|
||||||
closed_by: closer_id
|
closed_by: closer_id,
|
||||||
|
reason: reason
|
||||||
});
|
});
|
||||||
|
|
||||||
let channel = await this.client.channels.fetch(t_row.channel);
|
|
||||||
|
|
||||||
if (channel) {
|
|
||||||
let settings = await guild.settings;
|
|
||||||
const i18n = this.client.i18n.get(settings.locale);
|
|
||||||
|
|
||||||
await channel.send(
|
|
||||||
new MessageEmbed()
|
|
||||||
.setColor(settings.success_colour)
|
|
||||||
.setTitle(i18n('commands.close.response.closed.title'))
|
|
||||||
.setDescription(i18n('commands.close.response.closed.description', member.user.toString()))
|
|
||||||
);
|
|
||||||
|
|
||||||
setTimeout(async () => {
|
|
||||||
await channel.delete(`Ticket channel closed by ${member.user.tag}`);
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.client.log.info(`${member.user.tag} closed a ticket (${ticket_id})`);
|
|
||||||
|
|
||||||
this.emit('close', ticket_id);
|
this.emit('close', ticket_id);
|
||||||
return t_row;
|
return t_row;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user