@elara-services/tickets 2.1.1 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +28 -59
- package/package.json +1 -5
- package/post.js +0 -12
package/index.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
const { Collection, WebhookClient, MessageEmbed } = require("discord.js"),
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
2
|
+
{ generate } = require("shortid"),
|
|
3
|
+
{ Interactions: { button, modal }, AES } = require("@elara-services/packages"),
|
|
4
|
+
Webhook = require("discord-hook"),
|
|
5
|
+
de = {
|
|
6
|
+
user: "<:Members:860931214232125450>",
|
|
7
|
+
channel: "<:Channel:841654412509839390>",
|
|
8
|
+
transcript: "<:Log:792290922749624320>"
|
|
9
|
+
};
|
|
11
10
|
|
|
12
11
|
module.exports = class Tickets {
|
|
13
12
|
constructor(options = {}) {
|
|
@@ -15,7 +14,9 @@ module.exports = class Tickets {
|
|
|
15
14
|
if (!("client" in options) || !("prefix" in options) || !("encryptToken" in options)) throw new Error(`You forgot to fill out either 'client', 'prefix' or 'encryptToken'`)
|
|
16
15
|
this.options = options;
|
|
17
16
|
};
|
|
17
|
+
|
|
18
18
|
get prefix() { return `system:ticket:${this.options.prefix}`; };
|
|
19
|
+
|
|
19
20
|
/** @private */
|
|
20
21
|
get webhookOptions() {
|
|
21
22
|
return {
|
|
@@ -25,6 +26,7 @@ module.exports = class Tickets {
|
|
|
25
26
|
avatar: this.options.webhook?.avatar || this.options.webhookAvatar || "https://cdn.discordapp.com/emojis/818757771310792704.png?v=1"
|
|
26
27
|
}
|
|
27
28
|
}
|
|
29
|
+
|
|
28
30
|
webhook() {
|
|
29
31
|
const { id, token, username, avatar } = this.webhookOptions;
|
|
30
32
|
return new Webhook(`https://discord.com/api/webhooks/${id}/${token}`, { username, avatar_url: avatar });
|
|
@@ -51,31 +53,22 @@ module.exports = class Tickets {
|
|
|
51
53
|
};
|
|
52
54
|
switch (customId) {
|
|
53
55
|
case this.prefix: {
|
|
54
|
-
if (this.options.modal?.enabled) {
|
|
55
|
-
return int.showModal(this.modal({
|
|
56
|
-
title: this.options.modal.title,
|
|
57
|
-
components: this.options.modal.questions?.length >= 1 ? this.options.modal.questions.slice(0, 5).map(c => ({ type: 1, components: [{ min_length: c.min_length || 10, max_length: c.max_length || 4000, type: 4, style: c.style || 2, label: c.label, value: c.value, placeholder: c.placeholder, required: c.required, custom_id: c.label || `random_${Math.floor(Math.random() * 10000)}` }] })) : []
|
|
58
|
-
})).catch(e => this._debug(e));
|
|
59
|
-
}
|
|
56
|
+
if (this.options.modal?.enabled) return int.showModal(this.modal({ title: this.options.modal.title, components: this.options.modal.questions?.length >= 1 ? this.options.modal.questions.slice(0, 5).map(c => ({ type: 1, components: [{ min_length: c.min_length || 10, max_length: c.max_length || 4000, type: 4, style: c.style || 2, label: c.label, value: c.value, placeholder: c.placeholder, required: c.required, custom_id: c.label || `random_${Math.floor(Math.random() * 10000)}` }] })) : [] })).catch(e => this._debug(e));
|
|
60
57
|
return this.handleCreate({ guild, member, category, send })
|
|
61
58
|
};
|
|
62
59
|
|
|
63
60
|
case `${this.prefix}:close`: {
|
|
64
61
|
if (this.options.support?.canOnlyCloseTickets && !member.permissions.has("MANAGE_GUILD")) {
|
|
65
|
-
let [ support, staffOnly ] = [
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (!support.users?.includes?.(member.id)) return staffOnly();
|
|
70
|
-
if (support.roles?.length && !support.roles.some(c => member.roles.cache.has(c))) return staffOnly()
|
|
62
|
+
let [ support, staffOnly ] = [ this.getSupportIds(), () => send({ ephemeral: true, embeds: [ { author: { name: `Only support staff can close tickets`, iconURL: "https://cdn.discordapp.com/emojis/781955502035697745.gif" }, color: 0xFF0000 } ] }) ];
|
|
63
|
+
if (!support.users?.includes?.(member.id)) {
|
|
64
|
+
if (!support.roles?.some?.(c => member.roles.cache.has(c))) return staffOnly()
|
|
65
|
+
}
|
|
71
66
|
}
|
|
72
67
|
return send({ ephemeral: true, content: `🤔 Are you sure you want to close this ticket?`, components: [{ type: 1, components: [{ type: 2, custom_id: `${this.prefix}:close:confirm:${this.code(channel.topic?.split?.("ID: ")?.[1])}`, label: "Yes close the ticket", style: 4, emoji: { id: "807031399563264030" } }] }] })
|
|
73
68
|
}
|
|
74
69
|
|
|
75
70
|
case `${this.prefix}:modal_submit`: {
|
|
76
|
-
let [embed, fields, split] = [
|
|
77
|
-
new MessageEmbed().setColor("ORANGE").setTimestamp().setTitle(`For Responses`).setFooter({ text: `ID: ${member.id}` }).setAuthor({ name: member.user.username, iconURL: member.user.displayAvatarURL({ dynamic: true }) }),
|
|
78
|
-
[], false];
|
|
71
|
+
let [ embed, fields, split ] = [ new MessageEmbed().setColor("ORANGE").setTimestamp().setTitle(`For Responses`).setFooter({ text: `ID: ${member.id}` }).setAuthor({ name: member.user.username, iconURL: member.user.displayAvatarURL({ dynamic: true }) }), [], false];
|
|
79
72
|
for (const c of int.fields.components) {
|
|
80
73
|
for (const cc of c.components) {
|
|
81
74
|
if (cc.value && cc.customId) {
|
|
@@ -97,12 +90,13 @@ module.exports = class Tickets {
|
|
|
97
90
|
}
|
|
98
91
|
};
|
|
99
92
|
if (customId.startsWith(`${this.prefix}:close:confirm`)) {
|
|
100
|
-
|
|
101
|
-
|
|
93
|
+
await send({ ephemeral: true }, true);
|
|
94
|
+
let user = await this.options.client.users.fetch(customId.split("close:confirm:")[1]).catch(() => null);
|
|
95
|
+
if (!user) return send({ content: `❌ I was unable to fetch the user that opened the ticket.` })
|
|
102
96
|
let messages = await this.fetchMessages(channel, 5000);
|
|
103
|
-
if (!messages?.length) return send({
|
|
97
|
+
if (!messages?.length) return send({ content: `❌ I was unable to close the ticket, I couldn't fetch the messages in this channel.` })
|
|
104
98
|
let closed = await channel.delete(`${member.user.tag} (${member.id}) closed the ticket.`).catch(e => this._debug(e));
|
|
105
|
-
if (!closed) return send({
|
|
99
|
+
if (!closed) return send({ content: `❌ I was unable to delete the channel & close the ticket.` })
|
|
106
100
|
return this.closeTicket({ channel, guild, user, member, messages });
|
|
107
101
|
}
|
|
108
102
|
};
|
|
@@ -151,8 +145,6 @@ module.exports = class Tickets {
|
|
|
151
145
|
}
|
|
152
146
|
}
|
|
153
147
|
}
|
|
154
|
-
|
|
155
|
-
/** @type {import("discord.js").TextChannel} */
|
|
156
148
|
let channel = await guild.channels.create(`${this.options.prefix}-${generate().slice(0, 5).replace(/-|_/g, "")}`, {
|
|
157
149
|
type: "GUILD_TEXT", parent: category, reason: `Ticket created by: @${member.user.tag} (${member.id})`,
|
|
158
150
|
topic: `ID: ${this.code(member.id, "e")}`,
|
|
@@ -202,11 +194,7 @@ module.exports = class Tickets {
|
|
|
202
194
|
* @param {import("@elara-services/packages").Modal['components']} [options.components]
|
|
203
195
|
*/
|
|
204
196
|
modal(options = { title: "", components: [] }) {
|
|
205
|
-
return modal({
|
|
206
|
-
id: `${this.prefix}:modal_submit`,
|
|
207
|
-
title: options?.title || "Create Ticket",
|
|
208
|
-
components: options?.components?.length >= 1 ? options.components : [ { type: 1, components: [ { type: 4, min_length: 10, max_length: 4000, custom_id: "message", label: "Content", style: 2, placeholder: "What's the ticket about?", required: true } ] } ]
|
|
209
|
-
})
|
|
197
|
+
return modal({ id: `${this.prefix}:modal_submit`, title: options?.title || "Create Ticket", components: options?.components?.length >= 1 ? options.components : [ { type: 1, components: [ { type: 4, min_length: 10, max_length: 4000, custom_id: "message", label: "Content", style: 2, placeholder: "What's the ticket about?", required: true } ] } ] })
|
|
210
198
|
}
|
|
211
199
|
|
|
212
200
|
async starterMessage(channelId, options) {
|
|
@@ -214,20 +202,16 @@ module.exports = class Tickets {
|
|
|
214
202
|
if (!channel) return Promise.reject(`No channel found for: ${channelId}`);
|
|
215
203
|
if (!channel.isText()) return Promise.reject(`The channel ID provided isn't a text-based-channel`);
|
|
216
204
|
if (!channel.permissionsFor?.(this.options.client.user.id)?.has?.(["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS", "ATTACH_FILES", "READ_MESSAGE_HISTORY"])) return Promise.reject(`I'm missing permissions in ${channel.name} (${channelId})`);
|
|
217
|
-
return channel.send({
|
|
218
|
-
content: options?.content,
|
|
219
|
-
files: options?.attachments,
|
|
220
|
-
embeds: options?.embeds,
|
|
221
|
-
components: options?.components || [{ type: 1, components: [this.button()] }]
|
|
222
|
-
})
|
|
205
|
+
return channel.send({ content: options?.content, files: options?.attachments, embeds: options?.embeds, components: options?.components || [{ type: 1, components: [this.button()] }] })
|
|
223
206
|
.then(() => console.log(`Sent the starter message in ${channel.name} (${channel.id})`))
|
|
224
207
|
};
|
|
225
208
|
|
|
226
209
|
code(id, type = "d") {
|
|
227
210
|
try {
|
|
211
|
+
const aes = new AES(this.options.encryptToken);
|
|
228
212
|
switch (type) {
|
|
229
|
-
case "e": return encrypt(
|
|
230
|
-
case "d": return decrypt(
|
|
213
|
+
case "e": return aes.encrypt(id);
|
|
214
|
+
case "d": return aes.decrypt(id);
|
|
231
215
|
}
|
|
232
216
|
} catch {
|
|
233
217
|
return id;
|
|
@@ -252,13 +236,6 @@ module.exports = class Tickets {
|
|
|
252
236
|
return [...(await channel.messages.fetch({ limit, before, after, around }).catch(() => new Collection())).values()];
|
|
253
237
|
};
|
|
254
238
|
|
|
255
|
-
/**
|
|
256
|
-
* @param {import("discord.js").TextBasedChannel} channel
|
|
257
|
-
* @param {import("discord.js").Message[]} messages
|
|
258
|
-
* @param {string} ticketID
|
|
259
|
-
* @param {string} type
|
|
260
|
-
* @returns {string}
|
|
261
|
-
*/
|
|
262
239
|
displayMessages(channel, messages = [], ticketID, type) {
|
|
263
240
|
let users = [];
|
|
264
241
|
for (const i of messages.values()) {
|
|
@@ -359,15 +336,7 @@ module.exports = class Tickets {
|
|
|
359
336
|
}).catch(e => this._debug(e));
|
|
360
337
|
}).catch(e => this._debug(e));
|
|
361
338
|
};
|
|
362
|
-
|
|
363
|
-
* @typedef {Object} getSupportResponse
|
|
364
|
-
* @property {string[]} [roles]
|
|
365
|
-
* @property {string[]} [users]
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
* @private
|
|
369
|
-
* @returns {getSupportResponse}
|
|
370
|
-
*/
|
|
339
|
+
|
|
371
340
|
getSupportIds() {
|
|
372
341
|
return {
|
|
373
342
|
roles: this.options.support?.roles || this.options.supportRoleIds || [],
|
package/package.json
CHANGED
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elara-services/tickets",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Helper for tickets",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
7
|
"typings": "index.d.ts",
|
|
8
8
|
"author": "SUPERCHIEFYT (Elara-Discord-Bots, Elara-Services)",
|
|
9
9
|
"license": "MIT",
|
|
10
|
-
"scripts": {
|
|
11
|
-
"postinstall": "node post.js"
|
|
12
|
-
},
|
|
13
10
|
"optionalDependencies": {
|
|
14
11
|
"discord.js": "13.8.1"
|
|
15
12
|
},
|
|
16
13
|
"dependencies": {
|
|
17
14
|
"@elara-services/packages": "5.0.0",
|
|
18
|
-
"aes256": "1.1.0",
|
|
19
15
|
"discord-hook": "2.0.0",
|
|
20
16
|
"shortid": "2.2.16"
|
|
21
17
|
}
|
package/post.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
const package = require("./package.json");
|
|
2
|
-
console.log([
|
|
3
|
-
`Package: ${package.name}`,
|
|
4
|
-
`────────────────────────`,
|
|
5
|
-
`Thanks for installing the package!`,
|
|
6
|
-
`Version you installed: ${package.version}`,
|
|
7
|
-
`─────────────────────────────────────────`,
|
|
8
|
-
`To get started look at the 'Getting Started' section on the npm page here: https://www.npmjs.com/package/@elara-services/tickets`,
|
|
9
|
-
`Here is some helpful links:`,
|
|
10
|
-
`Source Code: https://github.com/elara-bots/tickets`,
|
|
11
|
-
`Support: https://discord.gg/qafHJ63`
|
|
12
|
-
].join("\n"))
|