UNPKG

discord-tickets

Version:

Discord.js extention library for manage easily tickets

273 lines (272 loc) 10.4 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ThreadManager = void 0; const BaseManager_1 = require("../Base/BaseManager"); /** * @external ThreadChannel * @see {@link https://discord.js.org/#/docs/main/stable/class/ThreadChannel} */ /** * @external Client * @see {@link https://discord.js.org/#/docs/main/stable/class/Client} */ /** * @external Collection * @see {@link https://discord.js.org/#/docs/collection/stable/class/Collection} */ /** * @external Guild * @see {@link https://discord.js.org/#/docs/main/stable/class/Guild} */ /** * @external GuildMember * @see {@link https://discord.js.org/#/docs/main/stable/class/GuildMember} */ /** * @external TextChannel * @see {@link https://discord.js.org/#/docs/main/stable/class/TextChannel} */ /** * @external Role * @see {@link https://discord.js.org/#/docs/main/stable/class/Role} */ /** * @external Message * @see {@link https://discord.js.org/#/docs/main/stable/class/Message} */ const discord_js_1 = require("discord.js"); const ThreadTicket_1 = require("./ThreadTicket"); /** * Thread Ticket Manager * @extends {BaseManager} */ class ThreadManager extends BaseManager_1.BaseManager { constructor(client, options) { super(client, options); /** * The Discord Client * @readonly * @type {Client} */ if (!client) throw new Error('Client is a required option.'); this.client = client; /** * The manager options * @type {ThreadManagerOptions} */ this.options = options; /** * Collection with all tickets (tickets's cache) * @type {Collection<string, TicketData>} */ this.tickets = new discord_js_1.Collection(); this.cachingTickets().then(r => null); } /** * Caching raws tickets into Array * @return {Promise<void>} * @private */ cachingTickets() { return __awaiter(this, void 0, void 0, function* () { this.ticketRaws = yield this.getAllTickets(); if (this.options.ticketCache) { this.ticketRaws.forEach(ticket => { this.tickets.set(ticket.channel, new ThreadTicket_1.ThreadTicket(this, ticket)); }); } }); } /** * Get options * @private * @param {string} id * @return {ThreadManagerOptions} */ // @ts-ignore getOptions(id) { return __awaiter(this, void 0, void 0, function* () { return this.options; }); } /** * Create Ticket * @param {Guild} guild Discord Guild * @param {GuildMember} member Discord Guild Member * @return {Promise<TextTicket>} * @example * //Create Thread Ticket * await ticketThread.createTicket(message.guild, message.member) */ createTicket(guild, member) { return __awaiter(this, void 0, void 0, function* () { const options = yield this.getOptions(guild.id); if (!options) throw new Error("Cannot find options"); const channel = guild.channels.cache.get(options.channelId); if (!channel || channel.type !== "GUILD_TEXT") throw new Error("Cannot find tickets channel, please check id/if channel type is GUILD_TEXT"); const guildsTickets = this.ticketRaws.filter(ticket => ticket.guild === guild.id); let number; if (guildsTickets.length > 0) { number = guildsTickets.sort((ticketA, ticketB) => ticketB.number - ticketA.number)[0].number; } else number = 0; number = (parseInt(String(number)) + 1).toString(); let newNumber = "0000" + number; newNumber = newNumber.slice(newNumber.length - 4, newNumber.length + 2); const message = yield channel.send(`ticket-${newNumber}`); if (!message) throw new Error("Cannot find Message thread's creation"); let thread = yield channel.threads.create({ startMessage: message, name: `ticket-${newNumber}`, reason: `Create Thread Ticket for ${member.user.tag}`, autoArchiveDuration: "MAX", type: "GUILD_PRIVATE_THREAD", invitable: false }); yield thread.members.add(member.user); yield thread.members.add("@me"); let role = guild.roles.cache.get(options.staffRole); if (!role) throw new Error("Cannot find staff role"); role.members.forEach(m => { thread.members.add(m.user); }); const data = { guild: guild.id, channel: thread.id, member: member.id, // @ts-ignore number: number, status: "open", participants: [member.id], type: "thread" }; this.ticketRaws.push(data); yield this.saveTicketRaws(); const ticket = new ThreadTicket_1.ThreadTicket(this, data); if (this.options.ticketCache) { this.tickets.set(data.channel, new ThreadTicket_1.ThreadTicket(this, data)); } yield message.delete(); /** * Emitted when user create ticket * @event ThreadManager#ticketCreate * @param {ThreadManager} ticket Ticket resolvable */ this.emit("ticketCreate", ticket); return ticket; }); } /** * Delete Ticket * @param {TextTicket} ticket Ticket class * @return {Promise<any>} */ deleteTicket(ticket) { return __awaiter(this, void 0, void 0, function* () { yield ticket.channel.delete(); this.ticketRaws = this.ticketRaws.filter(y => y.channel !== ticket.channelId); yield this.saveTicketRaws(); if (this.options.ticketCache) { this.tickets.delete(ticket.channelId); } /** * Emitted when ticket be delete * @event ThreadManager#ticketDeleted * @param {ThreadTicket} ticket Ticket resolvable */ return this.emit("ticketDeleted", ticket); }); } /** * Close Ticket * @param {TextTicket} ticket Ticket class * @return {Promise<any>} */ closeTicket(ticket) { return __awaiter(this, void 0, void 0, function* () { yield ticket.channel.members.remove(ticket.member.id); yield ticket.channel.setArchived(true); let data = ticket.data; data.status = "closed"; ticket = new ThreadTicket_1.ThreadTicket(this, data); this.tickets.set(ticket.channelId, ticket); let index = this.ticketRaws.indexOf(data); this.ticketRaws[index] = data; yield this.saveTicketRaws(); /** * Emitted when ticket be closed * @event ThreadManager#ticketClosed * @param {TextTicket} ticket Ticket resolvable */ return this.emit("ticketClosed", ticket); }); } /** * ReOpen ticket * @param {TextTicket} ticket Ticket Resolvable * @return {Promise<any>} */ reOpenTicket(ticket) { return __awaiter(this, void 0, void 0, function* () { yield ticket.channel.setArchived(false); yield ticket.channel.members.add(ticket.member.user); let data = ticket.data; data.status = "open"; ticket = new ThreadTicket_1.ThreadTicket(this, data); this.tickets.set(ticket.channelId, ticket); let index = this.ticketRaws.indexOf(data); this.ticketRaws[index] = data; yield this.saveTicketRaws(); /** * Emitted when ticket be reopen * @event ThreadManager#ticketReOpen * @param {ThreadTicket} ticket Ticket resolvable */ return this.emit("ticketReOpen", ticket); }); } /** * Rename Ticket * @param {ThreadTicket} ticket ThreadTicket * @param {string} name new Name * @return {Promise<any>} */ renameTicket(ticket, name) { return __awaiter(this, void 0, void 0, function* () { let newNumber = "0000" + ticket.number; newNumber = newNumber.slice(newNumber.length - 4, newNumber.length + 2); yield ticket.channel.setName(`${name}-${newNumber}`); /** * Emitted when ticket be renamed * @event ThreadManager#ticketRename * @param {ThreadTicket} ticket Ticket resolvable */ return this.emit("ticketRename", ticket); }); } } exports.ThreadManager = ThreadManager; /** * Threads Ticket Manager Config Types * @typedef {object} ThreadManagerOptions * @property {boolean} enabled Manager status * @property {string} channelId Discord Channel Id where are created tickets * @property {string} staffRole Discord Role id who can access to tickets * @property {boolean} ticketCache Storing tickets in the cache * @property {StorageType} storage Storage File path */