@elara-services/tickets 3.1.6 → 4.0.0
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/.eslintrc.json +15 -8
- package/.prettierrc +4 -0
- package/README.md +23 -1
- package/index.d.ts +82 -20
- package/index.js +15 -8
- package/languages/en-US.js +63 -36
- package/lib/base.js +170 -47
- package/lib/util.js +276 -79
- package/lib/v13.js +453 -153
- package/lib/v14.js +449 -197
- package/package.json +9 -6
package/.eslintrc.json
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"env": {
|
|
3
3
|
"node": true,
|
|
4
|
-
"commonjs": true,
|
|
5
4
|
"es2021": true
|
|
6
5
|
},
|
|
7
|
-
"extends":
|
|
6
|
+
"extends": [
|
|
7
|
+
"eslint:recommended"
|
|
8
|
+
],
|
|
9
|
+
"overrides": [
|
|
10
|
+
],
|
|
8
11
|
"parserOptions": {
|
|
9
|
-
"ecmaVersion":
|
|
12
|
+
"ecmaVersion": "latest",
|
|
13
|
+
"sourceType": "module"
|
|
10
14
|
},
|
|
15
|
+
"plugins": [],
|
|
11
16
|
"rules": {
|
|
12
|
-
"no-
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"no-
|
|
17
|
+
"no-empty-function": 0,
|
|
18
|
+
"semi": ["error", "always"],
|
|
19
|
+
"curly": ["error", "all"],
|
|
20
|
+
"no-var-requires": 0,
|
|
21
|
+
"object-shorthand": "error"
|
|
16
22
|
},
|
|
17
23
|
"ignorePatterns": [
|
|
18
|
-
"
|
|
24
|
+
"**/*.json",
|
|
25
|
+
"node_modules/*"
|
|
19
26
|
]
|
|
20
27
|
}
|
package/.prettierrc
ADDED
package/README.md
CHANGED
|
@@ -84,4 +84,26 @@ client.on("ready", () => {
|
|
|
84
84
|
});
|
|
85
85
|
|
|
86
86
|
client.login("BOT TOKEN HERE")
|
|
87
|
-
```
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
## Want to have a select menu instead of button(s)?
|
|
91
|
+
> Just use `<Ticket>.prefix` for the select menu option value
|
|
92
|
+
```js
|
|
93
|
+
{
|
|
94
|
+
"custom_id": "....", // This can be anything.
|
|
95
|
+
"max_values": 1,
|
|
96
|
+
"min_values": 1,
|
|
97
|
+
"placeholder": "Select a ticket type below",
|
|
98
|
+
"options": [
|
|
99
|
+
{ "label": "Support", "value": supportTicket.prefix, "description": "Open an Support ticket for x, y, z." },
|
|
100
|
+
{ "label": "Moderator", "value": modTicket.prefix, "description": "Open an Moderator ticket for x, y, z." },
|
|
101
|
+
// etc.
|
|
102
|
+
// Just make sure you use `<Ticket>.prefix` for the value of the option.
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
# Want to make the bot / responses be in a certain lagnauge?
|
|
108
|
+
Make a PR request with the language you would like to see in [elara-bots/npm](https://github.com/elara-bots/npm) GitHub repo
|
|
109
|
+
- Copy the contents of `./languages/en-US.js`
|
package/index.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
declare module "@elara-services/tickets" {
|
|
2
2
|
|
|
3
|
-
import { Client, MessageOptions, GuildMember, Guild, User, TextBasedChannel, Message, Interaction
|
|
4
|
-
|
|
3
|
+
import { Client, MessageOptions, GuildMember, Guild, User, TextBasedChannel, Message, Interaction } from "discord.js";
|
|
4
|
+
|
|
5
|
+
type Langs = "en-US";
|
|
5
6
|
|
|
6
7
|
export interface TicketOptions {
|
|
7
8
|
client: Client;
|
|
8
9
|
prefix: string;
|
|
10
|
+
lang?: Langs;
|
|
9
11
|
debug?: boolean;
|
|
10
12
|
encryptToken: string;
|
|
11
13
|
appeals?: {
|
|
@@ -35,6 +37,7 @@ declare module "@elara-services/tickets" {
|
|
|
35
37
|
webhook?: {
|
|
36
38
|
id?: string;
|
|
37
39
|
token?: string;
|
|
40
|
+
threadId?: string;
|
|
38
41
|
username?: string;
|
|
39
42
|
avatar?: string
|
|
40
43
|
};
|
|
@@ -50,39 +53,98 @@ declare module "@elara-services/tickets" {
|
|
|
50
53
|
limitOnePerUser?: boolean;
|
|
51
54
|
open?: Pick<MessageOptions, "content" | "embeds">
|
|
52
55
|
}
|
|
56
|
+
}
|
|
53
57
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
interface LangFile {
|
|
59
|
+
NO_BAN_PERMS_USER_IN_APPEAL_SERVER(server: Guild): string;
|
|
60
|
+
NOT_FOUND_IN_APPEAL_SERVER(server: Guild): string;
|
|
61
|
+
TICKET_LIMIT_ONE_PER_USER(name: string): string;
|
|
62
|
+
NO_CONSTRUCTOR_OPTIONS(name?: string): string;
|
|
63
|
+
NO_CHANNEL_FOUND(id: string): string;
|
|
64
|
+
USER_NOT_BANNED(id: string): string;
|
|
65
|
+
UNBAN_FAILED(id: string, serverName: string): string;
|
|
66
|
+
UNBAN_SUCCESS(id: string, serverName: string): string;
|
|
67
|
+
ID(id?: string): string;
|
|
58
68
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
OPEN_TICKET_MESSAGE_CONTENT: string;
|
|
70
|
+
TICKET_CLOSE_CONFIRM_BUTTON: string;
|
|
71
|
+
OPEN_TICKET_MESSAGE_FOOTER: string;
|
|
72
|
+
MODAL_CONTENT_PLACEHOLDER: string;
|
|
73
|
+
CLOSE_TICKET_FIELD_REASON: string;
|
|
74
|
+
OPEN_TICKET_AUDIT_REASON: string;
|
|
75
|
+
TICKET_CLOSE_PLACEHOLDER: string;
|
|
76
|
+
NO_APPEAL_SERVER_FOUND: string;
|
|
77
|
+
NOT_BANNED_MAIN_SERVER: string;
|
|
78
|
+
TICKET_CLOSE_CONFIRM: string;
|
|
79
|
+
NO_MESSAGES_FETCHED: string;
|
|
80
|
+
OPEN_TICKET_MESSAGE: string;
|
|
81
|
+
OPEN_TICKET_CREATE: string;
|
|
82
|
+
CLOSE_TICKET_TITLE: string;
|
|
83
|
+
OPEN_TICKET_TITLE: string;
|
|
84
|
+
NO_CHANNEL_CREATE: string;
|
|
85
|
+
NO_CHANNEL_DELETE: string;
|
|
86
|
+
NO_BAN_PERMS_USER: string;
|
|
87
|
+
TICKET_BLOCKED: string;
|
|
88
|
+
FORM_RESPONSES: string;
|
|
89
|
+
NO_USER_FOUND: string;
|
|
90
|
+
CREATE_TICKET: string;
|
|
91
|
+
CLOSED_TICKET: string;
|
|
92
|
+
FORM_RESPONSE: string;
|
|
93
|
+
MODAL_CONTENT: string;
|
|
94
|
+
ONLY_SUPPORT: string;
|
|
95
|
+
GO_TO_TICKET: string;
|
|
96
|
+
CLOSE_TICKET: string;
|
|
97
|
+
BAN_REASON: string;
|
|
98
|
+
UNBAN_FROM: string;
|
|
99
|
+
TRANSCRIPT: string;
|
|
100
|
+
TICKET_ID: string;
|
|
101
|
+
VIEW_HERE: string;
|
|
102
|
+
NO_REASON: string;
|
|
103
|
+
CLOSED_BY: string;
|
|
104
|
+
UNBANNED: string;
|
|
105
|
+
TICKETS: string;
|
|
106
|
+
CHANNEL: string;
|
|
107
|
+
REASON: string;
|
|
108
|
+
UNBAN: string;
|
|
109
|
+
ERROR: string;
|
|
110
|
+
USER: string;
|
|
111
|
+
INFO: string;
|
|
112
|
+
BY: string;
|
|
64
113
|
}
|
|
65
114
|
|
|
66
115
|
class Tickets {
|
|
67
116
|
public constructor(options: TicketOptions);
|
|
68
117
|
public options: TicketOptions;
|
|
69
118
|
public prefix: string;
|
|
70
|
-
|
|
119
|
+
|
|
120
|
+
private _debug(...args: unknown[]): unknown;
|
|
121
|
+
|
|
122
|
+
public get webhookOptions(): {
|
|
123
|
+
id: string | undefined;
|
|
124
|
+
token: string | undefined;
|
|
125
|
+
threadId: string | undefined;
|
|
126
|
+
username: string;
|
|
127
|
+
avatar: string;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
public get getSupportIds(): {
|
|
131
|
+
roles: string[];
|
|
132
|
+
users: string[];
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
public str(name: keyof LangFile): string;
|
|
136
|
+
|
|
71
137
|
public button(options: { style: 1 | 2 | 3 | 4 | 5 | number, id?: string, label?: string, emoji?: { name?: string, id?: string } }): { type: number, custom_id: string, style: number, label?: string, emoji?: { name?: string, id?: string } }
|
|
72
|
-
|
|
73
|
-
public fetchMessages(channel: TextBasedChannel, limit?: number, before?: string, after?: string, around?: string): Promise<Array<Message>>
|
|
74
|
-
public displayMessages(channel: TextBasedChannel, messages: Array<Message>, ticketID: string, type: string): string;
|
|
75
138
|
public closeTicket(options: {
|
|
76
139
|
member: GuildMember,
|
|
77
140
|
guild: Guild,
|
|
78
141
|
user: User,
|
|
79
|
-
messages:
|
|
142
|
+
messages: Message[],
|
|
80
143
|
channel: TextBasedChannel
|
|
81
|
-
}): Promise<
|
|
144
|
+
}): Promise<unknown>;
|
|
82
145
|
|
|
83
|
-
public
|
|
84
|
-
public
|
|
85
|
-
public starterMessage(channelId: string, options?: Pick<MessageOptions, "embeds" | "content" | "components" | "attachments">): Promise<void>;
|
|
146
|
+
public run(int: Interaction): Promise<unknown>;
|
|
147
|
+
public starterMessage(channelId: string, options?: Pick<MessageOptions, "embeds" | "content" | "components" | "attachments">): Promise<unknown>;
|
|
86
148
|
};
|
|
87
149
|
|
|
88
150
|
export = Tickets;
|
package/index.js
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
const pack = require("./package.json");
|
|
2
|
+
const { version } = require("discord.js");
|
|
2
3
|
|
|
3
4
|
module.exports = (() => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
let [
|
|
8
|
-
if (major === "14")
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
if (!version) {
|
|
6
|
+
throw new Error(`[${pack.name}, v${pack.version}]: I was unable to find the discord.js version you're using.`);
|
|
7
|
+
}
|
|
8
|
+
let [major] = version.split(".");
|
|
9
|
+
if (major === "14") {
|
|
10
|
+
return require("./lib/v14");
|
|
11
|
+
}
|
|
12
|
+
if (major === "13") {
|
|
13
|
+
return require("./lib/v13");
|
|
14
|
+
}
|
|
15
|
+
if (["12", "11"].includes(major)) {
|
|
16
|
+
throw new Error(`[${pack.name}, v${pack.version}]: The discord.js version you're using is outdated and unsupported, please update to v13+`);
|
|
17
|
+
}
|
|
11
18
|
throw new Error(`[${pack.name}, v${pack.version}]: The discord.js version you're using isn't supported by this package. (currently supported: v13, v14)`);
|
|
12
|
-
})();
|
|
19
|
+
})();
|
package/languages/en-US.js
CHANGED
|
@@ -1,36 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
TICKET_CLOSE_CONFIRM:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
1
|
+
const y = "✅";
|
|
2
|
+
const x = "❌";
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
// Functions
|
|
6
|
+
NO_BAN_PERMS_USER_IN_APPEAL_SERVER: (server) => `${x} You need (Ban Members) in ${server.name} to complete this action!`,
|
|
7
|
+
NOT_FOUND_IN_APPEAL_SERVER: (server) => `${x} I was unable to find you in ${server.name}!`,
|
|
8
|
+
TICKET_LIMIT_ONE_PER_USER: (name = "") => `${x} You can only create one (${name}) ticket at a time.`,
|
|
9
|
+
NO_CONSTRUCTOR_OPTIONS: (name = "") => (name ? `You didn't provide any data in the constructor, fill it out!` : `You forgot to fill out either ${name}`),
|
|
10
|
+
NO_CHANNEL_FOUND: (id) => `${x} No channel found for: ${id}`,
|
|
11
|
+
USER_NOT_BANNED: (id) => `${x} User (<@${id}>) isn't banned in the main server!`,
|
|
12
|
+
UNBAN_FAILED: (id, serverName) => `${x} Unable to unban <@${id} from ${serverName}!`,
|
|
13
|
+
UNBAN_SUCCESS: (id, serverName) => `${y} Successfully unbanned <@${id}> from ${serverName}!`,
|
|
14
|
+
ID: (id = "") => `ID: ${id}`,
|
|
15
|
+
|
|
16
|
+
// Strings
|
|
17
|
+
OPEN_TICKET_MESSAGE_CONTENT: "👋 Hello, please explain what you need help with.",
|
|
18
|
+
TICKET_CLOSE_CONFIRM_BUTTON: "Yes, close the ticket!",
|
|
19
|
+
OPEN_TICKET_MESSAGE_FOOTER: "To close the ticket, press the button below",
|
|
20
|
+
MODAL_CONTENT_PLACEHOLDER: "What's the ticket about?",
|
|
21
|
+
CLOSE_TICKET_FIELD_REASON: "Close Reason",
|
|
22
|
+
OPEN_TICKET_AUDIT_REASON: "Ticket created by:",
|
|
23
|
+
TICKET_CLOSE_PLACEHOLDER: "What's the reason for closing the ticket?",
|
|
24
|
+
NO_APPEAL_SERVER_FOUND: `${x} I was unable to find the appeal server!`,
|
|
25
|
+
NOT_BANNED_MAIN_SERVER: `${x} You can't open this ticket due to you not being banned in the main server!`,
|
|
26
|
+
TICKET_CLOSE_CONFIRM: "🤔 Are you sure you want to close the ticket?",
|
|
27
|
+
NO_MESSAGES_FETCHED: `${x} I was unable to close the ticket, I couldn't fetch the messages in this channel.`,
|
|
28
|
+
OPEN_TICKET_MESSAGE: "Support will be with you shortly.",
|
|
29
|
+
OPEN_TICKET_CREATE: "Ticket Created!",
|
|
30
|
+
CLOSE_TICKET_TITLE: "Ticket: Closed",
|
|
31
|
+
OPEN_TICKET_TITLE: "Ticket: Opened",
|
|
32
|
+
NO_CHANNEL_CREATE: `${x} I was unable to create the ticket channel, if this keeps happening contact one of the staff members via their DMs!`,
|
|
33
|
+
NO_CHANNEL_DELETE: `${x} I was unable to delete the channel and close the ticket.`,
|
|
34
|
+
NO_BAN_PERMS_USER: `${x} You need (Ban Members) in this server to complete this action!`,
|
|
35
|
+
TICKET_BLOCKED: `${x} You can't create tickets, if you believe this is a mistake contact one of the staff members.`,
|
|
36
|
+
FORM_RESPONSES: "Form Responses",
|
|
37
|
+
TOTAL_MESSAGES: "Total Messages",
|
|
38
|
+
NO_USER_FOUND: `${x} I was unable to fetch the user that opened the ticket.`,
|
|
39
|
+
CREATE_TICKET: "Create Ticket",
|
|
40
|
+
CLOSED_TICKET: "closed the ticket.",
|
|
41
|
+
FORM_RESPONSE: "Form Response",
|
|
42
|
+
MODAL_CONTENT: "Content",
|
|
43
|
+
ONLY_SUPPORT: "Only support staff can close tickets",
|
|
44
|
+
GO_TO_TICKET: "Go to ticket",
|
|
45
|
+
CLOSE_TICKET: "Close Ticket",
|
|
46
|
+
BAN_REASON: "Ban Reason",
|
|
47
|
+
UNBAN_FROM: "Unban From",
|
|
48
|
+
TRANSCRIPT: "Transcript",
|
|
49
|
+
TICKET_ID: "Ticket ID:",
|
|
50
|
+
VIEW_HERE: "View here",
|
|
51
|
+
NO_REASON: "No Reason Provided",
|
|
52
|
+
CLOSED_BY: "Closed By:",
|
|
53
|
+
UNBANNED: "Unbanned!",
|
|
54
|
+
TICKETS: "Tickets",
|
|
55
|
+
CHANNEL: "Channel",
|
|
56
|
+
TICKET: "Ticket",
|
|
57
|
+
REASON: "Reason",
|
|
58
|
+
UNBAN: "Unban",
|
|
59
|
+
ERROR: "ERROR",
|
|
60
|
+
USER: "User",
|
|
61
|
+
INFO: "INFO",
|
|
62
|
+
BY: "By",
|
|
63
|
+
};
|
package/lib/base.js
CHANGED
|
@@ -1,81 +1,204 @@
|
|
|
1
|
-
const { getWebhookInfo, displayMessages, de, webhook, getString } = require("./util")
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
const { getWebhookInfo, displayMessages, de, webhook, getString } = require("./util");
|
|
2
|
+
const {
|
|
3
|
+
Interactions: { button, modal },
|
|
4
|
+
} = require("@elara-services/packages");
|
|
5
|
+
const { is } = require("@elara-services/utils");
|
|
6
|
+
const { WebhookClient } = require("discord.js");
|
|
7
|
+
const required = ["client", "prefix", "encryptToken"];
|
|
4
8
|
|
|
5
9
|
module.exports = class Tickets {
|
|
10
|
+
/**
|
|
11
|
+
* @param {import("@elara-services/tickets").TicketOptions} options
|
|
12
|
+
*/
|
|
6
13
|
constructor(options) {
|
|
7
|
-
if (
|
|
8
|
-
|
|
14
|
+
if (!is.object(options)) {
|
|
15
|
+
throw new Error(this.str("NO_CONSTRUCTOR_OPTIONS")());
|
|
16
|
+
}
|
|
17
|
+
for (const r of required) {
|
|
18
|
+
if (!(r in options)) {
|
|
19
|
+
throw new Error(this.str("NO_CONSTRUCTOR_OPTIONS")(`'${r}'`));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
9
22
|
this.options = options;
|
|
10
23
|
}
|
|
11
|
-
get prefix() {
|
|
12
|
-
|
|
24
|
+
get prefix() {
|
|
25
|
+
return `system:ticket:${this.options.prefix}`;
|
|
26
|
+
}
|
|
27
|
+
get webhookOptions() {
|
|
28
|
+
return getWebhookInfo(this.options, this.str("TICKETS"));
|
|
29
|
+
}
|
|
13
30
|
get getSupportIds() {
|
|
14
31
|
return {
|
|
15
32
|
roles: this.options.support?.roles || [],
|
|
16
|
-
users: this.options.support?.users || []
|
|
17
|
-
}
|
|
33
|
+
users: this.options.support?.users || [],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @param {keyof typeof import("../languages/en-US")} name
|
|
38
|
+
*/
|
|
39
|
+
str(name) {
|
|
40
|
+
return getString(name, this.options?.lang || "en-US");
|
|
18
41
|
}
|
|
19
|
-
|
|
20
|
-
|
|
42
|
+
|
|
21
43
|
/** @private */
|
|
22
44
|
_debug(...args) {
|
|
23
|
-
if (this.options?.debug)
|
|
45
|
+
if (this.options?.debug) {
|
|
46
|
+
console.log(...args);
|
|
47
|
+
}
|
|
24
48
|
return null;
|
|
25
49
|
}
|
|
26
50
|
|
|
27
|
-
button(
|
|
28
|
-
|
|
29
|
-
|
|
51
|
+
button(
|
|
52
|
+
options = {
|
|
53
|
+
style: 3,
|
|
54
|
+
label: this.str("CREATE_TICKET"),
|
|
55
|
+
emoji: { name: "📩" },
|
|
56
|
+
},
|
|
57
|
+
) {
|
|
58
|
+
return button({
|
|
59
|
+
id: options?.id || this.prefix,
|
|
60
|
+
style: options.style || 3,
|
|
61
|
+
title: options.label,
|
|
62
|
+
emoji: options.emoji,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
30
65
|
|
|
31
66
|
/**
|
|
32
|
-
* @param {object} options
|
|
33
|
-
* @param {string} [options.title] The title of the modal submit form
|
|
67
|
+
* @param {object} options
|
|
68
|
+
* @param {string} [options.title] The title of the modal submit form
|
|
34
69
|
* @param {import("@elara-services/packages").Modal['components']} [options.components]
|
|
35
70
|
*/
|
|
36
71
|
modal(options = { title: "", components: [] }) {
|
|
37
|
-
return modal({
|
|
38
|
-
|
|
72
|
+
return modal({
|
|
73
|
+
id: `${this.prefix}:modal_submit`,
|
|
74
|
+
title: options?.title || this.str("CREATE_TICKET"),
|
|
75
|
+
components:
|
|
76
|
+
options?.components?.length >= 1
|
|
77
|
+
? options.components
|
|
78
|
+
: [
|
|
79
|
+
{
|
|
80
|
+
type: 1,
|
|
81
|
+
components: [
|
|
82
|
+
{
|
|
83
|
+
type: 4,
|
|
84
|
+
min_length: 10,
|
|
85
|
+
max_length: 4000,
|
|
86
|
+
custom_id: "message",
|
|
87
|
+
label: this.str("MODAL_CONTENT"),
|
|
88
|
+
style: 2,
|
|
89
|
+
placeholder: this.str("MODAL_CONTENT_PLACEHOLDER"),
|
|
90
|
+
required: true,
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
});
|
|
96
|
+
}
|
|
39
97
|
|
|
40
98
|
async closeTicket({ member, messages, channel, guild, user, reason } = {}) {
|
|
41
|
-
const { id, token, username, avatar: avatarURL } = this.webhookOptions;
|
|
42
|
-
if (!id || !token)
|
|
99
|
+
const { id, token, username, avatar: avatarURL, threadId } = this.webhookOptions;
|
|
100
|
+
if (!id || !token) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
43
103
|
let embeds = [
|
|
44
104
|
{
|
|
45
|
-
author: {
|
|
105
|
+
author: {
|
|
106
|
+
name: guild.name,
|
|
107
|
+
icon_url: guild.iconURL({ dynamic: true }),
|
|
108
|
+
},
|
|
46
109
|
title: this.str("CLOSE_TICKET_TITLE"),
|
|
47
|
-
description: `${de.user}
|
|
48
|
-
color:
|
|
49
|
-
fields: reason
|
|
110
|
+
description: `${de.user} ${this.str("USER")}: ${user.toString()} \`@${user.tag}\` (${user.id})\n${de.user} ${this.str("CLOSED_BY")} ${member.toString()} (${member.id})\n${de.channel} ${this.str("CHANNEL")}: \`#${channel.name}\` (${channel.id})`,
|
|
111
|
+
color: 0xff0000,
|
|
112
|
+
fields: reason
|
|
113
|
+
? [
|
|
114
|
+
{
|
|
115
|
+
name: this.str("CLOSE_TICKET_FIELD_REASON"),
|
|
116
|
+
value: reason?.slice?.(0, 1024) ?? this.str("NO_REASON"),
|
|
117
|
+
},
|
|
118
|
+
]
|
|
119
|
+
: undefined,
|
|
50
120
|
timestamp: new Date(),
|
|
51
|
-
footer: {
|
|
52
|
-
|
|
121
|
+
footer: {
|
|
122
|
+
text: `${this.str("TICKET_ID")} ${channel.name.split("-")[1]}`,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
53
125
|
];
|
|
54
126
|
new WebhookClient({ id, token })
|
|
55
127
|
.send({
|
|
56
|
-
username,
|
|
128
|
+
username,
|
|
129
|
+
avatarURL,
|
|
57
130
|
embeds,
|
|
58
|
-
|
|
131
|
+
threadId,
|
|
132
|
+
files: [
|
|
133
|
+
{
|
|
134
|
+
name: `${this.str("TRANSCRIPT")}.txt`,
|
|
135
|
+
attachment: Buffer.from(displayMessages(channel, messages.reverse(), channel.name.split("-")[1], this.options.prefix, this.str)),
|
|
136
|
+
},
|
|
137
|
+
],
|
|
59
138
|
})
|
|
60
|
-
.then(m => {
|
|
61
|
-
let components = [
|
|
62
|
-
|
|
139
|
+
.then((m) => {
|
|
140
|
+
let components = [
|
|
141
|
+
{
|
|
142
|
+
type: 2,
|
|
143
|
+
style: 5,
|
|
144
|
+
label: this.str("TRANSCRIPT"),
|
|
145
|
+
emoji: { id: "792290922749624320" },
|
|
146
|
+
url: `https://view.elara.workers.dev/tickets?url=${Array.isArray(m.attachments) ? m.attachments?.[0]?.url : m.attachments?.first?.()?.url ?? "URL_NOT_FOUND"}`,
|
|
147
|
+
},
|
|
148
|
+
];
|
|
149
|
+
embeds[0].description += `\n${de.transcript} ${this.str("TRANSCRIPT")}: [${this.str("VIEW_HERE")}](${components[0].url})`;
|
|
63
150
|
webhook(this.webhookOptions)
|
|
64
151
|
.embeds(embeds)
|
|
65
152
|
.button({ type: 1, components })
|
|
66
153
|
.edit(m.id)
|
|
67
|
-
.catch(e => this._debug(e));
|
|
68
|
-
if (user)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
154
|
+
.catch((e) => this._debug(e));
|
|
155
|
+
if (user) {
|
|
156
|
+
user.send({
|
|
157
|
+
embeds: [
|
|
158
|
+
{
|
|
159
|
+
author: {
|
|
160
|
+
name: guild.name,
|
|
161
|
+
icon_url: guild.iconURL({ dynamic: true }),
|
|
162
|
+
},
|
|
163
|
+
title: this.str("CLOSE_TICKET_TITLE"),
|
|
164
|
+
color: 0xff0000,
|
|
165
|
+
fields: reason
|
|
166
|
+
? [
|
|
167
|
+
{
|
|
168
|
+
name: this.str("CLOSE_TICKET_FIELD_REASON"),
|
|
169
|
+
value: reason?.slice?.(0, 1024) ?? this.str("NO_REASON"),
|
|
170
|
+
},
|
|
171
|
+
]
|
|
172
|
+
: undefined,
|
|
173
|
+
timestamp: new Date(),
|
|
174
|
+
footer: {
|
|
175
|
+
text: `${this.str("TICKET_ID")} ${channel.name.split("-")[1]}`,
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
components: [{ type: 1, components }],
|
|
180
|
+
}).catch((e) => this._debug(e));
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
.catch((e) => this._debug(e));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @param {string} channelId
|
|
188
|
+
* @param {import("discord.js").MessageOptions} options
|
|
189
|
+
*/
|
|
190
|
+
async starterMessage(channelId, options) {
|
|
191
|
+
let channel = this.options.client.channels.resolve(channelId);
|
|
192
|
+
if (!channel) {
|
|
193
|
+
return Promise.reject(this.str("NO_CHANNEL_FOUND")(channelId));
|
|
194
|
+
}
|
|
195
|
+
return channel
|
|
196
|
+
.send({
|
|
197
|
+
content: options?.content,
|
|
198
|
+
files: options?.attachments,
|
|
199
|
+
embeds: options?.embeds,
|
|
200
|
+
components: options?.components || [{ type: 1, components: [this.button()] }],
|
|
201
|
+
})
|
|
202
|
+
.then(() => console.log(`✅`));
|
|
203
|
+
}
|
|
204
|
+
};
|