@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.
Files changed (3) hide show
  1. package/index.js +28 -59
  2. package/package.json +1 -5
  3. package/post.js +0 -12
package/index.js CHANGED
@@ -1,13 +1,12 @@
1
1
  const { Collection, WebhookClient, MessageEmbed } = require("discord.js"),
2
- { encrypt, decrypt } = require("aes256"),
3
- { generate } = require("shortid"),
4
- { Interactions: { button, modal } } = require("@elara-services/packages"),
5
- Webhook = require("discord-hook"),
6
- de = {
7
- user: "<:Members:860931214232125450>",
8
- channel: "<:Channel:841654412509839390>",
9
- transcript: "<:Log:792290922749624320>"
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
- this.getSupportIds(),
67
- () => send({ ephemeral: true, embeds: [ { author: { name: `Only support staff can close tickets`, iconURL: "https://cdn.discordapp.com/emojis/781955502035697745.gif" }, color: 0xFF0000 } ] })
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
- let user = this.options.client.users.resolve(customId.split("close:confirm:")[1]) ?? await this.options.client.users.fetch(customId.split("close:confirm:")[1]).catch(() => null);
101
- if (!user) return send({ content: `❌ I was unable to fetch the user that opened the ticket.`, ephemeral: true })
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({ ephemeral: true, content: `❌ I was unable to close the ticket, I couldn't fetch the messages in this channel.` })
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({ ephemeral: true, content: `❌ I was unable to delete the channel & close the ticket.` })
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(this.options.encryptToken, id);
230
- case "d": return decrypt(this.options.encryptToken, id);
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.1.1",
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"))