Discord_API_Bot/helpers/interaction.js
2024-04-08 04:12:41 -06:00

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;
}