simple-discord-bot.js 0.1.3 → 0.1.4
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/README.md +354 -0
- package/client.js +111 -56
- package/gateway.js +29 -14
- package/index.js +6 -2
- package/package.json +1 -1
- package/structures/ButtonBuilder.js +50 -0
- package/structures/EmbedBuilder.js +34 -0
- package/structures/Message.js +37 -6
- package/structures/SelectMenuBuilder.js +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
simple-discord-bot.js
|
|
2
|
+
|
|
3
|
+
""npm version" (https://img.shields.io/npm/v/simple-discord-bot.js.svg)" (https://www.npmjs.com/package/simple-discord-bot.js)
|
|
4
|
+
""npm downloads" (https://img.shields.io/npm/dm/simple-discord-bot.js.svg)" (https://www.npmjs.com/package/simple-discord-bot.js)
|
|
5
|
+
""License" (https://img.shields.io/npm/l/simple-discord-bot.js.svg)" (https://www.npmjs.com/package/simple-discord-bot.js)
|
|
6
|
+
""Node.js" (https://img.shields.io/badge/Node.js-18%2B-brightgreen.svg)" (https://nodejs.org/)
|
|
7
|
+
|
|
8
|
+
A simple and lightweight Discord bot library for Node.js
|
|
9
|
+
|
|
10
|
+
Built to make Discord bot development easier while keeping the API simple and beginner friendly
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
✨ Features
|
|
15
|
+
|
|
16
|
+
- ⚡ Lightweight
|
|
17
|
+
- 🧩 Simple API
|
|
18
|
+
- 🤖 Discord bot support
|
|
19
|
+
- 💬 Message events
|
|
20
|
+
- ⚙️ Slash commands
|
|
21
|
+
- 📝 Slash command options
|
|
22
|
+
- 🎨 EmbedBuilder
|
|
23
|
+
- 🔐 Permission checking
|
|
24
|
+
- 💓 Gateway heartbeat
|
|
25
|
+
- 🛑 Clean bot shutdown
|
|
26
|
+
- 📦 Available through npm
|
|
27
|
+
- 🟢 Easy to learn
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
📦 Installation
|
|
32
|
+
|
|
33
|
+
Install the latest version with npm
|
|
34
|
+
|
|
35
|
+
npm install simple-discord-bot.js
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
🚀 Quick Start
|
|
40
|
+
|
|
41
|
+
Create a simple bot in just a few lines
|
|
42
|
+
|
|
43
|
+
const { Client } = require("simple-discord-bot.js")
|
|
44
|
+
|
|
45
|
+
const client = new Client()
|
|
46
|
+
|
|
47
|
+
client.command("ping", interaction => {
|
|
48
|
+
interaction.reply("Pong!")
|
|
49
|
+
}, {
|
|
50
|
+
description: "Replies with Pong!"
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
client.on("ready", () => {
|
|
54
|
+
console.log("Bot is online!")
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
client.login("YOUR_BOT_TOKEN")
|
|
58
|
+
|
|
59
|
+
Start your bot
|
|
60
|
+
|
|
61
|
+
node index.js
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
⚙️ Slash Commands
|
|
66
|
+
|
|
67
|
+
Create commands with "client.command()"
|
|
68
|
+
|
|
69
|
+
client.command("hello", interaction => {
|
|
70
|
+
interaction.reply("Hello!")
|
|
71
|
+
}, {
|
|
72
|
+
description: "Says hello"
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
🧩 Command Options
|
|
78
|
+
|
|
79
|
+
Commands can have options
|
|
80
|
+
|
|
81
|
+
client.command("say", interaction => {
|
|
82
|
+
interaction.reply(interaction.options.message)
|
|
83
|
+
}, {
|
|
84
|
+
description: "Make the bot say something",
|
|
85
|
+
options: [
|
|
86
|
+
{
|
|
87
|
+
name: "message",
|
|
88
|
+
description: "The message to send",
|
|
89
|
+
type: 3,
|
|
90
|
+
required: true
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
The option can then be accessed with
|
|
96
|
+
|
|
97
|
+
interaction.options.message
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
🎨 Embeds
|
|
102
|
+
|
|
103
|
+
Create beautiful Discord embeds with "EmbedBuilder"
|
|
104
|
+
|
|
105
|
+
const { EmbedBuilder } = require("simple-discord-bot.js")
|
|
106
|
+
|
|
107
|
+
const embed = new EmbedBuilder()
|
|
108
|
+
.setTitle("Hello")
|
|
109
|
+
.setDescription("This is an embed!")
|
|
110
|
+
.setColor("5865F2")
|
|
111
|
+
.setFooter("Made with SimpleDiscord.js")
|
|
112
|
+
.setTimestamp()
|
|
113
|
+
|
|
114
|
+
interaction.reply(embed)
|
|
115
|
+
|
|
116
|
+
Embed Methods
|
|
117
|
+
|
|
118
|
+
Title
|
|
119
|
+
|
|
120
|
+
.setTitle("Hello")
|
|
121
|
+
|
|
122
|
+
Description
|
|
123
|
+
|
|
124
|
+
.setDescription("This is my description")
|
|
125
|
+
|
|
126
|
+
Color
|
|
127
|
+
|
|
128
|
+
Hex colors are supported
|
|
129
|
+
|
|
130
|
+
.setColor("FF0000")
|
|
131
|
+
|
|
132
|
+
URL
|
|
133
|
+
|
|
134
|
+
.setURL("https://example.com")
|
|
135
|
+
|
|
136
|
+
Footer
|
|
137
|
+
|
|
138
|
+
.setFooter("Made with SimpleDiscord.js")
|
|
139
|
+
|
|
140
|
+
Footer Icon
|
|
141
|
+
|
|
142
|
+
.setFooter(
|
|
143
|
+
"Made with SimpleDiscord.js",
|
|
144
|
+
"https://example.com/icon.png"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
Author
|
|
148
|
+
|
|
149
|
+
.setAuthor("SimpleBot")
|
|
150
|
+
|
|
151
|
+
Author Icon
|
|
152
|
+
|
|
153
|
+
.setAuthor(
|
|
154
|
+
"SimpleBot",
|
|
155
|
+
"https://example.com/icon.png"
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
Thumbnail
|
|
159
|
+
|
|
160
|
+
.setThumbnail("https://example.com/image.png")
|
|
161
|
+
|
|
162
|
+
Image
|
|
163
|
+
|
|
164
|
+
.setImage("https://example.com/image.png")
|
|
165
|
+
|
|
166
|
+
Timestamp
|
|
167
|
+
|
|
168
|
+
.setTimestamp()
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
🔐 Permissions
|
|
173
|
+
|
|
174
|
+
Check Discord permissions easily
|
|
175
|
+
|
|
176
|
+
client.command("admin", interaction => {
|
|
177
|
+
if (!interaction.member?.permissions.has("Administrator")) {
|
|
178
|
+
return interaction.reply("You need Administrator")
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
interaction.reply("You have Administrator permission!")
|
|
182
|
+
}, {
|
|
183
|
+
description: "Administrator only command"
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
💬 Messages
|
|
189
|
+
|
|
190
|
+
Listen for messages
|
|
191
|
+
|
|
192
|
+
client.on("message", message => {
|
|
193
|
+
console.log(message.content)
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
Reply to messages
|
|
197
|
+
|
|
198
|
+
message.reply("Hello!")
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
📡 Events
|
|
203
|
+
|
|
204
|
+
SimpleDiscord.js currently supports:
|
|
205
|
+
|
|
206
|
+
Event| Description
|
|
207
|
+
"ready"| Bot is ready
|
|
208
|
+
"message"| A message was created
|
|
209
|
+
"error"| Gateway error
|
|
210
|
+
"disconnect"| Bot disconnected
|
|
211
|
+
|
|
212
|
+
Example
|
|
213
|
+
|
|
214
|
+
client.on("ready", () => {
|
|
215
|
+
console.log("Bot is online!")
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
🛠️ API
|
|
221
|
+
|
|
222
|
+
Client
|
|
223
|
+
|
|
224
|
+
const { Client } = require("simple-discord-bot.js")
|
|
225
|
+
|
|
226
|
+
const client = new Client()
|
|
227
|
+
|
|
228
|
+
"client.login(token)"
|
|
229
|
+
|
|
230
|
+
Connect your bot to Discord
|
|
231
|
+
|
|
232
|
+
client.login("YOUR_BOT_TOKEN")
|
|
233
|
+
|
|
234
|
+
"client.command(name, handler, options)"
|
|
235
|
+
|
|
236
|
+
Create a slash command
|
|
237
|
+
|
|
238
|
+
client.command(
|
|
239
|
+
"ping",
|
|
240
|
+
interaction => {
|
|
241
|
+
interaction.reply("Pong!")
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
description: "Replies with Pong!"
|
|
245
|
+
}
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
"client.destroy()"
|
|
249
|
+
|
|
250
|
+
Disconnect the bot
|
|
251
|
+
|
|
252
|
+
client.destroy()
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
📊 Current Status
|
|
257
|
+
|
|
258
|
+
SimpleDiscord.js is currently in early development
|
|
259
|
+
|
|
260
|
+
Current version:
|
|
261
|
+
|
|
262
|
+
0.1.2
|
|
263
|
+
|
|
264
|
+
The API may change as the library develops
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
🗺️ Roadmap
|
|
269
|
+
|
|
270
|
+
✅ Completed
|
|
271
|
+
|
|
272
|
+
- [x] Discord Gateway connection
|
|
273
|
+
- [x] Gateway heartbeat
|
|
274
|
+
- [x] Bot login
|
|
275
|
+
- [x] Clean shutdown
|
|
276
|
+
- [x] Ready event
|
|
277
|
+
- [x] Message events
|
|
278
|
+
- [x] Message replies
|
|
279
|
+
- [x] Slash commands
|
|
280
|
+
- [x] Slash command options
|
|
281
|
+
- [x] Permission checking
|
|
282
|
+
- [x] EmbedBuilder
|
|
283
|
+
- [x] npm publishing
|
|
284
|
+
|
|
285
|
+
🚧 Planned
|
|
286
|
+
|
|
287
|
+
- [ ] Embed fields
|
|
288
|
+
- [ ] Buttons
|
|
289
|
+
- [ ] Select menus
|
|
290
|
+
- [ ] More interaction types
|
|
291
|
+
- [ ] Channel objects
|
|
292
|
+
- [ ] Guild objects
|
|
293
|
+
- [ ] User objects
|
|
294
|
+
- [ ] Message editing
|
|
295
|
+
- [ ] Message deletion
|
|
296
|
+
- [ ] More permission helpers
|
|
297
|
+
- [ ] Better error handling
|
|
298
|
+
- [ ] Automatic reconnection
|
|
299
|
+
- [ ] Gateway resume support
|
|
300
|
+
- [ ] More Discord API features
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
📚 Why SimpleDiscord.js?
|
|
305
|
+
|
|
306
|
+
Discord libraries can become complicated when you're just starting
|
|
307
|
+
|
|
308
|
+
SimpleDiscord.js focuses on keeping things straightforward
|
|
309
|
+
|
|
310
|
+
Instead of learning a huge API you can start with:
|
|
311
|
+
|
|
312
|
+
const { Client } = require("simple-discord-bot.js")
|
|
313
|
+
|
|
314
|
+
const client = new Client()
|
|
315
|
+
|
|
316
|
+
client.command("ping", interaction => {
|
|
317
|
+
interaction.reply("Pong!")
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
client.login("YOUR_BOT_TOKEN")
|
|
321
|
+
|
|
322
|
+
Simple
|
|
323
|
+
|
|
324
|
+
Lightweight
|
|
325
|
+
|
|
326
|
+
Beginner friendly
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
📦 npm
|
|
331
|
+
|
|
332
|
+
Install the package from npm
|
|
333
|
+
|
|
334
|
+
npm install simple-discord-bot.js
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
🤝 Contributing
|
|
339
|
+
|
|
340
|
+
Contributions and suggestions are welcome
|
|
341
|
+
|
|
342
|
+
If you find a bug or have an idea for a feature you can open an issue or submit a pull request
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
📄 License
|
|
347
|
+
|
|
348
|
+
MIT License
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
Made with ❤️ and JavaScript
|
|
353
|
+
|
|
354
|
+
simple-discord-bot.js
|
package/client.js
CHANGED
|
@@ -46,11 +46,13 @@ class Permissions {
|
|
|
46
46
|
has(permission) {
|
|
47
47
|
const flag = PermissionFlags[permission]
|
|
48
48
|
|
|
49
|
-
if (flag
|
|
49
|
+
if (!flag) {
|
|
50
50
|
return false
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
if (
|
|
53
|
+
if (
|
|
54
|
+
(this.bitfield & PermissionFlags.Administrator) !== 0n
|
|
55
|
+
) {
|
|
54
56
|
return true
|
|
55
57
|
}
|
|
56
58
|
|
|
@@ -75,79 +77,131 @@ class Client extends EventEmitter {
|
|
|
75
77
|
})
|
|
76
78
|
|
|
77
79
|
this.on("rawInteraction", data => {
|
|
78
|
-
if (data.type
|
|
80
|
+
if (data.type === 2) {
|
|
81
|
+
this.handleCommandInteraction(data)
|
|
82
|
+
return
|
|
83
|
+
}
|
|
79
84
|
|
|
80
|
-
|
|
85
|
+
if (data.type === 3) {
|
|
86
|
+
this.handleComponentInteraction(data)
|
|
87
|
+
}
|
|
88
|
+
})
|
|
81
89
|
|
|
82
|
-
|
|
90
|
+
process.on("SIGINT", () => {
|
|
91
|
+
if (this.stopping) return
|
|
83
92
|
|
|
84
|
-
|
|
93
|
+
this.stopping = true
|
|
94
|
+
this.destroy()
|
|
85
95
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
96
|
+
setTimeout(() => {
|
|
97
|
+
process.exit(0)
|
|
98
|
+
}, 1000)
|
|
99
|
+
})
|
|
100
|
+
}
|
|
89
101
|
|
|
90
|
-
|
|
102
|
+
handleCommandInteraction(data) {
|
|
103
|
+
const command = this.commands.get(data.data.name)
|
|
91
104
|
|
|
92
|
-
|
|
105
|
+
if (!command) return
|
|
93
106
|
|
|
94
|
-
|
|
95
|
-
...member,
|
|
107
|
+
const member = data.member
|
|
96
108
|
|
|
97
|
-
|
|
98
|
-
|
|
109
|
+
const interaction = {
|
|
110
|
+
id: data.id,
|
|
111
|
+
token: data.token,
|
|
112
|
+
type: "command",
|
|
113
|
+
commandName: data.data.name,
|
|
114
|
+
user: member?.user || data.user,
|
|
99
115
|
|
|
100
|
-
|
|
116
|
+
member: member
|
|
117
|
+
? {
|
|
118
|
+
...member,
|
|
119
|
+
permissions: new Permissions(
|
|
120
|
+
member.permissions
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
: null,
|
|
101
124
|
|
|
102
|
-
|
|
125
|
+
channelId: data.channel_id,
|
|
126
|
+
guildId: data.guild_id || null,
|
|
127
|
+
options: {},
|
|
103
128
|
|
|
104
|
-
|
|
129
|
+
reply: content => {
|
|
130
|
+
return this.replyToInteraction(data, content)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
105
133
|
|
|
106
|
-
|
|
107
|
-
|
|
134
|
+
for (const option of data.data.options || []) {
|
|
135
|
+
interaction.options[option.name] = option.value
|
|
136
|
+
}
|
|
108
137
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
} else if (
|
|
112
|
-
content &&
|
|
113
|
-
typeof content.toJSON === "function"
|
|
114
|
-
) {
|
|
115
|
-
messageData.embeds = [content.toJSON()]
|
|
116
|
-
} else if (content && typeof content === "object") {
|
|
117
|
-
Object.assign(messageData, content)
|
|
118
|
-
}
|
|
138
|
+
command.handler(interaction)
|
|
139
|
+
}
|
|
119
140
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
`/interactions/${data.id}/${data.token}/callback`,
|
|
123
|
-
{
|
|
124
|
-
type: 4,
|
|
125
|
-
data: messageData
|
|
126
|
-
}
|
|
127
|
-
)
|
|
128
|
-
}
|
|
129
|
-
}
|
|
141
|
+
handleComponentInteraction(data) {
|
|
142
|
+
const componentType = data.data.component_type
|
|
130
143
|
|
|
131
|
-
|
|
132
|
-
interaction.options[option.name] = option.value
|
|
133
|
-
}
|
|
144
|
+
let type = "selectMenu"
|
|
134
145
|
|
|
135
|
-
|
|
136
|
-
|
|
146
|
+
if (componentType === 2) {
|
|
147
|
+
type = "button"
|
|
148
|
+
}
|
|
137
149
|
|
|
138
|
-
|
|
139
|
-
|
|
150
|
+
const interaction = {
|
|
151
|
+
id: data.id,
|
|
152
|
+
token: data.token,
|
|
153
|
+
type: type,
|
|
154
|
+
componentType: componentType,
|
|
155
|
+
customId: data.data.custom_id,
|
|
156
|
+
|
|
157
|
+
user: data.member?.user || data.user,
|
|
158
|
+
|
|
159
|
+
member: data.member
|
|
160
|
+
? {
|
|
161
|
+
...data.member,
|
|
162
|
+
permissions: new Permissions(
|
|
163
|
+
data.member.permissions
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
: null,
|
|
140
167
|
|
|
141
|
-
|
|
168
|
+
channelId: data.channel_id,
|
|
169
|
+
guildId: data.guild_id || null,
|
|
170
|
+
values: data.data.values || [],
|
|
171
|
+
|
|
172
|
+
reply: content => {
|
|
173
|
+
return this.replyToInteraction(data, content)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
142
176
|
|
|
143
|
-
|
|
177
|
+
this.emit("interaction", interaction)
|
|
178
|
+
}
|
|
144
179
|
|
|
145
|
-
|
|
180
|
+
replyToInteraction(data, content) {
|
|
181
|
+
const messageData = {}
|
|
182
|
+
|
|
183
|
+
if (typeof content === "string") {
|
|
184
|
+
messageData.content = content
|
|
185
|
+
} else if (
|
|
186
|
+
content &&
|
|
187
|
+
typeof content.toJSON === "function"
|
|
188
|
+
) {
|
|
189
|
+
messageData.embeds = [content.toJSON()]
|
|
190
|
+
} else if (
|
|
191
|
+
content &&
|
|
192
|
+
typeof content === "object"
|
|
193
|
+
) {
|
|
194
|
+
Object.assign(messageData, content)
|
|
195
|
+
}
|
|
146
196
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
197
|
+
return this.api.request(
|
|
198
|
+
"POST",
|
|
199
|
+
`/interactions/${data.id}/${data.token}/callback`,
|
|
200
|
+
{
|
|
201
|
+
type: 4,
|
|
202
|
+
data: messageData
|
|
203
|
+
}
|
|
204
|
+
)
|
|
151
205
|
}
|
|
152
206
|
|
|
153
207
|
login(token) {
|
|
@@ -166,10 +220,11 @@ class Client extends EventEmitter {
|
|
|
166
220
|
this.commands.set(name, {
|
|
167
221
|
command: {
|
|
168
222
|
name: name,
|
|
169
|
-
description:
|
|
223
|
+
description:
|
|
224
|
+
options.description || "No description",
|
|
170
225
|
options: options.options || []
|
|
171
226
|
},
|
|
172
|
-
handler
|
|
227
|
+
handler: handler
|
|
173
228
|
})
|
|
174
229
|
}
|
|
175
230
|
}
|
package/gateway.js
CHANGED
|
@@ -13,11 +13,13 @@ class Gateway {
|
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
this.ws.on("open", () => {
|
|
16
|
+
console.log("Connected to Discord Gateway")
|
|
17
|
+
|
|
16
18
|
this.ws.send(JSON.stringify({
|
|
17
19
|
op: 2,
|
|
18
20
|
d: {
|
|
19
21
|
token: token,
|
|
20
|
-
intents: 33281,
|
|
22
|
+
intents: 33281 | 32768,
|
|
21
23
|
properties: {
|
|
22
24
|
os: "android",
|
|
23
25
|
browser: "SimpleDiscord.js",
|
|
@@ -28,23 +30,33 @@ class Gateway {
|
|
|
28
30
|
})
|
|
29
31
|
|
|
30
32
|
this.ws.on("message", data => {
|
|
31
|
-
|
|
33
|
+
try {
|
|
34
|
+
const packet = JSON.parse(data)
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
if (packet.op === 10) {
|
|
37
|
+
console.log("Gateway connected")
|
|
38
|
+
this.startHeartbeat(packet.d.heartbeat_interval)
|
|
39
|
+
}
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
if (packet.op === 9) {
|
|
42
|
+
console.error("Discord rejected the Gateway connection")
|
|
43
|
+
return
|
|
44
|
+
}
|
|
41
45
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
if (packet.t === "READY") {
|
|
47
|
+
this.client.user = packet.d.user
|
|
48
|
+
this.client.emit("ready", packet.d)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (packet.t === "MESSAGE_CREATE") {
|
|
52
|
+
this.client.emit("rawMessage", packet.d)
|
|
53
|
+
}
|
|
45
54
|
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
if (packet.t === "INTERACTION_CREATE") {
|
|
56
|
+
this.client.emit("rawInteraction", packet.d)
|
|
57
|
+
}
|
|
58
|
+
} catch (error) {
|
|
59
|
+
this.client.emit("error", error)
|
|
48
60
|
}
|
|
49
61
|
})
|
|
50
62
|
|
|
@@ -57,6 +69,8 @@ class Gateway {
|
|
|
57
69
|
this.ws = null
|
|
58
70
|
this.client.emit("disconnect")
|
|
59
71
|
})
|
|
72
|
+
|
|
73
|
+
return this.ws
|
|
60
74
|
}
|
|
61
75
|
|
|
62
76
|
startHeartbeat(interval) {
|
|
@@ -84,6 +98,7 @@ class Gateway {
|
|
|
84
98
|
|
|
85
99
|
if (this.ws) {
|
|
86
100
|
this.ws.close(1000, "Bot stopped")
|
|
101
|
+
this.ws = null
|
|
87
102
|
}
|
|
88
103
|
}
|
|
89
104
|
}
|
package/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
const Client = require("./client")
|
|
2
2
|
const EmbedBuilder = require("./structures/EmbedBuilder")
|
|
3
|
+
const ButtonBuilder = require("./structures/ButtonBuilder")
|
|
4
|
+
const SelectMenuBuilder = require("./structures/SelectMenuBuilder")
|
|
3
5
|
|
|
4
6
|
module.exports = {
|
|
5
7
|
Client,
|
|
6
|
-
EmbedBuilder
|
|
7
|
-
|
|
8
|
+
EmbedBuilder,
|
|
9
|
+
ButtonBuilder,
|
|
10
|
+
SelectMenuBuilder
|
|
11
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
class ButtonBuilder {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.data = {
|
|
4
|
+
type: 2
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
setCustomId(customId) {
|
|
9
|
+
this.data.custom_id = customId
|
|
10
|
+
return this
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
setLabel(label) {
|
|
14
|
+
this.data.label = label
|
|
15
|
+
return this
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
setStyle(style) {
|
|
19
|
+
const styles = {
|
|
20
|
+
primary: 1,
|
|
21
|
+
secondary: 2,
|
|
22
|
+
success: 3,
|
|
23
|
+
danger: 4,
|
|
24
|
+
link: 5
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (typeof style === "string") {
|
|
28
|
+
style = styles[style.toLowerCase()]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
this.data.style = style
|
|
32
|
+
return this
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
setURL(url) {
|
|
36
|
+
this.data.url = url
|
|
37
|
+
return this
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
setDisabled(disabled = true) {
|
|
41
|
+
this.data.disabled = disabled
|
|
42
|
+
return this
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
toJSON() {
|
|
46
|
+
return this.data
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module.exports = ButtonBuilder
|
|
@@ -82,6 +82,40 @@ class EmbedBuilder {
|
|
|
82
82
|
return this
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
addField(name, value, inline = false) {
|
|
86
|
+
if (!this.data.fields) {
|
|
87
|
+
this.data.fields = []
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
this.data.fields.push({
|
|
91
|
+
name: name,
|
|
92
|
+
value: value,
|
|
93
|
+
inline: inline
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
return this
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
addFields(...fields) {
|
|
100
|
+
for (const field of fields) {
|
|
101
|
+
if (
|
|
102
|
+
!field ||
|
|
103
|
+
typeof field.name !== "string" ||
|
|
104
|
+
typeof field.value !== "string"
|
|
105
|
+
) {
|
|
106
|
+
continue
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
this.addField(
|
|
110
|
+
field.name,
|
|
111
|
+
field.value,
|
|
112
|
+
field.inline || false
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return this
|
|
117
|
+
}
|
|
118
|
+
|
|
85
119
|
toJSON() {
|
|
86
120
|
return this.data
|
|
87
121
|
}
|
package/structures/Message.js
CHANGED
|
@@ -1,22 +1,53 @@
|
|
|
1
1
|
class Message {
|
|
2
2
|
constructor(client, data) {
|
|
3
3
|
this.client = client
|
|
4
|
-
|
|
5
4
|
this.id = data.id
|
|
6
|
-
this.content = data.content
|
|
5
|
+
this.content = data.content || ""
|
|
7
6
|
this.channelId = data.channel_id
|
|
8
|
-
this.guildId = data.guild_id
|
|
9
|
-
this.author = data.author
|
|
7
|
+
this.guildId = data.guild_id || null
|
|
8
|
+
this.author = data.author || null
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
reply(content) {
|
|
13
|
-
|
|
11
|
+
async reply(content) {
|
|
12
|
+
const data = await this.client.api.request(
|
|
14
13
|
"POST",
|
|
15
14
|
`/channels/${this.channelId}/messages`,
|
|
16
15
|
{
|
|
17
16
|
content: content
|
|
18
17
|
}
|
|
19
18
|
)
|
|
19
|
+
|
|
20
|
+
if (!data || !data.id) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
"Discord did not return a valid message: " +
|
|
23
|
+
JSON.stringify(data)
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return new Message(this.client, data)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async edit(content) {
|
|
31
|
+
const data = await this.client.api.request(
|
|
32
|
+
"PATCH",
|
|
33
|
+
`/channels/${this.channelId}/messages/${this.id}`,
|
|
34
|
+
{
|
|
35
|
+
content: content
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
this.content = data.content || content
|
|
40
|
+
|
|
41
|
+
return this
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async delete() {
|
|
45
|
+
await this.client.api.request(
|
|
46
|
+
"DELETE",
|
|
47
|
+
`/channels/${this.channelId}/messages/${this.id}`
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
return true
|
|
20
51
|
}
|
|
21
52
|
}
|
|
22
53
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
class SelectMenuBuilder {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.data = {
|
|
4
|
+
type: 3,
|
|
5
|
+
options: []
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
setCustomId(customId) {
|
|
10
|
+
this.data.custom_id = customId
|
|
11
|
+
return this
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
setPlaceholder(placeholder) {
|
|
15
|
+
this.data.placeholder = placeholder
|
|
16
|
+
return this
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
addOptions(...options) {
|
|
20
|
+
for (const option of options) {
|
|
21
|
+
if (!option || !option.label || !option.value) {
|
|
22
|
+
continue
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const data = {
|
|
26
|
+
label: option.label,
|
|
27
|
+
value: option.value
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (option.description) {
|
|
31
|
+
data.description = option.description
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (option.emoji) {
|
|
35
|
+
data.emoji = option.emoji
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (option.default) {
|
|
39
|
+
data.default = true
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this.data.options.push(data)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return this
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
setMinValues(min) {
|
|
49
|
+
this.data.min_values = min
|
|
50
|
+
return this
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
setMaxValues(max) {
|
|
54
|
+
this.data.max_values = max
|
|
55
|
+
return this
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
setDisabled(disabled = true) {
|
|
59
|
+
this.data.disabled = disabled
|
|
60
|
+
return this
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
toJSON() {
|
|
64
|
+
return this.data
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = SelectMenuBuilder
|