@wlix/ceres 0.0.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/LICENSE +7 -0
- package/README.md +60 -0
- package/dist/index.cjs +543 -0
- package/dist/index.d.cts +143 -0
- package/dist/index.d.mts +143 -0
- package/dist/index.mjs +519 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2026 Andrew (e60m5ss / wlix)
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<h1 align="center">@wlix/ceres</h1>
|
|
2
|
+
|
|
3
|
+
> Node.js library for creating Discord bots
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @wlix/ceres
|
|
9
|
+
# or
|
|
10
|
+
yarn add @wlix/ceres
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @wlix/ceres
|
|
13
|
+
# or
|
|
14
|
+
bun add @wlix/ceres
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Example
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
import { Client, ClientIntents } from "@wlix/ceres";
|
|
21
|
+
|
|
22
|
+
const client = new Client({
|
|
23
|
+
// replace TOKEN with the bot's token
|
|
24
|
+
// https://discord.com/developers/applications
|
|
25
|
+
token: "TOKEN",
|
|
26
|
+
intents: [
|
|
27
|
+
// include client intents here
|
|
28
|
+
ClientIntents.Guilds,
|
|
29
|
+
ClientIntents.GuildMembers,
|
|
30
|
+
ClientIntents.GuildMessages,
|
|
31
|
+
],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
client.once("ready", () => {
|
|
35
|
+
console.log("Client has been connected to Discord");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
client.on("messageCreate", (message) => {
|
|
39
|
+
if (message.author.bot) return;
|
|
40
|
+
|
|
41
|
+
if (message.content === "!ping") {
|
|
42
|
+
message.reply("Pong!");
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// in case any issues arise
|
|
47
|
+
client.on("debug", console.log);
|
|
48
|
+
client.on("error", console.log);
|
|
49
|
+
|
|
50
|
+
// connect to Discord
|
|
51
|
+
client.connect();
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Contributing
|
|
55
|
+
|
|
56
|
+
Pull requests are always welcomed. For more major changes, please open an issue to discuss what you wish to change.
|
|
57
|
+
|
|
58
|
+
## License
|
|
59
|
+
|
|
60
|
+
[MIT](LICENSE)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
let discord_api_types_v10 = require("discord-api-types/v10");
|
|
2
|
+
|
|
3
|
+
//#region src/structures/EventHandler.ts
|
|
4
|
+
/**
|
|
5
|
+
* Class representing a typed EventHandler supporting generics
|
|
6
|
+
*/
|
|
7
|
+
var EventHandler = class {
|
|
8
|
+
/**
|
|
9
|
+
* All stored listeners
|
|
10
|
+
*/
|
|
11
|
+
#listeners = {};
|
|
12
|
+
/**
|
|
13
|
+
* Listen for an event
|
|
14
|
+
* @param event Event name
|
|
15
|
+
* @param listener Callback once event is emitted
|
|
16
|
+
*/
|
|
17
|
+
on(event, listener) {
|
|
18
|
+
if (!this.#listeners[event]) this.#listeners[event] = [];
|
|
19
|
+
this.#listeners[event].push(listener);
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Listen for an event once
|
|
24
|
+
* @param event Event name
|
|
25
|
+
* @param listener Callback once event is emitted
|
|
26
|
+
*/
|
|
27
|
+
once(event, listener) {
|
|
28
|
+
const wrapped = (...args) => {
|
|
29
|
+
listener(...args);
|
|
30
|
+
this.off(event, wrapped);
|
|
31
|
+
};
|
|
32
|
+
this.on(event, wrapped);
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Remove a registered event listener
|
|
37
|
+
* @param event Event name
|
|
38
|
+
* @param listener Callback function to remove
|
|
39
|
+
*/
|
|
40
|
+
off(event, listener) {
|
|
41
|
+
if (!this.#listeners[event]) return this;
|
|
42
|
+
this.#listeners[event] = this.#listeners[event].filter((l) => l !== listener);
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Emit an event
|
|
47
|
+
* @param event Event name
|
|
48
|
+
* @param args Event arguments
|
|
49
|
+
*/
|
|
50
|
+
emit(event, ...args) {
|
|
51
|
+
if (!this.#listeners[event]) return false;
|
|
52
|
+
for (const listener of this.#listeners[event]) listener(...args);
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/structures/Channel.ts
|
|
59
|
+
/**
|
|
60
|
+
* Class representing a base Channel
|
|
61
|
+
*/
|
|
62
|
+
var Channel = class {
|
|
63
|
+
/**
|
|
64
|
+
* The Client associated with this Channel
|
|
65
|
+
*/
|
|
66
|
+
client;
|
|
67
|
+
/**
|
|
68
|
+
* The Discord channel ID
|
|
69
|
+
*/
|
|
70
|
+
id;
|
|
71
|
+
/**
|
|
72
|
+
* The Discord channel name
|
|
73
|
+
*/
|
|
74
|
+
name;
|
|
75
|
+
/**
|
|
76
|
+
* The type of this channel
|
|
77
|
+
*/
|
|
78
|
+
type;
|
|
79
|
+
/**
|
|
80
|
+
* The ID of the guild this channel is in
|
|
81
|
+
*/
|
|
82
|
+
guildId;
|
|
83
|
+
/**
|
|
84
|
+
* Instantiate a new Channel (internal)
|
|
85
|
+
* @param client Associated client
|
|
86
|
+
* @param data API channel data
|
|
87
|
+
*/
|
|
88
|
+
constructor(client, data) {
|
|
89
|
+
this.client = client;
|
|
90
|
+
this.id = data.id;
|
|
91
|
+
this.type = data.type;
|
|
92
|
+
if ("guild_id" in data) this.guildId = data.guild_id ?? void 0;
|
|
93
|
+
if ("name" in data) this.name = data.name ?? void 0;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Whether this channel is a guild text channel, a direct message, or a guild announcement channel
|
|
97
|
+
*/
|
|
98
|
+
isText() {
|
|
99
|
+
return this.type === discord_api_types_v10.ChannelType.GuildText || this.type === discord_api_types_v10.ChannelType.DM || this.type === discord_api_types_v10.ChannelType.GuildAnnouncement;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Send a message in this channel
|
|
103
|
+
* @param props Message data
|
|
104
|
+
* @returns Created message object
|
|
105
|
+
*/
|
|
106
|
+
send(props) {
|
|
107
|
+
return this.client.createMessage(this.id, typeof props === "string" ? { content: props } : props);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
//#endregion
|
|
112
|
+
//#region src/utils/client-events.ts
|
|
113
|
+
async function handleClientEvent(client, packet) {
|
|
114
|
+
const { t, d } = packet;
|
|
115
|
+
client.emit("debug", `[@wlix/ceres Client debug]: Received ${t} event`);
|
|
116
|
+
switch (t) {
|
|
117
|
+
case discord_api_types_v10.GatewayDispatchEvents.MessageCreate:
|
|
118
|
+
client.emit("messageCreate", new Message(client, await client.fetchChannel(d.channel_id), d));
|
|
119
|
+
break;
|
|
120
|
+
case discord_api_types_v10.GatewayDispatchEvents.Ready:
|
|
121
|
+
client.user = new User(client, d.user);
|
|
122
|
+
client.emit("ready", client);
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/utils/intents.ts
|
|
129
|
+
const ClientIntents = {
|
|
130
|
+
AutoModerationConfiguration: 1 << 20,
|
|
131
|
+
AutoModerationExecution: 1 << 21,
|
|
132
|
+
DirectMessagePolls: 1 << 25,
|
|
133
|
+
DirectMessageReactions: 8192,
|
|
134
|
+
DirectMessages: 4096,
|
|
135
|
+
DirectMessageTyping: 16384,
|
|
136
|
+
GuildExpressions: 8,
|
|
137
|
+
GuildIntegrations: 16,
|
|
138
|
+
GuildInvites: 64,
|
|
139
|
+
GuildMembers: 2,
|
|
140
|
+
GuildMessagePolls: 1 << 24,
|
|
141
|
+
GuildMessageReactions: 1024,
|
|
142
|
+
GuildMessages: 512,
|
|
143
|
+
GuildMessageTyping: 2048,
|
|
144
|
+
GuildModeration: 4,
|
|
145
|
+
GuildPresences: 256,
|
|
146
|
+
Guilds: 1,
|
|
147
|
+
GuildScheduledEvents: 65536,
|
|
148
|
+
GuildVoiceStates: 128,
|
|
149
|
+
GuildWebhooks: 32,
|
|
150
|
+
MessageContent: 32768
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
//#endregion
|
|
154
|
+
//#region src/structures/Client.ts
|
|
155
|
+
/**
|
|
156
|
+
* Class representing a Client connecting to Discord's API
|
|
157
|
+
* @extends EventHandler
|
|
158
|
+
*/
|
|
159
|
+
var Client = class Client extends EventHandler {
|
|
160
|
+
/**
|
|
161
|
+
* The URL to connect to when initializing the gateway
|
|
162
|
+
*/
|
|
163
|
+
static gatewayUrl = "wss://gateway.discord.gg/?v=10&encoding=json";
|
|
164
|
+
/**
|
|
165
|
+
* The URL to connect to when contacting the API
|
|
166
|
+
*/
|
|
167
|
+
static baseApiUrl = "https://discord.com/api/v10";
|
|
168
|
+
/**
|
|
169
|
+
* The client's intents
|
|
170
|
+
*/
|
|
171
|
+
intents;
|
|
172
|
+
/**
|
|
173
|
+
* Whether the client is ready
|
|
174
|
+
*/
|
|
175
|
+
ready = false;
|
|
176
|
+
/**
|
|
177
|
+
* The client's token
|
|
178
|
+
*/
|
|
179
|
+
token;
|
|
180
|
+
/**
|
|
181
|
+
* The client's user
|
|
182
|
+
*/
|
|
183
|
+
user = null;
|
|
184
|
+
/**
|
|
185
|
+
* A simple cache for Discord objects
|
|
186
|
+
*/
|
|
187
|
+
#cache = {
|
|
188
|
+
channels: /* @__PURE__ */ new Map(),
|
|
189
|
+
users: /* @__PURE__ */ new Map()
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* The client's presence
|
|
193
|
+
*/
|
|
194
|
+
#presence;
|
|
195
|
+
/**
|
|
196
|
+
* The client's heartbeat interval
|
|
197
|
+
*/
|
|
198
|
+
#heartbeatInterval;
|
|
199
|
+
/**
|
|
200
|
+
* The client's websocket
|
|
201
|
+
*/
|
|
202
|
+
#ws;
|
|
203
|
+
/**
|
|
204
|
+
* Instantiate a new Client
|
|
205
|
+
* @param options Client options
|
|
206
|
+
* @param options.token Client token
|
|
207
|
+
*/
|
|
208
|
+
constructor(options) {
|
|
209
|
+
super();
|
|
210
|
+
if (!options?.token) throw new Error("[@wlix/ceres Client]: Client token must be provided as a non-empty string");
|
|
211
|
+
if (!options?.intents) throw new Error("[@wlix/ceres Client]: Client intents must be provided");
|
|
212
|
+
this.token = options.token.toLowerCase().startsWith("bot ") ? options.token : "Bot " + options.token;
|
|
213
|
+
this.intents = options.intents.reduce((bitfield, i) => bitfield | i, 0);
|
|
214
|
+
if (options.presence) this.#presence = options.presence;
|
|
215
|
+
}
|
|
216
|
+
async #apiFetch(path, options) {
|
|
217
|
+
const res = await fetch(`${Client.baseApiUrl}${path}`, {
|
|
218
|
+
...options,
|
|
219
|
+
headers: {
|
|
220
|
+
Authorization: this.token,
|
|
221
|
+
"Content-Type": "application/json",
|
|
222
|
+
...options?.headers ?? {}
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
if (!res.ok) throw new Error(`[@wlix/ceres] Discord API error: ${res.status} ${res.statusText}`);
|
|
226
|
+
return res.json();
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Handle incoming packets
|
|
230
|
+
* @param packet Packet data
|
|
231
|
+
*/
|
|
232
|
+
#handlePacket(packet) {
|
|
233
|
+
const { t, op, d, s } = packet;
|
|
234
|
+
if (op === 10) {
|
|
235
|
+
this.#heartbeatInterval = setInterval(() => {
|
|
236
|
+
this.#ws?.send(JSON.stringify({
|
|
237
|
+
op: discord_api_types_v10.GatewayOpcodes.Heartbeat,
|
|
238
|
+
d: s
|
|
239
|
+
}));
|
|
240
|
+
}, d.heartbeat_interval);
|
|
241
|
+
this.#ws?.send(JSON.stringify({
|
|
242
|
+
op: discord_api_types_v10.GatewayOpcodes.Identify,
|
|
243
|
+
d: {
|
|
244
|
+
token: this.token,
|
|
245
|
+
intents: this.intents,
|
|
246
|
+
properties: {
|
|
247
|
+
$os: "linux",
|
|
248
|
+
$browser: "@wlix/ceres",
|
|
249
|
+
$device: "@wlix/ceres"
|
|
250
|
+
},
|
|
251
|
+
presence: this.#presence ? {
|
|
252
|
+
status: this.#presence.status,
|
|
253
|
+
since: null,
|
|
254
|
+
afk: false,
|
|
255
|
+
activities: this.#presence.activities ?? []
|
|
256
|
+
} : {
|
|
257
|
+
status: "online",
|
|
258
|
+
since: null,
|
|
259
|
+
afk: false,
|
|
260
|
+
activities: []
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
if (packet.t) handleClientEvent(this, packet);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Whether the client is ready
|
|
269
|
+
*/
|
|
270
|
+
isReady() {
|
|
271
|
+
return this.user !== null;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Returns the client's user presence
|
|
275
|
+
*/
|
|
276
|
+
get presence() {
|
|
277
|
+
return this.#presence ?? null;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Update the client's token (only when not connected)
|
|
281
|
+
* @param token New token
|
|
282
|
+
*/
|
|
283
|
+
setToken(token) {
|
|
284
|
+
if (this.#ws) throw new Error("[@wlix/ceres Client]: Cannot change token while connected, disconnect first");
|
|
285
|
+
if (!token || typeof token !== "string") throw new Error("[@wlix/ceres Client]: Client token must be provided as a non-empty string");
|
|
286
|
+
this.token = token.toLowerCase().startsWith("bot ") ? token : "Bot " + token;
|
|
287
|
+
this.emit("debug", "[@wlix/ceres Client debug]: Client token was updated");
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Connects the Client to the Discord gateway
|
|
291
|
+
* @returns Client instance
|
|
292
|
+
*/
|
|
293
|
+
async connect() {
|
|
294
|
+
this.emit("debug", "[@wlix/ceres Client debug]: Connecting to Discord gateway");
|
|
295
|
+
this.#ws = new WebSocket(Client.gatewayUrl);
|
|
296
|
+
this.#ws.onopen = () => {
|
|
297
|
+
this.emit("debug", "[@wlix/ceres Client debug]: WebSocket has been opened");
|
|
298
|
+
};
|
|
299
|
+
this.#ws.onmessage = (message) => {
|
|
300
|
+
this.#handlePacket(JSON.parse(message.data));
|
|
301
|
+
};
|
|
302
|
+
this.#ws.onerror = (error) => {
|
|
303
|
+
this.emit("debug", `[@wlix/ceres Client debug]: WebSocket error: ${error}`);
|
|
304
|
+
};
|
|
305
|
+
return this;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Disconnects the client from the Discord gateway
|
|
309
|
+
*/
|
|
310
|
+
disconnect() {
|
|
311
|
+
if (this.#heartbeatInterval) {
|
|
312
|
+
clearInterval(this.#heartbeatInterval);
|
|
313
|
+
this.#heartbeatInterval = void 0;
|
|
314
|
+
}
|
|
315
|
+
if (this.#ws) {
|
|
316
|
+
this.#ws.close(1e3, "Client disconnect");
|
|
317
|
+
this.#ws = void 0;
|
|
318
|
+
}
|
|
319
|
+
this.emit("debug", "[@wlix/ceres Client debug]: Disconnected from Discord gateway");
|
|
320
|
+
this.emit("disconnect");
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Fetch a Discord channel by ID
|
|
324
|
+
* @param id Channel ID
|
|
325
|
+
* @returns Channel object or null
|
|
326
|
+
*/
|
|
327
|
+
async fetchChannel(id) {
|
|
328
|
+
if (this.#cache.channels.has(id)) return this.#cache.channels.get(id);
|
|
329
|
+
try {
|
|
330
|
+
const channel = new Channel(this, await this.#apiFetch(`${discord_api_types_v10.Routes.channel(id)}`));
|
|
331
|
+
this.#cache.channels.set(id, channel);
|
|
332
|
+
return channel;
|
|
333
|
+
} catch (error) {
|
|
334
|
+
this.emit("error", error);
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Fetch a user by ID
|
|
340
|
+
* @param id User ID
|
|
341
|
+
* @returns User object or null
|
|
342
|
+
*/
|
|
343
|
+
async fetchUser(id) {
|
|
344
|
+
if (this.#cache.users.has(id)) return this.#cache.users.get(id);
|
|
345
|
+
try {
|
|
346
|
+
const user = new User(this, await this.#apiFetch(`${discord_api_types_v10.Routes.user(id)}`));
|
|
347
|
+
this.#cache.users.set(id, user);
|
|
348
|
+
return user;
|
|
349
|
+
} catch (error) {
|
|
350
|
+
this.emit("error", error);
|
|
351
|
+
throw error;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Sends a new message as the Client
|
|
356
|
+
* @returns Created message or null
|
|
357
|
+
*/
|
|
358
|
+
async createMessage(channelId, props) {
|
|
359
|
+
if (!this.isReady()) return null;
|
|
360
|
+
try {
|
|
361
|
+
const data = await this.#apiFetch(discord_api_types_v10.Routes.channelMessages(channelId), {
|
|
362
|
+
method: "POST",
|
|
363
|
+
body: typeof props === "string" ? JSON.stringify({ content: props }) : JSON.stringify({
|
|
364
|
+
content: props.content,
|
|
365
|
+
nonce: props.nonce,
|
|
366
|
+
tts: props.tts,
|
|
367
|
+
embeds: props.embeds,
|
|
368
|
+
allowed_mentions: props.allowedMentions,
|
|
369
|
+
message_reference: props.messageReference,
|
|
370
|
+
components: props.components,
|
|
371
|
+
sticker_ids: props.stickerIds,
|
|
372
|
+
attachments: props.attachments,
|
|
373
|
+
flags: props.flags,
|
|
374
|
+
enforce_nonce: props.enforceNonce
|
|
375
|
+
})
|
|
376
|
+
});
|
|
377
|
+
return new Message(this, await this.fetchChannel(data.channel_id), data);
|
|
378
|
+
} catch (error) {
|
|
379
|
+
this.emit("error", error);
|
|
380
|
+
throw error;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Update the client's user presence
|
|
385
|
+
* @param presence Presence data
|
|
386
|
+
*/
|
|
387
|
+
setPresence(presence) {
|
|
388
|
+
this.#presence = presence;
|
|
389
|
+
if (this.#ws) this.#ws.send(JSON.stringify({
|
|
390
|
+
op: discord_api_types_v10.GatewayOpcodes.PresenceUpdate,
|
|
391
|
+
d: {
|
|
392
|
+
status: presence.status,
|
|
393
|
+
since: null,
|
|
394
|
+
afk: false,
|
|
395
|
+
activities: []
|
|
396
|
+
}
|
|
397
|
+
}));
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
//#endregion
|
|
402
|
+
//#region src/structures/Message.ts
|
|
403
|
+
/**
|
|
404
|
+
* Class representing a Message
|
|
405
|
+
*/
|
|
406
|
+
var Message = class {
|
|
407
|
+
/**
|
|
408
|
+
* The Client associated with this Message
|
|
409
|
+
*/
|
|
410
|
+
client;
|
|
411
|
+
/**
|
|
412
|
+
* The Discord message ID
|
|
413
|
+
*/
|
|
414
|
+
id;
|
|
415
|
+
/**
|
|
416
|
+
* The Discord message content
|
|
417
|
+
*/
|
|
418
|
+
content;
|
|
419
|
+
/**
|
|
420
|
+
* The User who sent this message
|
|
421
|
+
*/
|
|
422
|
+
author;
|
|
423
|
+
/**
|
|
424
|
+
* The channel where this message is
|
|
425
|
+
*/
|
|
426
|
+
channel;
|
|
427
|
+
/**
|
|
428
|
+
* The ID of the channel where this message is
|
|
429
|
+
*/
|
|
430
|
+
channelId;
|
|
431
|
+
/**
|
|
432
|
+
* A Date representing when this message was sent
|
|
433
|
+
*/
|
|
434
|
+
timestamp;
|
|
435
|
+
/**
|
|
436
|
+
* Instantiate a new Message (internal)
|
|
437
|
+
* @param client Associated client
|
|
438
|
+
* @param data API message data
|
|
439
|
+
*/
|
|
440
|
+
constructor(client, channel, data) {
|
|
441
|
+
this.client = client;
|
|
442
|
+
this.id = data.id;
|
|
443
|
+
this.content = data.content;
|
|
444
|
+
this.author = new User(client, data.author);
|
|
445
|
+
this.channelId = data.channel_id;
|
|
446
|
+
this.timestamp = new Date(data.timestamp);
|
|
447
|
+
this.channel = channel;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Reply to a message
|
|
451
|
+
* @param props Message reply props
|
|
452
|
+
* @returns Replied message
|
|
453
|
+
*/
|
|
454
|
+
async reply(props) {
|
|
455
|
+
return this.client.createMessage(this.channelId, typeof props === "string" ? {
|
|
456
|
+
content: props,
|
|
457
|
+
messageReference: { message_id: this.id }
|
|
458
|
+
} : {
|
|
459
|
+
...props,
|
|
460
|
+
messageReference: { message_id: this.id }
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
//#endregion
|
|
466
|
+
//#region src/structures/User.ts
|
|
467
|
+
/**
|
|
468
|
+
* Class representing a User
|
|
469
|
+
*/
|
|
470
|
+
var User = class {
|
|
471
|
+
/**
|
|
472
|
+
* The Client associated with this User
|
|
473
|
+
*/
|
|
474
|
+
client;
|
|
475
|
+
/**
|
|
476
|
+
* The Discord user ID
|
|
477
|
+
*/
|
|
478
|
+
id;
|
|
479
|
+
/**
|
|
480
|
+
* The Discord user username
|
|
481
|
+
*/
|
|
482
|
+
username;
|
|
483
|
+
/**
|
|
484
|
+
* The Discord user's discriminator, or "0" if they have none
|
|
485
|
+
*/
|
|
486
|
+
discriminator = "0";
|
|
487
|
+
/**
|
|
488
|
+
* Whether this Discord user is a bot
|
|
489
|
+
*/
|
|
490
|
+
bot;
|
|
491
|
+
/**
|
|
492
|
+
* If the user has a discriminator (i.e., it's not "0"), returns username#discriminator
|
|
493
|
+
* Else, returns just the username
|
|
494
|
+
*/
|
|
495
|
+
get tag() {
|
|
496
|
+
return this.discriminator === "0" ? this.username : `${this.username}#${this.discriminator}`;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Represent the User as a mention (e.g., <@USERID>)
|
|
500
|
+
*/
|
|
501
|
+
toString() {
|
|
502
|
+
return `<@${this.id}>`;
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Instantiate a new User (internal)
|
|
506
|
+
* @param client Associated client
|
|
507
|
+
* @param data API user data
|
|
508
|
+
*/
|
|
509
|
+
constructor(client, data) {
|
|
510
|
+
this.client = client;
|
|
511
|
+
this.id = data.id;
|
|
512
|
+
this.username = data.username;
|
|
513
|
+
this.discriminator = data.discriminator;
|
|
514
|
+
this.bot = data.bot ?? false;
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
//#endregion
|
|
519
|
+
Object.defineProperty(exports, 'ActivityType', {
|
|
520
|
+
enumerable: true,
|
|
521
|
+
get: function () {
|
|
522
|
+
return discord_api_types_v10.ActivityType;
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
exports.Channel = Channel;
|
|
526
|
+
Object.defineProperty(exports, 'ChannelType', {
|
|
527
|
+
enumerable: true,
|
|
528
|
+
get: function () {
|
|
529
|
+
return discord_api_types_v10.ChannelType;
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
exports.Client = Client;
|
|
533
|
+
exports.ClientIntents = ClientIntents;
|
|
534
|
+
exports.EventHandler = EventHandler;
|
|
535
|
+
Object.defineProperty(exports, 'GatewayDispatchEvents', {
|
|
536
|
+
enumerable: true,
|
|
537
|
+
get: function () {
|
|
538
|
+
return discord_api_types_v10.GatewayDispatchEvents;
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
exports.Message = Message;
|
|
542
|
+
exports.User = User;
|
|
543
|
+
exports.handleClientEvent = handleClientEvent;
|