331 lines
No EOL
11 KiB
JavaScript
331 lines
No EOL
11 KiB
JavaScript
const { query, queryMulti } = require("./helper");
|
|
const { ticket_settings } = require("../config");
|
|
const discordTranscripts = require("discord-html-transcripts");
|
|
const {
|
|
EmbedBuilder,
|
|
ButtonBuilder,
|
|
ActionRowBuilder,
|
|
ModalBuilder,
|
|
TextInputBuilder
|
|
} = require('discord.js');
|
|
|
|
module.exports = async (client, db) => {
|
|
client.on("interactionCreate", async interaction => {
|
|
if (!interaction.customId) {
|
|
return;
|
|
}
|
|
|
|
if (interaction.customId === "newTicket") {
|
|
const [, ticketOptionId] = interaction.values[0].split("newTicket_");
|
|
const ticketOption = await query(
|
|
db,
|
|
`SELECT * FROM options WHERE id='${ticketOptionId}' AND guildID='${interaction.guildId}'`
|
|
);
|
|
const questions = await queryMulti(
|
|
db,
|
|
`SELECT * FROM questions WHERE optionID='${ticketOptionId}' AND guildID='${interaction.guildId}'`
|
|
);
|
|
|
|
if (questions) {
|
|
const modal = new ModalBuilder()
|
|
.setTitle("Ticket Form")
|
|
.setCustomId(`ticket_${ticketOptionId}`);
|
|
|
|
questions.forEach((question, index) => {
|
|
const textInput = new TextInputBuilder()
|
|
.setLabel(question.question)
|
|
.setStyle(question.answer_type)
|
|
.setRequired(question.required)
|
|
.setCustomId(`input_${question.id}`)
|
|
.setPlaceholder(question.place_holder);
|
|
|
|
const actionRow = new ActionRowBuilder().addComponents(textInput);
|
|
modal.addComponents(actionRow);
|
|
});
|
|
|
|
return interaction.showModal(modal);
|
|
} else {
|
|
await interaction.deferReply({ ephemeral: true });
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setTimestamp()
|
|
.setColor(ticket_settings.embed_color)
|
|
.setDescription(ticket_settings.ticket_message.replace("{user}", interaction.user))
|
|
.setThumbnail(ticket_settings.ticket_thumbnail)
|
|
.setAuthor({
|
|
name: interaction.user.tag,
|
|
iconURL: interaction.user.avatarURL()
|
|
});
|
|
|
|
const existingTicket = await query(
|
|
db,
|
|
`SELECT * FROM tickets WHERE status='open' AND userID='${interaction.user.id}' AND guildID='${interaction.guildId}'`
|
|
);
|
|
const existingChannel = client.channels.cache.get(existingTicket?.channelID);
|
|
|
|
if (existingTicket && existingChannel) {
|
|
return interaction.editReply({
|
|
content: `You already have a ticket! Please check the ${existingChannel}`,
|
|
ephemeral: true
|
|
});
|
|
}
|
|
|
|
const settings = await query(db, `SELECT * FROM settings WHERE guildID='${interaction.guildId}'`);
|
|
db.query(`UPDATE settings SET ticket_counter=ticket_counter+1 WHERE guildID='${interaction.guildId}'`);
|
|
|
|
const permissions = [
|
|
{
|
|
id: interaction.guildId,
|
|
deny: ["ViewChannel", "SendMessages"]
|
|
},
|
|
{
|
|
id: interaction.member.id,
|
|
allow: ["ViewChannel", "SendMessages"]
|
|
},
|
|
{
|
|
id: client.user.id,
|
|
allow: ["ViewChannel", "SendMessages"]
|
|
},
|
|
{
|
|
id: settings?.support_roleID,
|
|
allow: ["ViewChannel", "SendMessages"]
|
|
}
|
|
];
|
|
|
|
const channel = await interaction.guild.channels.create({
|
|
parent: ticketOption?.categoryID,
|
|
name: `ticket-${pad(settings.ticket_counter + 1, 4)}`,
|
|
topic: `#Ticket | From ${interaction.user.username}`,
|
|
permissionOverwrites: permissions
|
|
});
|
|
|
|
const closeButton = new ButtonBuilder()
|
|
.setEmoji(ticket_settings.buttoncloseemoji)
|
|
.setLabel(ticket_settings.buttoncloselabel)
|
|
.setStyle(ticket_settings.buttonclosestyle)
|
|
.setCustomId("close_ticket");
|
|
|
|
const actionRow = new ActionRowBuilder().addComponents(closeButton);
|
|
|
|
await channel.send({
|
|
content: `<@&${settings?.support_roleID}>`,
|
|
embeds: [embed],
|
|
components: [actionRow]
|
|
});
|
|
|
|
await interaction.editReply({
|
|
content: `You successfully created a ticket! Please check the ${channel}`,
|
|
ephemeral: true
|
|
});
|
|
|
|
db.query(
|
|
"INSERT INTO tickets (id, status, userID, guildID, channelID) VALUES (?, ?, ?, ?, ?)",
|
|
[pad(settings.ticket_counter + 1, 4), "open", interaction.user.id, interaction.guildId, channel.id]
|
|
);
|
|
}
|
|
} else if (interaction.customId.startsWith("ticket_")) {
|
|
if (!interaction.isModalSubmit()) {
|
|
return;
|
|
}
|
|
|
|
await interaction.deferReply({ ephemeral: true });
|
|
|
|
const ticketOptionId = interaction.customId.split("ticket_")[1];
|
|
const ticketOption = await query(
|
|
db,
|
|
`SELECT * FROM options WHERE id='${ticketOptionId}' AND guildID='${interaction.guildId}'`
|
|
);
|
|
|
|
const userEmbed = new EmbedBuilder()
|
|
.setTimestamp()
|
|
.setColor(ticket_settings.embed_color)
|
|
.setDescription(ticket_settings.ticket_message.replace("{user}", interaction.user))
|
|
.setAuthor({
|
|
name: interaction.user.tag,
|
|
iconURL: interaction.user.avatarURL()
|
|
});
|
|
|
|
const answerEmbed = new EmbedBuilder()
|
|
.setTimestamp()
|
|
.setColor(ticket_settings.embed_color)
|
|
.setAuthor({
|
|
name: interaction.user.tag,
|
|
iconURL: interaction.user.avatarURL()
|
|
});
|
|
|
|
interaction.fields.fields.forEach(async field => {
|
|
const question = await query(
|
|
db,
|
|
`SELECT * FROM questions WHERE id='${field.customId.split("input_")[1]}' AND guildID='${interaction.guildId}'`
|
|
);
|
|
|
|
answerEmbed.addFields({
|
|
name: question.question,
|
|
value: `\`\`\`${field.value}\`\`\``,
|
|
inline: false
|
|
});
|
|
});
|
|
|
|
const existingTicket = await query(
|
|
db,
|
|
`SELECT * FROM tickets WHERE status='open' AND userID='${interaction.user.id}' AND guildID='${interaction.guildId}'`
|
|
);
|
|
const existingChannel = client.channels.cache.get(existingTicket?.channelID);
|
|
|
|
if (existingTicket && existingChannel) {
|
|
return interaction.editReply({
|
|
content: `You already have a ticket! Please check the ${existingChannel}`,
|
|
ephemeral: true
|
|
});
|
|
}
|
|
|
|
const settings = await query(db, `SELECT * FROM settings WHERE guildID='${interaction.guildId}'`);
|
|
db.query(`UPDATE settings SET ticket_counter=ticket_counter+1 WHERE guildID='${interaction.guildId}'`);
|
|
|
|
const permissions = [
|
|
{
|
|
id: interaction.guildId,
|
|
deny: ["ViewChannel", "SendMessages"]
|
|
},
|
|
{
|
|
id: interaction.member.id,
|
|
allow: ["ViewChannel", "SendMessages"]
|
|
},
|
|
{
|
|
id: client.user.id,
|
|
allow: ["ViewChannel", "SendMessages"]
|
|
},
|
|
{
|
|
id: settings?.support_roleID,
|
|
allow: ["ViewChannel", "SendMessages"]
|
|
}
|
|
];
|
|
|
|
const channel = await interaction.guild.channels.create({
|
|
parent: ticketOption?.categoryID,
|
|
name: `ticket-${pad(settings.ticket_counter + 1, 4)}`,
|
|
topic: `#Ticket | From ${interaction.user.username}`,
|
|
permissionOverwrites: permissions
|
|
});
|
|
|
|
const closeButton = new ButtonBuilder()
|
|
.setEmoji(ticket_settings.buttoncloseemoji)
|
|
.setLabel(ticket_settings.buttoncloselabel)
|
|
.setStyle(ticket_settings.buttonclosestyle)
|
|
.setCustomId("close_ticket");
|
|
|
|
const actionRow = new ActionRowBuilder().addComponents(closeButton);
|
|
|
|
await channel.send({
|
|
content: `<@&${settings?.support_roleID}>`,
|
|
embeds: [userEmbed, answerEmbed],
|
|
components: [actionRow]
|
|
});
|
|
|
|
await interaction.editReply({
|
|
content: `You successfully created a ticket! Please check the ${channel}`,
|
|
ephemeral: true
|
|
});
|
|
|
|
db.query(
|
|
"INSERT INTO tickets (id, status, userID, guildID, channelID) VALUES (?, ?, ?, ?, ?)",
|
|
[pad(settings.ticket_counter + 1, 4), "open", interaction.user.id, interaction.guildId, channel.id]
|
|
);
|
|
} else if (interaction.customId === "close_ticket") {
|
|
const modal = new ModalBuilder()
|
|
.setTitle("Close Ticket")
|
|
.setCustomId("close_ticket_form");
|
|
|
|
const textInput = new TextInputBuilder()
|
|
.setRequired(false)
|
|
.setCustomId('input')
|
|
.setStyle("Paragraph")
|
|
.setLabel("Close message");
|
|
|
|
const actionRow = new ActionRowBuilder().addComponents(textInput);
|
|
modal.addComponents(actionRow);
|
|
|
|
return interaction.showModal(modal);
|
|
} else if (interaction.customId === "close_ticket_form") {
|
|
if (!interaction.isModalSubmit()) {
|
|
return;
|
|
}
|
|
|
|
await interaction.deferReply({ ephemeral: true });
|
|
|
|
const closeMessage = interaction.fields.getTextInputValue("input");
|
|
const transcript = await discordTranscripts.createTranscript(interaction.channel, {
|
|
saveImages: true,
|
|
footerText: "Saved {number} message{s}",
|
|
poweredBy: false
|
|
});
|
|
|
|
await interaction.editReply({
|
|
content: "You successfully closed the ticket!",
|
|
ephemeral: true
|
|
});
|
|
|
|
const ticket = await query(
|
|
db,
|
|
`SELECT * FROM tickets WHERE status='open' AND channelID='${interaction.channel.id}' AND guildID='${interaction.guildId}'`
|
|
);
|
|
const settings = await query(db, `SELECT * FROM settings WHERE guildID='${interaction.guildId}'`);
|
|
const logChannel = settings?.log_channelID;
|
|
const logChannelObj = client.channels.cache.get(logChannel);
|
|
const user = client.users.cache.get(ticket.userID);
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setTimestamp()
|
|
.setColor(ticket_settings.embed_color)
|
|
.setFooter({ text: interaction.guild.name })
|
|
.setAuthor({ name: "Ticket has been closed!" })
|
|
.addFields(
|
|
{
|
|
name: 'Ticket',
|
|
value: `\`\`\`${interaction.channel.name}\`\`\``,
|
|
inline: true
|
|
},
|
|
{
|
|
name: "Ticket Author",
|
|
value: `\`\`\`${user.tag}\`\`\``,
|
|
inline: true
|
|
},
|
|
{
|
|
name: "Server",
|
|
value: `\`\`\`${interaction.guild.name}\`\`\``,
|
|
inline: true
|
|
},
|
|
{
|
|
name: "Reason",
|
|
value: `\`\`\`${closeMessage}\`\`\``,
|
|
inline: false
|
|
}
|
|
);
|
|
|
|
await user?.send({
|
|
embeds: [embed],
|
|
files: [transcript]
|
|
}).catch(() => {});
|
|
|
|
await logChannelObj?.send({
|
|
embeds: [embed],
|
|
files: [transcript]
|
|
}).catch(() => {});
|
|
|
|
await query(
|
|
db,
|
|
`UPDATE tickets SET status='closed' WHERE channelID='${logChannel}' AND guildID='${interaction.guildId}'`
|
|
);
|
|
|
|
return interaction.channel.delete();
|
|
}
|
|
});
|
|
};
|
|
|
|
function pad(num, size) {
|
|
let numStr = num.toString();
|
|
while (numStr.length < size) {
|
|
numStr = '0' + numStr;
|
|
}
|
|
return numStr;
|
|
} |