@tryty/easydc-js 1.1.0 → 1.2.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/README.md +619 -504
- package/examples/mongo.js +44 -0
- package/index.d.ts +27 -6
- package/mongodb.d.ts +31 -0
- package/package.json +25 -4
- package/src/bot.js +105 -13
- package/src/database.js +24 -1
- package/src/functions/vars.js +8 -4
- package/src/index.js +2 -1
- package/src/plugins/mongodb.js +140 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# easydc-js
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A **super easy** Discord Bot wrapper built on top of [discord.js](https://discord.js.org). You only need to write commands using the `$function[argument]` syntax, without having to manually manage events, embeds, buttons, or databases.
|
|
4
4
|
|
|
5
5
|
```js
|
|
6
6
|
const { Bot } = require('easydc-js');
|
|
@@ -12,62 +12,63 @@ bot.command({ name: 'ping', code: '🏓 Pong! $ping ms' });
|
|
|
12
12
|
bot.connect();
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Type `!ping` in Discord → the bot replies `🏓 Pong! 42 ms`.
|
|
16
16
|
|
|
17
|
-
> **
|
|
17
|
+
> **Note:** This is an independent package, not an official part of discord.js. This package uses discord.js under the hood.
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
1. [
|
|
24
|
-
2. [
|
|
25
|
-
3. [Bot
|
|
26
|
-
4. [
|
|
27
|
-
5. [
|
|
28
|
-
6. [
|
|
29
|
-
7. [
|
|
30
|
-
8. [
|
|
31
|
-
9. [
|
|
32
|
-
10. [
|
|
33
|
-
11. [Eval (
|
|
34
|
-
12. [
|
|
35
|
-
13. [
|
|
36
|
-
14. [
|
|
37
|
-
15. [
|
|
38
|
-
16. [
|
|
21
|
+
## Table of Contents
|
|
22
|
+
|
|
23
|
+
1. [Installation](#1-installation)
|
|
24
|
+
2. [Creating a Bot on Discord](#2-creating-a-bot-on-discord)
|
|
25
|
+
3. [Your First Bot](#3-your-first-bot)
|
|
26
|
+
4. [How the `$function` Syntax Works](#4-how-the-function-syntax-works)
|
|
27
|
+
5. [Handler Types](#5-handler-types)
|
|
28
|
+
6. [Bot Options](#6-bot-options)
|
|
29
|
+
7. [Variables & Database](#7-variables--database)
|
|
30
|
+
8. [The `$if` Condition](#8-the-if-condition)
|
|
31
|
+
9. [Embeds, Buttons, Select Menus](#9-embeds-buttons-select-menus)
|
|
32
|
+
10. [Advanced Features: Modals, Autocomplete, Right-Click Menus, Polls, Threads, Webhooks](#10-advanced-features)
|
|
33
|
+
11. [Eval (Owner Only)](#11-eval-owner-only)
|
|
34
|
+
12. [Database & Plugins (MongoDB)](#12-database--plugins-mongodb)
|
|
35
|
+
13. [Creating Custom Functions](#13-creating-custom-functions)
|
|
36
|
+
14. [Splitting Commands into Multiple Files](#14-splitting-commands-into-multiple-files)
|
|
37
|
+
15. [Security](#15-security)
|
|
38
|
+
16. [Troubleshooting](#16-troubleshooting)
|
|
39
|
+
17. [List of All Functions](#17-list of-all-functions)
|
|
39
40
|
|
|
40
41
|
---
|
|
41
42
|
|
|
42
|
-
## 1.
|
|
43
|
+
## 1. Installation
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
Requires **Node.js 18.17 or newer**.
|
|
45
46
|
|
|
46
47
|
```bash
|
|
47
48
|
npm install easydc-js discord.js
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
## 2.
|
|
51
|
+
## 2. Creating a Bot on Discord
|
|
51
52
|
|
|
52
|
-
1.
|
|
53
|
-
2.
|
|
54
|
-
3.
|
|
55
|
-
- **Message Content Intent** (
|
|
56
|
-
- **Server Members Intent** (
|
|
57
|
-
4.
|
|
53
|
+
1. Open <https://discord.com/developers/applications> → **New Application**.
|
|
54
|
+
2. Go to the **Bot** menu → **Reset Token** → copy the token. **Do not share it with anyone.**
|
|
55
|
+
3. On the same page, enable **Privileged Gateway Intents**:
|
|
56
|
+
- **Message Content Intent** (required for commands starting with prefix `!` to be read)
|
|
57
|
+
- **Server Members Intent** (for member join/leave events & member info)
|
|
58
|
+
4. Go to the **OAuth2 → URL Generator** menu → check `bot` and `applications.commands` → select the required permissions → open the generated URL to invite the bot.
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
Store the token in environment variables, do not write it directly in your code:
|
|
60
61
|
|
|
61
62
|
```bash
|
|
62
63
|
# Linux / macOS
|
|
63
|
-
TOKEN="
|
|
64
|
+
TOKEN="your_token" node index.js
|
|
64
65
|
# Windows PowerShell
|
|
65
|
-
$env:TOKEN="
|
|
66
|
+
$env:TOKEN="your_token"; node index.js
|
|
66
67
|
```
|
|
67
68
|
|
|
68
|
-
## 3. Bot
|
|
69
|
+
## 3. Your First Bot
|
|
69
70
|
|
|
70
|
-
|
|
71
|
+
Create `index.js`:
|
|
71
72
|
|
|
72
73
|
```js
|
|
73
74
|
const { Bot } = require('easydc-js');
|
|
@@ -78,721 +79,835 @@ const bot = new Bot({
|
|
|
78
79
|
timezone: 'Asia/Jakarta',
|
|
79
80
|
});
|
|
80
81
|
|
|
81
|
-
bot.variables({
|
|
82
|
+
bot.variables({ money: 100 });
|
|
82
83
|
|
|
83
84
|
bot.command({
|
|
84
|
-
name: '
|
|
85
|
-
code: '💰 $username
|
|
85
|
+
name: 'money',
|
|
86
|
+
code: '💰 $username has $getUserVar[money] coins',
|
|
86
87
|
});
|
|
87
88
|
|
|
88
89
|
bot.command({
|
|
89
|
-
name: '
|
|
90
|
+
name: 'work',
|
|
90
91
|
code: `
|
|
91
|
-
$cooldown[1m;
|
|
92
|
-
$setUserVar[
|
|
93
|
-
|
|
92
|
+
$cooldown[1m;Take a rest first, please wait %time%.]
|
|
93
|
+
$setUserVar[money;$math[$getUserVar[money]+25]]
|
|
94
|
+
You got 25 coins! Total: $getUserVar[money]
|
|
94
95
|
`,
|
|
95
96
|
});
|
|
96
97
|
|
|
97
98
|
bot.connect();
|
|
98
99
|
```
|
|
99
100
|
|
|
100
|
-
|
|
101
|
+
A complete example can be found in [`examples/basic.js`](examples/basic.js).
|
|
101
102
|
|
|
102
|
-
## 4.
|
|
103
|
+
## 4. How the `$function` Syntax Works
|
|
103
104
|
|
|
104
105
|
```
|
|
105
|
-
$
|
|
106
|
+
$functionName[argument1;argument2;...]
|
|
106
107
|
```
|
|
107
108
|
|
|
108
|
-
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
109
|
+
- Arguments are separated by a **semicolon** `;`.
|
|
110
|
+
- Functions can be **nested**: `$toUpperCase[$username]`, `$math[$getUserVar[money]*2]`.
|
|
111
|
+
- Function names are **case-insensitive** (`$Username` = `$username`).
|
|
112
|
+
- Functions that do not require arguments are written without parentheses: `$ping`, `$serverName`.
|
|
113
|
+
- The final result of the entire text (after all `$functions` are executed) is sent as the bot's reply.
|
|
114
|
+
- Texts exceeding 2000 characters are automatically split into multiple messages.
|
|
114
115
|
|
|
115
|
-
###
|
|
116
|
+
### Writing Special Characters
|
|
116
117
|
|
|
117
|
-
|
|
118
|
+
To write `$ [ ] ;` characters as literal text, escape them with a backslash:
|
|
118
119
|
|
|
119
|
-
|
|
|
120
|
+
| Write | Result |
|
|
120
121
|
|---|---|
|
|
121
|
-
| `\$ping` | `$ping` (
|
|
122
|
+
| `\$ping` | `$ping` (will not be executed) |
|
|
122
123
|
| `\[` `\]` | `[` `]` |
|
|
123
|
-
| `\;` | `;` (
|
|
124
|
-
|
|
|
124
|
+
| `\;` | `;` (will not separate arguments) |
|
|
125
|
+
| `\` | `\` |
|
|
125
126
|
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
Alternatively, use the functions `$semicolon`, `$leftBracket`, `$rightBracket`, `$dollar`.
|
|
128
|
+
A `$` sign followed by a number or space (e.g., `price $5`) is automatically treated as plain text.
|
|
128
129
|
|
|
129
|
-
>
|
|
130
|
+
> Inside JavaScript template strings (backticks `` ` ``), backslashes need to be **doubled**: `` `\$ping` ``. If you want to avoid this, use `$dollar`.
|
|
130
131
|
|
|
131
|
-
###
|
|
132
|
+
### Code Validation Before Bot Starts
|
|
132
133
|
|
|
133
|
-
|
|
134
|
+
When `bot.connect()` is called, **all code is validated first**. If there is a misspelled function, wrong number of arguments, or an `$if` without an `$endif`, the bot **will not log in** and you will get a full list of issues, for example:
|
|
134
135
|
|
|
135
136
|
```
|
|
136
|
-
|
|
137
|
-
- command "ban":
|
|
138
|
-
- command "
|
|
137
|
+
Found 2 issues in the code:
|
|
138
|
+
- command "ban": Unknown function $bann (line 3, column 1)
|
|
139
|
+
- command "check": $if is not closed, add $endif (line 1, column 1)
|
|
139
140
|
```
|
|
140
141
|
|
|
141
|
-
## 5.
|
|
142
|
+
## 5. Handler Types
|
|
142
143
|
|
|
143
|
-
###
|
|
144
|
+
### Prefix Commands
|
|
144
145
|
|
|
145
146
|
```js
|
|
146
|
-
bot.command({ name: '
|
|
147
|
+
bot.command({ name: 'greet', aliases: ['hi', 'hello'], code: 'Hello $username!' });
|
|
147
148
|
```
|
|
148
149
|
|
|
149
|
-
|
|
150
|
+
Arguments after the command name: `$message` (all), `$message[1]` (1st word), `$argsCount`.
|
|
150
151
|
|
|
151
|
-
### Slash
|
|
152
|
+
### Slash Commands
|
|
152
153
|
|
|
153
154
|
```js
|
|
154
155
|
bot.slashCommand({
|
|
155
|
-
name: '
|
|
156
|
-
description: '
|
|
156
|
+
name: 'hello', // lowercase, no spaces
|
|
157
|
+
description: 'Greets someone',
|
|
157
158
|
options: [
|
|
158
|
-
{ name: '
|
|
159
|
-
{ name: '
|
|
159
|
+
{ name: 'name', description: 'Name', type: 'string', required: true },
|
|
160
|
+
{ name: 'age', description: 'Age', type: 'integer', minValue: 1 },
|
|
160
161
|
],
|
|
161
|
-
code: '
|
|
162
|
+
code: 'Hello, $option[name]!',
|
|
162
163
|
});
|
|
163
164
|
```
|
|
164
165
|
|
|
165
|
-
|
|
166
|
-
Slash
|
|
167
|
-
|
|
166
|
+
Option types: `string integer boolean user channel role mentionable number attachment`.
|
|
167
|
+
Slash commands are automatically registered when the bot is ready. For fast testing, set `slashGuild: 'GUILD_ID'` (appears instantly; global registration can take time).
|
|
168
|
+
If the process takes longer than 3 seconds, put `$defer` at the top of the code.
|
|
168
169
|
|
|
169
|
-
###
|
|
170
|
+
### Buttons & Select Menus
|
|
170
171
|
|
|
171
172
|
```js
|
|
172
173
|
bot.command({
|
|
173
|
-
name: '
|
|
174
|
-
code: '$addButton[
|
|
174
|
+
name: 'button',
|
|
175
|
+
code: '$addButton[Click;primary;click_1]$addButton[Web;link;https://example.com]Choose:',
|
|
175
176
|
});
|
|
176
177
|
|
|
177
|
-
bot.button({ customId: '
|
|
178
|
+
bot.button({ customId: 'click_*', code: '$ephemeral You pressed `$customID`' }); // * = wildcard
|
|
178
179
|
|
|
179
180
|
bot.command({
|
|
180
181
|
name: 'menu',
|
|
181
|
-
code: `
|
|
182
|
-
$addSelectMenu[
|
|
183
|
-
$addSelectOption[
|
|
184
|
-
$addSelectOption[
|
|
182
|
+
code: `Choose a fruit:
|
|
183
|
+
$addSelectMenu[fruit;Choose...]
|
|
184
|
+
$addSelectOption[Apple;apple;Red fruit]
|
|
185
|
+
$addSelectOption[Orange;orange]`,
|
|
185
186
|
});
|
|
186
|
-
bot.select({ customId: '
|
|
187
|
+
bot.select({ customId: 'fruit', code: 'You chose: $interactionValues' });
|
|
187
188
|
```
|
|
188
189
|
|
|
189
|
-
|
|
190
|
+
Use `$update` so that buttons/selects edit the original message instead of sending a new one.
|
|
190
191
|
|
|
191
|
-
###
|
|
192
|
+
### Events
|
|
192
193
|
|
|
193
|
-
|
|
|
194
|
+
| Short form | Executed when |
|
|
194
195
|
|---|---|
|
|
195
|
-
| `bot.onReady(code)` | bot
|
|
196
|
-
| `bot.onMemberJoin(code)` | member
|
|
197
|
-
| `bot.onMemberLeave(code)` | member
|
|
198
|
-
| `bot.onMessageDelete(code)` |
|
|
199
|
-
| `bot.onMessageUpdate(code)` |
|
|
200
|
-
| `bot.onReactionAdd(code)` / `onReactionRemove` |
|
|
201
|
-
| `bot.onGuildJoin(code)` / `onGuildLeave` | bot
|
|
202
|
-
| `bot.onMessage(code)` |
|
|
203
|
-
| `bot.onMemberBan(code)` / `onMemberUnban` | user
|
|
204
|
-
| `bot.onChannelCreate(code)` / `onChannelDelete` | channel
|
|
205
|
-
| `bot.onRoleCreate(code)` / `onRoleDelete` | role
|
|
206
|
-
| `bot.onThreadCreate(code)` | thread
|
|
207
|
-
| `bot.onVoiceJoin(code)` / `onVoiceLeave` | member
|
|
208
|
-
|
|
209
|
-
|
|
196
|
+
| `bot.onReady(code)` | bot is ready |
|
|
197
|
+
| `bot.onMemberJoin(code)` | member joins the server |
|
|
198
|
+
| `bot.onMemberLeave(code)` | member leaves |
|
|
199
|
+
| `bot.onMessageDelete(code)` | message is deleted |
|
|
200
|
+
| `bot.onMessageUpdate(code)` | message is edited |
|
|
201
|
+
| `bot.onReactionAdd(code)` / `onReactionRemove` | reaction is added / removed |
|
|
202
|
+
| `bot.onGuildJoin(code)` / `onGuildLeave` | bot joins / leaves a server |
|
|
203
|
+
| `bot.onMessage(code)` | every message that is **not** a command |
|
|
204
|
+
| `bot.onMemberBan(code)` / `onMemberUnban` | user is banned / ban lifted (`$targetID`, `$targetName`) |
|
|
205
|
+
| `bot.onChannelCreate(code)` / `onChannelDelete` | channel is created / deleted (`$targetName`) |
|
|
206
|
+
| `bot.onRoleCreate(code)` / `onRoleDelete` | role is created / deleted (`$targetName`) |
|
|
207
|
+
| `bot.onThreadCreate(code)` | new thread (reply is sent to that thread) |
|
|
208
|
+
| `bot.onVoiceJoin(code)` / `onVoiceLeave` | member joins / leaves voice (`$targetName` = voice name). Changing channels triggers both |
|
|
209
|
+
|
|
210
|
+
By default, replies are sent to the system channel of the server. Choose another channel using an object format:
|
|
210
211
|
|
|
211
212
|
```js
|
|
212
|
-
bot.onMemberJoin({ channel: '
|
|
213
|
+
bot.onMemberJoin({ channel: 'CHANNEL_ID', code: 'Welcome $mention! We are now $memberCount people.' });
|
|
213
214
|
```
|
|
214
215
|
|
|
215
|
-
## 6.
|
|
216
|
+
## 6. Bot Options
|
|
216
217
|
|
|
217
218
|
```js
|
|
218
219
|
new Bot({
|
|
219
|
-
token: '
|
|
220
|
-
prefix: '!', //
|
|
221
|
-
mentionPrefix: true, // @bot command
|
|
222
|
-
ignoreBots: true, //
|
|
223
|
-
owners: ['
|
|
224
|
-
timezone: 'Asia/Jakarta', //
|
|
220
|
+
token: 'REQUIRED',
|
|
221
|
+
prefix: '!', // or ['!', '?']
|
|
222
|
+
mentionPrefix: true, // @bot command works too
|
|
223
|
+
ignoreBots: true, // ignore messages from other bots
|
|
224
|
+
owners: ['YOUR_ID'], // for $onlyOwner and $isOwner
|
|
225
|
+
timezone: 'Asia/Jakarta', // for $date
|
|
225
226
|
intents: 'default', // 'default' | 'all' | ['Guilds', ...]
|
|
226
|
-
status: { text: '
|
|
227
|
-
slashGuild: null, // ID
|
|
228
|
-
syncSlash: true, //
|
|
229
|
-
database: { path: './easydc-data.json' }, //
|
|
230
|
-
messages: { cooldown: '⏳
|
|
231
|
-
debug: false, // true =
|
|
232
|
-
onError: (err, ctx) => {}, //
|
|
227
|
+
status: { text: 'with code', type: 'Playing', status: 'online' },
|
|
228
|
+
slashGuild: null, // server ID for fast slash deployment (null = global)
|
|
229
|
+
syncSlash: true, // auto register slash commands
|
|
230
|
+
database: { path: './easydc-data.json' }, // or { memory: true }
|
|
231
|
+
messages: { cooldown: '⏳ Wait %time%.', error: '❌ An error occurred.' },
|
|
232
|
+
debug: false, // true = show error causes in chat (development only!)
|
|
233
|
+
onError: (err, ctx) => {}, // handle errors manually
|
|
233
234
|
});
|
|
234
235
|
```
|
|
235
236
|
|
|
236
|
-
|
|
237
|
+
Default intents: `Guilds, GuildMessages, MessageContent, GuildMembers, GuildMessageReactions, DirectMessages, GuildModeration, GuildVoiceStates`.
|
|
237
238
|
|
|
238
|
-
|
|
239
|
+
Additional option: `eval: false` (turns on `$eval` / `$jsEval`, see [section 11](#11-eval-owner-only)).
|
|
239
240
|
|
|
240
|
-
## 7.
|
|
241
|
+
## 7. Variables & Database
|
|
241
242
|
|
|
242
|
-
|
|
243
|
+
Variables are permanently stored in a JSON file (`easydc-data.json`). Declare them first with default values:
|
|
243
244
|
|
|
244
245
|
```js
|
|
245
|
-
bot.variables({
|
|
246
|
+
bot.variables({ money: 0, bio: 'Not filled yet' });
|
|
246
247
|
```
|
|
247
248
|
|
|
248
|
-
|
|
|
249
|
+
| Function | Scope |
|
|
249
250
|
|---|---|
|
|
250
|
-
| `$getUserVar[
|
|
251
|
+
| `$getUserVar[name;userID?]` `$setUserVar[name;value;userID?]` `$resetUserVar` | per user |
|
|
251
252
|
| `$getServerVar` `$setServerVar` `$resetServerVar` | per server |
|
|
252
253
|
| `$getChannelVar` `$setChannelVar` `$resetChannelVar` | per channel |
|
|
253
|
-
| `$getGlobalVar` `$setGlobalVar` `$resetGlobalVar` |
|
|
254
|
+
| `$getGlobalVar` `$setGlobalVar` `$resetGlobalVar` | one for everyone |
|
|
254
255
|
|
|
255
|
-
|
|
256
|
-
|
|
256
|
+
All values are stored as **strings**. Use `$math[...]` for calculations.
|
|
257
|
+
Temporary variables during a single command execution: `$let[name;value]` and `$get[name]`.
|
|
257
258
|
|
|
258
|
-
-
|
|
259
|
-
-
|
|
260
|
-
-
|
|
259
|
+
- To use MongoDB, see [section 12](#12-database--plugins-mongodb).
|
|
260
|
+
- The database file is written safely and automatically. If the file is corrupted, it is **backed up** (`*.corrupt-<timestamp>`) and the bot starts fresh instead of crashing.
|
|
261
|
+
- For large bots (thousands of active users), consider using a real database; the built-in `Database` is suitable for small to medium bots.
|
|
262
|
+
- **A single database file must only be used by one bot process.**
|
|
261
263
|
|
|
262
|
-
## 8.
|
|
264
|
+
## 8. The `$if` Condition
|
|
263
265
|
|
|
264
266
|
```
|
|
265
|
-
$if[
|
|
267
|
+
$if[condition]
|
|
266
268
|
...
|
|
267
|
-
$elseif[
|
|
269
|
+
$elseif[condition]
|
|
268
270
|
...
|
|
269
271
|
$else
|
|
270
272
|
...
|
|
271
273
|
$endif
|
|
272
274
|
```
|
|
273
275
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
+
Operators: `== != > < >= <=`, combined with `&&` (and) / `||` (or). No parentheses required.
|
|
277
|
+
If both sides are numbers, they are compared numerically (`10>9` is true); otherwise, they are compared as text.
|
|
276
278
|
|
|
277
279
|
```
|
|
278
|
-
$if[$getUserVar[
|
|
279
|
-
|
|
280
|
-
$elseif[$getUserVar[
|
|
281
|
-
|
|
280
|
+
$if[$getUserVar[money]>=100&&$isAdmin==true]
|
|
281
|
+
Rich and admin
|
|
282
|
+
$elseif[$getUserVar[money]>=100]
|
|
283
|
+
Rich
|
|
282
284
|
$else
|
|
283
|
-
|
|
285
|
+
Poor
|
|
284
286
|
$endif
|
|
285
287
|
```
|
|
286
288
|
|
|
287
|
-
**
|
|
289
|
+
**Injection safe:** dynamic values like `$message` cannot be used by users to inject operators like `&&`, `||`, and similar into the condition. The user content is always treated as a plain text string.
|
|
288
290
|
|
|
289
|
-
|
|
291
|
+
Other constraints: `$onlyIf[condition;message?]`, `$stop[message?]`, `$onlyPerms`, `$onlyAdmin`, `$onlyOwner`, `$onlyForIDs`, `$onlyInServer`, `$argsCheck`, `$cooldown`.
|
|
290
292
|
|
|
291
|
-
## 9.
|
|
293
|
+
## 9. Embeds, Buttons, Select Menus
|
|
292
294
|
|
|
293
295
|
```js
|
|
294
296
|
bot.command({
|
|
295
297
|
name: 'info',
|
|
296
298
|
code: `
|
|
297
299
|
$title[Info $serverName]
|
|
298
|
-
$description[
|
|
300
|
+
$description[This server has $memberCount members.]
|
|
299
301
|
$color[#5865F2]
|
|
300
302
|
$thumbnail[$serverIcon]
|
|
301
|
-
$addField[
|
|
303
|
+
$addField[Created;$discordTime[$serverCreatedAt;D];true]
|
|
302
304
|
$addField[Ping;$ping ms;true]
|
|
303
|
-
$footer[
|
|
305
|
+
$footer[Requested by $username]
|
|
304
306
|
$addTimestamp
|
|
305
307
|
`,
|
|
306
308
|
});
|
|
307
309
|
```
|
|
308
310
|
|
|
309
|
-
-
|
|
310
|
-
-
|
|
311
|
-
-
|
|
312
|
-
-
|
|
311
|
+
- The first embed is created automatically; `$newEmbed` starts the next embed (maximum 10).
|
|
312
|
+
- Colors: `#RRGGBB`, names (`red green blue yellow orange purple pink white black grey blurple`), or `random`.
|
|
313
|
+
- Buttons: maximum 5 per row, 5 rows per message. New rows are made automatically, or can be forced using `$newRow`.
|
|
314
|
+
- Text length is validated against Discord limits, providing clear error messages if exceeded.
|
|
313
315
|
|
|
314
|
-
## 10.
|
|
316
|
+
## 10. Advanced Features
|
|
315
317
|
|
|
316
|
-
###
|
|
318
|
+
### Modals (Pop-up Forms)
|
|
317
319
|
|
|
318
|
-
|
|
320
|
+
Modals must be the **first** response to a slash command, button, or select menu interaction (do not use `$defer` beforehand; other texts in that command will be ignored).
|
|
319
321
|
|
|
320
322
|
```js
|
|
321
323
|
bot.slashCommand({
|
|
322
|
-
name: '
|
|
323
|
-
description: '
|
|
324
|
+
name: 'report',
|
|
325
|
+
description: 'Send a report',
|
|
324
326
|
code: `
|
|
325
|
-
$addModal[
|
|
326
|
-
$addTextInput[
|
|
327
|
-
$addTextInput[
|
|
327
|
+
$addModal[report_form;Report Form]
|
|
328
|
+
$addTextInput[title;Title;short;Keep it brief;true;3;50]
|
|
329
|
+
$addTextInput[content;Report content;paragraph]
|
|
328
330
|
`,
|
|
329
331
|
});
|
|
330
332
|
|
|
331
333
|
bot.modal({
|
|
332
|
-
customId: '
|
|
333
|
-
code: '$ephemeral
|
|
334
|
+
customId: 'report_form', // card wildcards allowed: 'report_*'
|
|
335
|
+
code: '$ephemeral Thank you! Title: $modalValue[title] | Content: $modalValue[content]',
|
|
334
336
|
});
|
|
335
337
|
```
|
|
336
338
|
|
|
337
|
-
|
|
339
|
+
Maximum 5 inputs per modal. `$addTextInput[customID;label;style?;placeholder?;required?;min?;max?;initialValue?]`, styles are `short` or `paragraph`.
|
|
338
340
|
|
|
339
|
-
### Autocomplete (
|
|
341
|
+
### Autocomplete (Dynamic Choices in Slash Commands)
|
|
340
342
|
|
|
341
343
|
```js
|
|
342
344
|
bot.slashCommand({
|
|
343
|
-
name: '
|
|
344
|
-
description: '
|
|
345
|
-
options: [{ name: '
|
|
346
|
-
code: '
|
|
345
|
+
name: 'fruit',
|
|
346
|
+
description: 'Select a fruit',
|
|
347
|
+
options: [{ name: 'name', description: 'Fruit name', autocomplete: true }], // cannot be used together with "choices"
|
|
348
|
+
code: 'You selected $option[name]',
|
|
347
349
|
});
|
|
348
350
|
|
|
349
351
|
bot.autocomplete({
|
|
350
|
-
command: '
|
|
351
|
-
option: '
|
|
352
|
+
command: 'fruit',
|
|
353
|
+
option: 'name', // leave empty for all autocomplete options in that command
|
|
352
354
|
code: `
|
|
353
|
-
$if[$checkContains[
|
|
354
|
-
$addChoice[
|
|
355
|
-
$addChoice[
|
|
355
|
+
$if[$checkContains[apple;$toLowerCase[$focusedValue]]==true]$addChoice[Apple;apple]$endif
|
|
356
|
+
$addChoice[Orange;orange]
|
|
357
|
+
$addChoice[Mango;mangga]
|
|
356
358
|
`,
|
|
357
359
|
});
|
|
358
360
|
```
|
|
359
361
|
|
|
360
|
-
`$focusedValue` =
|
|
362
|
+
`$focusedValue` = the text currently typed by the user. `$addChoice[name;value?]` max 25 choices. For `integer`/`number` options, the choice value must be a number. Discord gives 3 seconds to respond, so do not use `$wait`.
|
|
361
363
|
|
|
362
|
-
###
|
|
364
|
+
### Right-Click Menus (Context Menus)
|
|
363
365
|
|
|
364
366
|
```js
|
|
365
|
-
bot.contextMenu({ name: '
|
|
366
|
-
bot.contextMenu({ name: '
|
|
367
|
+
bot.contextMenu({ name: 'View Profile', menu: 'user', code: '$ephemeral Profile: $targetName (ID $targetID)' });
|
|
368
|
+
bot.contextMenu({ name: 'Report Message', menu: 'message', code: '$ephemeral Message "$targetContent" from $targetName reported.' });
|
|
367
369
|
```
|
|
368
370
|
|
|
369
|
-
|
|
371
|
+
Appears under the *Apps* menu when a user right-clicks a user or a message. Automatically registered alongside slash commands.
|
|
370
372
|
|
|
371
|
-
###
|
|
373
|
+
### User / Role / Channel Select Menus
|
|
372
374
|
|
|
373
375
|
```
|
|
374
|
-
$addUserSelect[
|
|
375
|
-
$addRoleSelect[
|
|
376
|
-
$addMentionableSelect[
|
|
377
|
-
$addChannelSelect[
|
|
376
|
+
$addUserSelect[select_user;Select user;1;3]
|
|
377
|
+
$addRoleSelect[select_role]
|
|
378
|
+
$addMentionableSelect[select_anything]
|
|
379
|
+
$addChannelSelect[select_channel;Select channel;;;text,voice]
|
|
378
380
|
```
|
|
379
381
|
|
|
380
|
-
|
|
382
|
+
Register handlers via `bot.select({ customId: 'select_user', code: 'Selected: $interactionValues' })`. Values are comma-separated IDs.
|
|
381
383
|
|
|
382
|
-
###
|
|
384
|
+
### Attachments, Polls, Webhooks
|
|
383
385
|
|
|
384
386
|
```
|
|
385
|
-
$addAttachment[https://example.com/
|
|
386
|
-
$addTextFile[
|
|
387
|
-
$poll[
|
|
388
|
-
$sendWebhook[https://discord.com/api/webhooks/ID/TOKEN;
|
|
387
|
+
$addAttachment[https://example.com/image.png;image.png]
|
|
388
|
+
$addTextFile[notes.txt;custom text file content created on the fly]
|
|
389
|
+
$poll[What to eat?;24;false;Chips;Noodles;Bread]
|
|
390
|
+
$sendWebhook[https://discord.com/api/webhooks/ID/TOKEN;Hello!;Bot Name;https://example.com/avatar.png]
|
|
389
391
|
```
|
|
390
392
|
|
|
391
|
-
|
|
393
|
+
Attachments only accept `http(s)` URLs or custom on-the-fly text strings (the bot does not read files from disk). `$poll[question;hours;multi;options...]` requires 2-10 options.
|
|
392
394
|
|
|
393
|
-
###
|
|
395
|
+
### Threads, Forums, and Guild Management
|
|
394
396
|
|
|
395
397
|
```
|
|
396
|
-
$createThread[
|
|
397
|
-
$createForumPost[
|
|
398
|
-
$unban[ID;
|
|
399
|
-
$createChannel[info;text;
|
|
398
|
+
$createThread[Discussion;$messageID;1440] -> returns thread ID
|
|
399
|
+
$createForumPost[FORUM_ID;Title;Content]
|
|
400
|
+
$unban[ID;reason] $isBanned[ID] $banCount
|
|
401
|
+
$createChannel[info;text;CATEGORY_ID;Topic] $lockChannel $unlockChannel
|
|
400
402
|
$createRole[VIP;#ff0000;true] $createInvite[;3600;10]
|
|
401
|
-
$createEvent[
|
|
403
|
+
$createEvent[WatchParty;START_MS;END_MS;Voice 1;Description]
|
|
402
404
|
```
|
|
403
405
|
|
|
404
|
-
|
|
406
|
+
Management functions use **bot permissions**, so make sure to protect them with `$onlyPerms[...]` as explained in the [Security](#15-security) section. The full list is located in the [List of All Functions](#17-list-of-all-functions) section.
|
|
405
407
|
|
|
406
408
|
---
|
|
407
409
|
|
|
408
|
-
## 11. Eval (
|
|
410
|
+
## 11. Eval (Owner Only)
|
|
409
411
|
|
|
410
|
-
Eval
|
|
412
|
+
Eval executes code inputted dynamically while the bot is running, which is useful for debugging. There are two types:
|
|
411
413
|
|
|
412
|
-
|
|
|
414
|
+
| Function | Code Language Executed |
|
|
413
415
|
|---|---|
|
|
414
|
-
| `$eval[
|
|
415
|
-
| `$jsEval[
|
|
416
|
+
| `$eval[code]` | Wrapper-version code, which uses this package's `$function` syntax |
|
|
417
|
+
| `$jsEval[code]` | JavaScript / **native discord.js** |
|
|
416
418
|
|
|
417
|
-
|
|
419
|
+
In `$jsEval`, the following variables are available: `ctx` `client` `bot` `guild` `channel` `message` `user` `member` `interaction` `discord` (discord.js module) `db` `require`. A single expression is directly returned; for multiple statements, use `return`. Supports `await`.
|
|
418
420
|
|
|
419
|
-
###
|
|
421
|
+
### Easiest Way to Use
|
|
420
422
|
|
|
421
423
|
```js
|
|
422
424
|
const bot = new Bot({
|
|
423
425
|
token: process.env.TOKEN,
|
|
424
|
-
owners: ['
|
|
425
|
-
eval: true, // eval
|
|
426
|
+
owners: ['YOUR_DISCORD_ID'],
|
|
427
|
+
eval: true, // eval is DISABLED unless turned on here
|
|
426
428
|
});
|
|
427
429
|
|
|
428
|
-
bot.evalCommand(); //
|
|
430
|
+
bot.evalCommand(); // mounts the "eval" command (name can be changed: { name: 'e', aliases: ['ev'] })
|
|
429
431
|
```
|
|
430
432
|
|
|
431
|
-
|
|
433
|
+
Then in Discord:
|
|
432
434
|
|
|
433
435
|
```
|
|
434
|
-
!eval $math[6*7] ->
|
|
435
|
-
!eval
|
|
436
|
-
!eval js client.guilds.cache.size -> discord.js
|
|
436
|
+
!eval $math[6*7] -> wrapper syntax version
|
|
437
|
+
!eval Hello $username from $serverName
|
|
438
|
+
!eval js client.guilds.cache.size -> native discord.js
|
|
437
439
|
!eval js guild.members.cache.filter(m => m.user.bot).size
|
|
438
440
|
!eval js const g = await client.guilds.fetch(guild.id);
|
|
439
441
|
return g.memberCount;
|
|
440
442
|
```
|
|
441
443
|
|
|
442
|
-
|
|
444
|
+
Results are sent inside a code block (max ±1800 characters), errors are displayed as `❌ ...`, and **tokens are automatically censored** from the output.
|
|
443
445
|
|
|
444
|
-
|
|
446
|
+
Can also be used in custom commands: `$eval[$message]` and `$jsEval[$message]`. Use `$messageFrom[2]` to get all text starting from the 2nd word (preserving spaces and newlines).
|
|
445
447
|
|
|
446
|
-
### ⚠️
|
|
448
|
+
### ⚠️ Security Warnings
|
|
447
449
|
|
|
448
|
-
- **`$jsEval`
|
|
449
|
-
-
|
|
450
|
-
-
|
|
451
|
-
-
|
|
452
|
-
-
|
|
453
|
-
- `$eval`
|
|
450
|
+
- **`$jsEval` grants FULL access** to the bot and the machine it runs on: reading files, environment variables, sending data out, and even terminating the process. Eval only runs if `eval: true` **and** the sender is listed in `owners`; otherwise, it is rejected immediately.
|
|
451
|
+
- Only include **YOUR OWN** ID in `owners`. Do not grant access to anyone else, including "trusted admins".
|
|
452
|
+
- If the owner's Discord account is compromised, the attacker can take over your hosting server. Enable 2FA.
|
|
453
|
+
- Disable `eval` (remove `eval: true`) in production bots that do not need it.
|
|
454
|
+
- Token censoring is just an accidental leaks prevention tool, not a foolproof security measure: JS code can still read tokens and send them elsewhere.
|
|
455
|
+
- Nested `$eval` calls are limited to 3 levels. Infinite loops (`while(true){}`) in `$jsEval` cannot be stopped and will freeze the bot until it is restarted.
|
|
454
456
|
|
|
455
457
|
---
|
|
456
458
|
|
|
457
|
-
## 12.
|
|
459
|
+
## 12. Database & Plugins (MongoDB)
|
|
460
|
+
|
|
461
|
+
By default, variable data is saved in the `easydc-data.json` file. For production bots (where data shouldn't be lost when a hosting provider deletes files, or when running across multiple servers), use **MongoDB** via a plugin.
|
|
462
|
+
|
|
463
|
+
### Install the MongoDB Plugin
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
npm install easydc-js discord.js mongodb
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
```js
|
|
470
|
+
const { Bot } = require('easydc-js');
|
|
471
|
+
const { mongodb } = require('easydc-js/mongodb');
|
|
472
|
+
|
|
473
|
+
const bot = new Bot({ token: process.env.TOKEN, prefix: '!' });
|
|
474
|
+
|
|
475
|
+
bot.use(mongodb({
|
|
476
|
+
uri: process.env.MONGO_URI, // e.g., mongodb+srv://user:pass@cluster0.xxxx.mongodb.net
|
|
477
|
+
dbName: 'mybot', // database name (automatically created by MongoDB)
|
|
478
|
+
}));
|
|
479
|
+
|
|
480
|
+
bot.variables({ money: 100 });
|
|
481
|
+
bot.command({ name: 'work', code: '$incUserVar[money;25]Your money is now $getUserVar[money]' });
|
|
482
|
+
|
|
483
|
+
bot.connect();
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
That's the only change required: all `$getUserVar`, `$setUserVar`, etc., will automatically use MongoDB. `bot.use(...)` must be called **before** `bot.connect()`.
|
|
487
|
+
|
|
488
|
+
How to get free MongoDB: create a cluster on MongoDB Atlas (M0 tier), create a database user, whitelist your hosting IP in *Network Access*, and copy the *connection string*. Store it in the `MONGO_URI` environment variable, **do not write it in the code**.
|
|
489
|
+
|
|
490
|
+
### Plugin Options
|
|
491
|
+
|
|
492
|
+
| Option | Description |
|
|
493
|
+
|---|---|
|
|
494
|
+
| `uri` | MongoDB URI string (required). |
|
|
495
|
+
| `dbName` | Database name. If empty, uses the database name from the URI, or `test`. |
|
|
496
|
+
| `collection` | Collection name, defaults to `easydc`. Each variable = one document `{ _id, v, t }`. |
|
|
497
|
+
| `cache` | Defaults to `true`: read data is cached in RAM for speed. **Change to `false` if multiple bot processes share the database**, otherwise data can become stale. |
|
|
498
|
+
| `cacheLimit` | Maximum keys in cache (defaults to 10000). |
|
|
499
|
+
| `client` | Custom `MongoClient` instance (will not be automatically closed by the bot). |
|
|
500
|
+
| `clientOptions` | Additional options passed to `new MongoClient(uri, options)`. |
|
|
501
|
+
|
|
502
|
+
If MongoDB cannot be reached, the bot **will not log in** and prints `Failed to connect to database: ...` (timeout is 10 seconds).
|
|
503
|
+
|
|
504
|
+
### Migrating Old Data (JSON → MongoDB)
|
|
505
|
+
|
|
506
|
+
A one-time script, run it in the bot's root folder before using the plugin:
|
|
507
|
+
|
|
508
|
+
```js
|
|
509
|
+
const { Database, copyDatabase } = require('easydc-js');
|
|
510
|
+
const { MongoDatabase } = require('easydc-js/mongodb');
|
|
511
|
+
|
|
512
|
+
(async () => {
|
|
513
|
+
const oldDb = new Database({ path: './easydc-data.json' });
|
|
514
|
+
const newDb = new MongoDatabase({ uri: process.env.MONGO_URI, dbName: 'mybot' });
|
|
515
|
+
await newDb.connect();
|
|
516
|
+
console.log(await copyDatabase(oldDb, newDb)); // { copied: 120, skipped: 0 }
|
|
517
|
+
await newDb.close();
|
|
518
|
+
})();
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
Existing data in MongoDB will not be overwritten. Pass `{ overwrite: true }` as the third argument if you wish to overwrite it.
|
|
522
|
+
|
|
523
|
+
### `$inc...Var`: Safely Incrementing Numbers
|
|
524
|
+
|
|
525
|
+
The `$setUserVar[money;$math[$getUserVar[money]+10]]` pattern can **lose data** if two commands execute concurrently (both reading the old value). Instead, use:
|
|
526
|
+
|
|
527
|
+
```
|
|
528
|
+
$incUserVar[money;10] $incUserVar[money;-5] (decrease)
|
|
529
|
+
$incServerVar $incChannelVar $incGlobalVar
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
`$incUserVar[name;amount;userID?]` executes sequentially per variable, ensuring they do not overwrite each other. This safety applies within a **single bot process**; if you run multiple bot instances on the same database, cross-process collisions can still occur.
|
|
533
|
+
|
|
534
|
+
### Creating a Custom Plugin / Database Adapter
|
|
535
|
+
|
|
536
|
+
A plugin is either a function or an object `{ name, install(bot, options) }`; `install` must be synchronous.
|
|
537
|
+
|
|
538
|
+
```js
|
|
539
|
+
bot.use({
|
|
540
|
+
name: 'hello',
|
|
541
|
+
install(bot) {
|
|
542
|
+
bot.addFunction({ name: '$hello', params: 0, run: () => 'Hello from plugin!' });
|
|
543
|
+
},
|
|
544
|
+
});
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
A database adapter (for Redis, SQLite, etc.) just needs to be an object with the following methods; all of them can be `async`:
|
|
548
|
+
|
|
549
|
+
| Method | Required | Description |
|
|
550
|
+
|---|---|---|
|
|
551
|
+
| `get(key)` | yes | Return the value (string) or `undefined` if missing. |
|
|
552
|
+
| `set(key, value)` | yes | Store a string value. |
|
|
553
|
+
| `delete(key)` | yes | Delete a key. |
|
|
554
|
+
| `keys(prefix?)` | no | Needed for `copyDatabase`. |
|
|
555
|
+
| `connect()` / `close()` | no | Called before logging into Discord / when the bot shuts down. |
|
|
556
|
+
| `flush()` | no | Save pending data. |
|
|
557
|
+
|
|
558
|
+
Install using `bot.setDatabase(adapter)` or `new Bot({ database: adapter })`.
|
|
559
|
+
|
|
560
|
+
> **Changes from version 1.1:** `bot.getVar`, `bot.setVar`, `bot.resetVar` now return a **Promise** (use `await`). `$function` styled commands are unaffected.
|
|
561
|
+
|
|
562
|
+
---
|
|
563
|
+
|
|
564
|
+
## 13. Creating Custom Functions
|
|
458
565
|
|
|
459
566
|
```js
|
|
460
567
|
bot.addFunction({
|
|
461
|
-
name: '$
|
|
462
|
-
params: 1, //
|
|
463
|
-
description: '
|
|
464
|
-
run: (ctx, [
|
|
568
|
+
name: '$greetUser',
|
|
569
|
+
params: 1, // exact number of arguments (or use min/max)
|
|
570
|
+
description: 'Greets someone',
|
|
571
|
+
run: (ctx, [name]) => `Welcome, ${name}! (requested by ${ctx.user.username})`,
|
|
465
572
|
});
|
|
466
573
|
|
|
467
|
-
bot.command({ name: '
|
|
574
|
+
bot.command({ name: 'test', code: '$greetUser[Budi]' });
|
|
468
575
|
```
|
|
469
576
|
|
|
470
|
-
`run`
|
|
471
|
-
|
|
577
|
+
`run` can be `async`. `ctx` contains `bot`, `client`, `guild`, `channel`, `member`, `user`, `message`, `interaction`, `args`. Throw `new Error('message')` on failure; the message will be printed to logs.
|
|
578
|
+
The option `override: true` overwrites built-in functions.
|
|
472
579
|
|
|
473
|
-
##
|
|
580
|
+
## 14. Splitting Commands into Multiple Files
|
|
474
581
|
|
|
475
582
|
```
|
|
476
|
-
|
|
583
|
+
project/
|
|
477
584
|
├── index.js
|
|
478
585
|
└── commands/
|
|
479
|
-
├──
|
|
480
|
-
└──
|
|
586
|
+
├── general.js
|
|
587
|
+
└── moderation.js
|
|
481
588
|
```
|
|
482
589
|
|
|
483
590
|
```js
|
|
484
591
|
bot.loadCommands('./commands');
|
|
485
592
|
```
|
|
486
593
|
|
|
487
|
-
|
|
594
|
+
Each file exports a single object or an array. Add a `type` for anything other than regular prefix commands (`'slash'`, `'button'`, `'select'`, `'modal'`, `'autocomplete'`, `'contextMenu'`, or an event name like `'memberJoin'`). Complete example: [`examples/advanced/lanjutan.js`](examples/advanced/lanjutan.js).
|
|
488
595
|
|
|
489
596
|
```js
|
|
490
597
|
module.exports = [
|
|
491
|
-
{ name: '
|
|
492
|
-
{ type: 'slash', name: 'ping', description: '
|
|
493
|
-
{ type: 'button', customId: 'ok_*', code: '
|
|
494
|
-
{ type: 'memberJoin', code: '
|
|
598
|
+
{ name: 'hello', code: 'Hello $username' },
|
|
599
|
+
{ type: 'slash', name: 'ping', description: 'Check ping', code: '$ping ms' },
|
|
600
|
+
{ type: 'button', customId: 'ok_*', code: 'Ok!' },
|
|
601
|
+
{ type: 'memberJoin', code: 'Welcome $mention' },
|
|
495
602
|
];
|
|
496
603
|
```
|
|
497
604
|
|
|
498
|
-
##
|
|
605
|
+
## 15. Security
|
|
499
606
|
|
|
500
|
-
- **
|
|
501
|
-
-
|
|
502
|
-
-
|
|
503
|
-
-
|
|
504
|
-
-
|
|
607
|
+
- **Never put tokens in your code** or push them to GitHub. Use environment variables. If a token leaks, immediately *Reset Token* in the Developer Portal.
|
|
608
|
+
- Action and management functions (`$ban`, `$unban`, `$kick`, `$timeout`, `$addRole`, `$clear`, `$sendDM`, `$createChannel`, `$deleteChannel`, `$deleteRole`, `$lockChannel`, `$leaveServer`, ...) run using **bot permissions**, not the sender's permissions. **Always** protect them with `$onlyPerms[...]`, `$onlyAdmin`, or `$onlyOwner` on the first line of the command.
|
|
609
|
+
- Mentions sent by the bot are restricted to users only (`@everyone` and roles will not ping anyone). Modify this via the `allowedMentions` option if necessary.
|
|
610
|
+
- The `$math` calculator does not use `eval`, making it safe from arbitrary code execution.
|
|
611
|
+
- Leave `debug: false` in production so that detailed error messages are not revealed to users (they will still be logged to the console).
|
|
505
612
|
|
|
506
|
-
##
|
|
613
|
+
## 16. Troubleshooting
|
|
507
614
|
|
|
508
|
-
|
|
|
615
|
+
| Issue | Cause / Solution |
|
|
509
616
|
|---|---|
|
|
510
|
-
| Bot online
|
|
511
|
-
| `Used disallowed intents`
|
|
512
|
-
|
|
|
513
|
-
| Slash
|
|
514
|
-
| `
|
|
515
|
-
| `...
|
|
516
|
-
|
|
|
517
|
-
|
|
|
518
|
-
| `Missing Permissions`
|
|
519
|
-
| `Token
|
|
520
|
-
|
|
|
521
|
-
| Modal
|
|
522
|
-
| Autocomplete
|
|
523
|
-
|
|
|
524
|
-
|
|
|
617
|
+
| Bot is online but does not respond to `!ping` | Enable **Message Content Intent** in the Developer Portal. |
|
|
618
|
+
| `Used disallowed intents` when logging in | Enable requested intents in the Developer Portal (Server Members / Message Content), or reduce your `intents`. |
|
|
619
|
+
| Member join/leave events are not working | Enable **Server Members Intent**. |
|
|
620
|
+
| Slash commands do not appear | Invite the bot with the `applications.commands` scope. Use `slashGuild` for immediate updates; global commands can take time. |
|
|
621
|
+
| `Unknown function $xxx` | Misspelling. If intended as plain text, write `\$xxx` (or `$dollar`). |
|
|
622
|
+
| `... requires N arguments` | Semicolon `;` count mismatch. Write `\;` if the semicolon is part of the text. |
|
|
623
|
+
| Variable "not declared" | Add it inside `bot.variables({ ... })` before calling `bot.connect()`. |
|
|
624
|
+
| Buttons/select menus do not respond | Ensure the `customId` on the button matches the one in `bot.button({ customId })`. |
|
|
625
|
+
| `Missing Permissions` in logs | The bot lacks permissions / the bot's highest role is below the target role. |
|
|
626
|
+
| `Token not provided` | `process.env.TOKEN` is empty. Check how to run the bot in section 2. |
|
|
627
|
+
| Interaction failed ("This interaction failed") | Process took > 3 seconds. Place `$defer` at the top of the command. |
|
|
628
|
+
| Modal does not appear / "Modal must be the first response" | Do not use `$defer` or send messages before `$addModal`. Modals are only available from slash/button/select triggers, not prefix commands. |
|
|
629
|
+
| Autocomplete list is empty | Options must be defined with `autocomplete: true`, and the `bot.autocomplete({ command, option })` handler must match. Process must finish in < 3 seconds. |
|
|
630
|
+
| `Package "mongodb" not found` | Run `npm install mongodb` (on panel hosting: add `mongodb` to *Additional Node Packages*). |
|
|
631
|
+
| `Failed to connect to database` | Check `MONGO_URI`, user & password, and whitelist your hosting IP in MongoDB Atlas (*Network Access*). Passwords with special characters (`@ : /`) must be URL-encoded. |
|
|
632
|
+
| Data in MongoDB does not update / looks stale | There is more than one bot process running on the same database: set `cache: false`. |
|
|
633
|
+
| `$eval ... is disabled` | Add `eval: true` and `owners: ['YOUR_ID']` inside `new Bot({...})`. |
|
|
634
|
+
| Ban / voice events are not working | `GuildModeration` / `GuildVoiceStates` intents are enabled by default; if you set `intents` manually, add both. |
|
|
525
635
|
|
|
526
636
|
---
|
|
527
637
|
|
|
528
|
-
##
|
|
638
|
+
## 17. List of All Functions
|
|
529
639
|
|
|
530
|
-
|
|
640
|
+
The `?` symbol means the argument is optional. This list is automatically generated from the source code (`npm run docs`).
|
|
531
641
|
|
|
532
642
|
<!-- FUNCTIONS:START -->
|
|
533
643
|
|
|
534
|
-
### Info (user, server, bot,
|
|
644
|
+
### Info (user, server, bot, message, time)
|
|
535
645
|
|
|
536
|
-
|
|
|
646
|
+
| Function | Description |
|
|
537
647
|
|---|---|
|
|
538
|
-
| `$username[userID?]` | Username (
|
|
539
|
-
| `$usertag[userID?]` |
|
|
540
|
-
| `$displayName[userID?]` |
|
|
541
|
-
| `$nickname[userID?]` | Nickname
|
|
542
|
-
| `$authorID` | ID
|
|
543
|
-
| `$userAvatar[userID?;
|
|
544
|
-
| `$isBot[userID?]` | true/false:
|
|
545
|
-
| `$userCreatedAt[userID?]` |
|
|
546
|
-
| `$mentioned[
|
|
547
|
-
| `$mention[userID?]` | Mention user,
|
|
548
|
-
| `$serverName` |
|
|
549
|
-
| `$serverID` | ID
|
|
550
|
-
| `$serverIcon` |
|
|
551
|
-
| `$memberCount` |
|
|
552
|
-
| `$ownerID` |
|
|
553
|
-
| `$serverCreatedAt` |
|
|
554
|
-
| `$roleCount` |
|
|
555
|
-
| `$channelCount` |
|
|
556
|
-
| `$channelName[channelID?]` |
|
|
557
|
-
| `$channelID` |
|
|
558
|
-
| `$channelMention[channelID?]` | Mention channel,
|
|
559
|
-
| `$roleName[roleID]` |
|
|
560
|
-
| `$roleMention[roleID]` | Mention role,
|
|
561
|
-
| `$botID` | ID
|
|
562
|
-
| `$botName` |
|
|
563
|
-
| `$ping` |
|
|
564
|
-
| `$uptime` |
|
|
565
|
-
| `$serverCount` |
|
|
566
|
-
| `$message[
|
|
567
|
-
| `$argsCount` |
|
|
568
|
-
| `$messageID` |
|
|
569
|
-
| `$messageContent` |
|
|
570
|
-
| `$commandName` |
|
|
571
|
-
| `$option[
|
|
572
|
-
| `$customID` | customId
|
|
573
|
-
| `$interactionValues[
|
|
574
|
-
| `$reactionEmoji` | Emoji
|
|
575
|
-
| `$timestamp` |
|
|
576
|
-
| `$unix` |
|
|
577
|
-
| `$date[format?;ms?]` |
|
|
578
|
-
| `$discordTime[ms?;
|
|
579
|
-
|
|
580
|
-
###
|
|
581
|
-
|
|
582
|
-
|
|
|
648
|
+
| `$username[userID?]` | Username (without ID = sender) |
|
|
649
|
+
| `$usertag[userID?]` | User tag |
|
|
650
|
+
| `$displayName[userID?]` | Display name (server nickname / global name / username) |
|
|
651
|
+
| `$nickname[userID?]` | Nickname in the server (empty -> username) |
|
|
652
|
+
| `$authorID` | ID of the message author / interaction user |
|
|
653
|
+
| `$userAvatar[userID?;size?]` | Avatar URL (size 16-4096) |
|
|
654
|
+
| `$isBot[userID?]` | true/false: whether the user is a bot |
|
|
655
|
+
| `$userCreatedAt[userID?]` | Account creation timestamp (ms) |
|
|
656
|
+
| `$mentioned[number;fallbackAuthor?]` | ID of the N-th mentioned user (if 2nd arg is yes = defaults to sender if absent) |
|
|
657
|
+
| `$mention[userID?]` | Mention a user, e.g., <@123> |
|
|
658
|
+
| `$serverName` | Server name |
|
|
659
|
+
| `$serverID` | Server ID |
|
|
660
|
+
| `$serverIcon` | Server icon URL |
|
|
661
|
+
| `$memberCount` | Number of server members |
|
|
662
|
+
| `$ownerID` | Server owner ID |
|
|
663
|
+
| `$serverCreatedAt` | Server creation timestamp (ms) |
|
|
664
|
+
| `$roleCount` | Number of roles |
|
|
665
|
+
| `$channelCount` | Number of channels |
|
|
666
|
+
| `$channelName[channelID?]` | Channel name (without ID = current channel) |
|
|
667
|
+
| `$channelID` | Current channel ID |
|
|
668
|
+
| `$channelMention[channelID?]` | Mention a channel, e.g., <#123> |
|
|
669
|
+
| `$roleName[roleID]` | Role name |
|
|
670
|
+
| `$roleMention[roleID]` | Mention a role, e.g., <@&123> |
|
|
671
|
+
| `$botID` | Bot ID |
|
|
672
|
+
| `$botName` | Bot username |
|
|
673
|
+
| `$ping` | Websocket ping (ms) |
|
|
674
|
+
| `$uptime` | Duration the bot has been online, e.g., "1d 2h 3m 4s" |
|
|
675
|
+
| `$serverCount` | Number of servers the bot is in |
|
|
676
|
+
| `$message[number?]` | All arguments after the command, or the N-th argument |
|
|
677
|
+
| `$argsCount` | Argument count |
|
|
678
|
+
| `$messageID` | Message / interaction ID |
|
|
679
|
+
| `$messageContent` | Full text content of the triggering message |
|
|
680
|
+
| `$commandName` | Name of the currently running command |
|
|
681
|
+
| `$option[name]` | Value of a slash command option |
|
|
682
|
+
| `$customID` | customId of the pressed button/select menu |
|
|
683
|
+
| `$interactionValues[number?]` | Selected values in a select menu |
|
|
684
|
+
| `$reactionEmoji` | Emoji from a reaction event |
|
|
685
|
+
| `$timestamp` | Current timestamp (ms) |
|
|
686
|
+
| `$unix` | Current timestamp (seconds) |
|
|
687
|
+
| `$date[format?;ms?]` | Date/time string. Tokens: YYYY MM DD HH mm ss. Timezone comes from bot option |
|
|
688
|
+
| `$discordTime[ms?;style?]` | Discord timestamp format <t:..>. Styles: t T d D f F R |
|
|
689
|
+
|
|
690
|
+
### Text, Math & Validation
|
|
691
|
+
|
|
692
|
+
| Function | Description |
|
|
583
693
|
|---|---|
|
|
584
|
-
| `$math[
|
|
585
|
-
| `$sum[a;b;...]` |
|
|
694
|
+
| `$math[expression]` | Safe evaluation. Supports + - * / % ^ ( ) sqrt abs round floor ceil min max pow pi e |
|
|
695
|
+
| `$sum[a;b;...]` | Sum of all numbers |
|
|
586
696
|
| `$sub[a;b]` | a - b |
|
|
587
|
-
| `$multiply[a;b;...]` |
|
|
697
|
+
| `$multiply[a;b;...]` | Multiply all numbers |
|
|
588
698
|
| `$divide[a;b]` | a / b |
|
|
589
|
-
| `$modulo[a;b]` |
|
|
590
|
-
| `$round[
|
|
591
|
-
| `$max[a;b;...]` |
|
|
592
|
-
| `$min[a;b;...]` |
|
|
593
|
-
| `$random[min;max]` |
|
|
594
|
-
| `$randomText[a;b;...]` |
|
|
595
|
-
| `$numberSeparator[
|
|
596
|
-
| `$toUpperCase[
|
|
597
|
-
| `$toLowerCase[
|
|
598
|
-
| `$capitalize[
|
|
599
|
-
| `$titleCase[
|
|
600
|
-
| `$trimSpace[
|
|
601
|
-
| `$length[
|
|
602
|
-
| `$reverse[
|
|
603
|
-
| `$repeat[
|
|
604
|
-
| `$substring[
|
|
605
|
-
| `$replaceText[
|
|
606
|
-
| `$split[
|
|
607
|
-
| `$urlEncode[
|
|
608
|
-
| `$semicolon` |
|
|
609
|
-
| `$leftBracket` |
|
|
610
|
-
| `$rightBracket` |
|
|
611
|
-
| `$dollar` |
|
|
612
|
-
| `$isNumber[
|
|
613
|
-
| `$checkContains[
|
|
614
|
-
| `$checkCondition[
|
|
615
|
-
| `$hasRole[roleID;userID?]` | true/false: member
|
|
616
|
-
| `$hasPerms[
|
|
617
|
-
| `$isAdmin[userID?]` | true/false: member administrator |
|
|
618
|
-
| `$isOwner[userID?]` | true/false: user
|
|
619
|
-
| `$isTrue[
|
|
620
|
-
|
|
621
|
-
###
|
|
622
|
-
|
|
623
|
-
|
|
|
699
|
+
| `$modulo[a;b]` | Remainder of division a % b |
|
|
700
|
+
| `$round[number;decimals?]` | Round a number |
|
|
701
|
+
| `$max[a;b;...]` | Largest number |
|
|
702
|
+
| `$min[a;b;...]` | Smallest number |
|
|
703
|
+
| `$random[min;max]` | Random integer (inclusive) |
|
|
704
|
+
| `$randomText[a;b;...]` | Randomly select one text block |
|
|
705
|
+
| `$numberSeparator[number;separator?]` | 1234567 -> 1,234,567 |
|
|
706
|
+
| `$toUpperCase[text]` | UPPERCASE |
|
|
707
|
+
| `$toLowerCase[text]` | lowercase |
|
|
708
|
+
| `$capitalize[text]` | Capitalize the first letter |
|
|
709
|
+
| `$titleCase[text]` | Capitalize The First Letter Of Each Word |
|
|
710
|
+
| `$trimSpace[text]` | Trim leading/trailing spaces |
|
|
711
|
+
| `$length[text]` | Character count |
|
|
712
|
+
| `$reverse[text]` | Reverse string order |
|
|
713
|
+
| `$repeat[text;count]` | Repeat text (max 100x) |
|
|
714
|
+
| `$substring[text;start;end?]` | Extract substring (0-based index) |
|
|
715
|
+
| `$replaceText[text;search;replace;limit?]` | Replace text (all, or first N occurrences) |
|
|
716
|
+
| `$split[text;delimiter;number]` | Get the N-th element after splitting text |
|
|
717
|
+
| `$urlEncode[text]` | URL encode a string |
|
|
718
|
+
| `$semicolon` | Literal character ; |
|
|
719
|
+
| `$leftBracket` | Literal character [ |
|
|
720
|
+
| `$rightBracket` | Literal character ] |
|
|
721
|
+
| `$dollar` | Literal character $ |
|
|
722
|
+
| `$isNumber[text]` | true/false: whether it's a number |
|
|
723
|
+
| `$checkContains[text;search1;search2;...]` | true if text contains any of the search words |
|
|
724
|
+
| `$checkCondition[condition]` | true/false. Operators: == != > < >= <= && \|\| |
|
|
725
|
+
| `$hasRole[roleID;userID?]` | true/false: member has role |
|
|
726
|
+
| `$hasPerms[perms1,perms2;userID?]` | true/false: member has all permissions (discord.js permission names) |
|
|
727
|
+
| `$isAdmin[userID?]` | true/false: member is an administrator |
|
|
728
|
+
| `$isOwner[userID?]` | true/false: user is listed in the bot's owners |
|
|
729
|
+
| `$isTrue[text]` | true if text evaluates to true/yes/1/on |
|
|
730
|
+
|
|
731
|
+
### Flow Control & Constraints
|
|
732
|
+
|
|
733
|
+
| Function | Description |
|
|
624
734
|
|---|---|
|
|
625
|
-
| `$if[
|
|
626
|
-
| `$elseif[
|
|
627
|
-
| `$else` |
|
|
628
|
-
| `$endif` |
|
|
629
|
-
| `$stop[
|
|
630
|
-
| `$onlyIf[
|
|
631
|
-
| `$onlyPerms[
|
|
632
|
-
| `$onlyBotPerms[
|
|
633
|
-
| `$onlyAdmin[
|
|
634
|
-
| `$onlyOwner[
|
|
635
|
-
| `$onlyForIDs[id1,id2;
|
|
636
|
-
| `$onlyInServer[
|
|
637
|
-
| `$argsCheck[
|
|
638
|
-
| `$cooldown[
|
|
639
|
-
| `$wait[
|
|
640
|
-
| `$deleteCommand` |
|
|
641
|
-
| `$deleteIn[
|
|
642
|
-
| `$ephemeral` | Slash/
|
|
643
|
-
| `$reply` |
|
|
644
|
-
| `$update` |
|
|
645
|
-
| `$typing` |
|
|
646
|
-
| `$defer` | Slash/
|
|
647
|
-
| `$let[
|
|
648
|
-
| `$get[
|
|
649
|
-
|
|
650
|
-
###
|
|
651
|
-
|
|
652
|
-
|
|
|
735
|
+
| `$if[condition]` | Start conditional block. Close with $endif |
|
|
736
|
+
| `$elseif[condition]` | Alternative condition |
|
|
737
|
+
| `$else` | If all previous conditions are false |
|
|
738
|
+
| `$endif` | Close $if block |
|
|
739
|
+
| `$stop[message?]` | Halt execution (optionally send a message) |
|
|
740
|
+
| `$onlyIf[condition;message?]` | Proceed only if the condition is true |
|
|
741
|
+
| `$onlyPerms[Perms1,Perms2;message?]` | Proceed only if the sender has all permissions (e.g., BanMembers) |
|
|
742
|
+
| `$onlyBotPerms[Perms1,Perms2;message?]` | Proceed only if the bot has those permissions in the server |
|
|
743
|
+
| `$onlyAdmin[message?]` | Proceed only if the sender is an administrator |
|
|
744
|
+
| `$onlyOwner[message?]` | Proceed only if the sender is in the owners option |
|
|
745
|
+
| `$onlyForIDs[id1,id2;message?]` | Proceed only for specific user IDs |
|
|
746
|
+
| `$onlyInServer[message?]` | Proceed only if used inside a server (not DMs) |
|
|
747
|
+
| `$argsCheck[requirement;message?]` | Check argument count. "2" = at least 2; also supports >=1 <=3 >1 <3 =2 |
|
|
748
|
+
| `$cooldown[time;message?]` | Cooldown per user per command. %time% in message = remaining time |
|
|
749
|
+
| `$wait[time]` | Pause execution briefly (max 60 seconds) |
|
|
750
|
+
| `$deleteCommand` | Delete the command message sent by the user after replying |
|
|
751
|
+
| `$deleteIn[time]` | Delete the bot's reply after a certain time (max 24 hours) |
|
|
752
|
+
| `$ephemeral` | Slash/button: make reply visible only to the user |
|
|
753
|
+
| `$reply` | Reply to the triggering command message directly using inline replies |
|
|
754
|
+
| `$update` | Button/select: edit original message instead of sending a new one |
|
|
755
|
+
| `$typing` | Display "is typing" status |
|
|
756
|
+
| `$defer` | Slash/button: defer reply (for processes > 3s). Put $ephemeral before this if needed |
|
|
757
|
+
| `$let[name;value]` | Save a temporary variable (lasts only during command execution) |
|
|
758
|
+
| `$get[name]` | Retrieve a temporary variable from $let |
|
|
759
|
+
|
|
760
|
+
### Variables & Database
|
|
761
|
+
|
|
762
|
+
| Function | Description |
|
|
653
763
|
|---|---|
|
|
654
|
-
| `$setUserVar[
|
|
655
|
-
| `$getUserVar[
|
|
656
|
-
| `$resetUserVar[
|
|
657
|
-
| `$
|
|
658
|
-
| `$
|
|
659
|
-
| `$
|
|
660
|
-
| `$
|
|
661
|
-
| `$
|
|
662
|
-
| `$
|
|
663
|
-
| `$
|
|
664
|
-
| `$
|
|
665
|
-
| `$
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
|
764
|
+
| `$setUserVar[name;value;userID?]` | Save a user variable (must be declared via bot.variables) |
|
|
765
|
+
| `$getUserVar[name;userID?]` | Read a user variable |
|
|
766
|
+
| `$resetUserVar[name;userID?]` | Reset a user variable to its initial value |
|
|
767
|
+
| `$incUserVar[name;amount;userID?]` | Increment a numeric user var (negative = decrease). Safe from race conditions. Prints nothing |
|
|
768
|
+
| `$setServerVar[name;value;serverID?]` | Save a server variable (must be declared via bot.variables) |
|
|
769
|
+
| `$getServerVar[name;serverID?]` | Read a server variable |
|
|
770
|
+
| `$resetServerVar[name;serverID?]` | Reset a server variable to its initial value |
|
|
771
|
+
| `$incServerVar[name;amount;serverID?]` | Increment a numeric server var (negative = decrease). Safe from race conditions. Prints nothing |
|
|
772
|
+
| `$setChannelVar[name;value;channelID?]` | Save a channel variable (must be declared via bot.variables) |
|
|
773
|
+
| `$getChannelVar[name;channelID?]` | Read a channel variable |
|
|
774
|
+
| `$resetChannelVar[name;channelID?]` | Reset a channel variable to its initial value |
|
|
775
|
+
| `$incChannelVar[name;amount;channelID?]` | Increment a numeric channel var (negative = decrease). Safe from race conditions. Prints nothing |
|
|
776
|
+
| `$setGlobalVar[name;value]` | Save a global variable |
|
|
777
|
+
| `$getGlobalVar[name]` | Read a global variable |
|
|
778
|
+
| `$resetGlobalVar[name]` | Reset a global variable to its initial value |
|
|
779
|
+
| `$incGlobalVar[name;amount]` | Increment a numeric global var (negative = decrease) |
|
|
780
|
+
|
|
781
|
+
### Embeds
|
|
782
|
+
|
|
783
|
+
| Function | Description |
|
|
670
784
|
|---|---|
|
|
671
|
-
| `$newEmbed` |
|
|
672
|
-
| `$title[
|
|
673
|
-
| `$embedURL[url]` |
|
|
674
|
-
| `$description[
|
|
675
|
-
| `$color[#hex|
|
|
676
|
-
| `$footer[
|
|
677
|
-
| `$author[
|
|
678
|
-
| `$thumbnail[url]` |
|
|
679
|
-
| `$image[url]` |
|
|
680
|
-
| `$addField[
|
|
681
|
-
| `$addTimestamp[ms?]` |
|
|
682
|
-
|
|
683
|
-
###
|
|
684
|
-
|
|
685
|
-
|
|
|
785
|
+
| `$newEmbed` | Start a new embed block (the first one is created automatically). Max 10 |
|
|
786
|
+
| `$title[text]` | Embed title (max 256) |
|
|
787
|
+
| `$embedURL[url]` | URL link on the embed title |
|
|
788
|
+
| `$description[text]` | Embed description body (max 4096) |
|
|
789
|
+
| `$color[#hex|name|random]` | Embed color |
|
|
790
|
+
| `$footer[text;iconURL?]` | Embed footer text (max 2048) |
|
|
791
|
+
| `$author[name;iconURL?;url?]` | Embed author name (max 256) |
|
|
792
|
+
| `$thumbnail[url]` | Embed small thumbnail image URL |
|
|
793
|
+
| `$image[url]` | Embed large main image URL |
|
|
794
|
+
| `$addField[name;value;inline?]` | Add a field (max 25; inline = true/false) |
|
|
795
|
+
| `$addTimestamp[ms?]` | Add a timestamp to the embed (default: current time) |
|
|
796
|
+
|
|
797
|
+
### Buttons & Select Menus
|
|
798
|
+
|
|
799
|
+
| Function | Description |
|
|
686
800
|
|---|---|
|
|
687
|
-
| `$addUserSelect[customID;placeholder?;min?;max?]` |
|
|
688
|
-
| `$addRoleSelect[customID;placeholder?;min?;max?]` |
|
|
689
|
-
| `$addMentionableSelect[customID;placeholder?;min?;max?]` |
|
|
690
|
-
| `$addChannelSelect[customID;placeholder?;min?;max?;
|
|
691
|
-
| `$newRow` |
|
|
692
|
-
| `$addButton[label;
|
|
693
|
-
| `$addSelectMenu[customID;placeholder?;min?;max?]` |
|
|
694
|
-
| `$addSelectOption[label;
|
|
695
|
-
|
|
696
|
-
###
|
|
697
|
-
|
|
698
|
-
|
|
|
801
|
+
| `$addUserSelect[customID;placeholder?;min?;max?]` | User select menu (retrieve selected items via $interactionValues) |
|
|
802
|
+
| `$addRoleSelect[customID;placeholder?;min?;max?]` | Role select menu (retrieve selected items via $interactionValues) |
|
|
803
|
+
| `$addMentionableSelect[customID;placeholder?;min?;max?]` | Mentionable select menu (retrieve selected items via $interactionValues) |
|
|
804
|
+
| `$addChannelSelect[customID;placeholder?;min?;max?;types?]` | Channel select menu (retrieve via $interactionValues). Types: text voice category announcement stage forum, comma-separated |
|
|
805
|
+
| `$newRow` | Start a new action row for buttons (automatic every 5 buttons) |
|
|
806
|
+
| `$addButton[label;style;customID/URL;disabled?;emoji?]` | Add a button. Styles: primary secondary success danger link |
|
|
807
|
+
| `$addSelectMenu[customID;placeholder?;min?;max?]` | Create a base string select menu (follow up with $addSelectOption) |
|
|
808
|
+
| `$addSelectOption[label;value;description?;emoji?;default?]` | Add a choice to the last select menu (max 25) |
|
|
809
|
+
|
|
810
|
+
### Actions & Moderation
|
|
811
|
+
|
|
812
|
+
| Function | Description |
|
|
699
813
|
|---|---|
|
|
700
|
-
| `$sendMessage[channelID;
|
|
701
|
-
| `$sendDM[userID;
|
|
702
|
-
| `$react[emoji1;emoji2;...]` |
|
|
703
|
-
| `$ban[userID;
|
|
704
|
-
| `$kick[userID;
|
|
705
|
-
| `$timeout[userID;
|
|
706
|
-
| `$untimeout[userID;
|
|
707
|
-
| `$addRole[userID;roleID;
|
|
708
|
-
| `$removeRole[userID;roleID;
|
|
709
|
-
| `$setNickname[userID;nickname]` |
|
|
710
|
-
| `$clear[
|
|
711
|
-
| `$slowmode[
|
|
712
|
-
|
|
713
|
-
###
|
|
714
|
-
|
|
715
|
-
|
|
|
814
|
+
| `$sendMessage[channelID;text]` | Send a message to another channel |
|
|
815
|
+
| `$sendDM[userID;text]` | Send a DM to a user |
|
|
816
|
+
| `$react[emoji1;emoji2;...]` | Add reactions to the command message |
|
|
817
|
+
| `$ban[userID;reason?;deleteMessageDays?]` | Ban a user (delete messages 0-7 days) |
|
|
818
|
+
| `$kick[userID;reason?]` | Kick a member |
|
|
819
|
+
| `$timeout[userID;duration;reason?]` | Timeout a member (max 28 days) |
|
|
820
|
+
| `$untimeout[userID;reason?]` | Remove timeout from a member |
|
|
821
|
+
| `$addRole[userID;roleID;reason?]` | Give a role to a member |
|
|
822
|
+
| `$removeRole[userID;roleID;reason?]` | Remove a role from a member |
|
|
823
|
+
| `$setNickname[userID;nickname]` | Change nickname (leave empty to reset) |
|
|
824
|
+
| `$clear[amount]` | Purge last 1-100 messages (max 14 days old). Returns count of deleted messages |
|
|
825
|
+
| `$slowmode[seconds]` | Set channel slowmode rate (0 = disabled, max 21600) |
|
|
826
|
+
|
|
827
|
+
### Messages, Attachments, Polls, Threads & Webhooks
|
|
828
|
+
|
|
829
|
+
| Function | Description |
|
|
716
830
|
|---|---|
|
|
717
|
-
| `$editMessage[messageID;
|
|
718
|
-
| `$deleteMessage[messageID;channelID?]` |
|
|
719
|
-
| `$pinMessage[messageID;channelID?]` |
|
|
720
|
-
| `$unpinMessage[messageID;channelID?]` |
|
|
721
|
-
| `$addReaction[messageID;emoji;channelID?]` |
|
|
722
|
-
| `$messageContentOf[messageID;channelID?]` |
|
|
723
|
-
| `$messageAuthorOf[messageID;channelID?]` | ID
|
|
724
|
-
| `$addAttachment[url;
|
|
725
|
-
| `$addTextFile[
|
|
726
|
-
| `$poll[
|
|
727
|
-
| `$sendWebhook[webhookURL;
|
|
728
|
-
| `$createThread[
|
|
729
|
-
| `$archiveThread[threadID?;
|
|
730
|
-
| `$addThreadMember[userID;threadID?]` |
|
|
731
|
-
| `$removeThreadMember[userID;threadID?]` |
|
|
732
|
-
| `$createForumPost[forumID;
|
|
733
|
-
|
|
734
|
-
###
|
|
735
|
-
|
|
736
|
-
|
|
|
831
|
+
| `$editMessage[messageID;text;channelID?]` | Edit a message belonging to the bot itself |
|
|
832
|
+
| `$deleteMessage[messageID;channelID?]` | Delete a single message |
|
|
833
|
+
| `$pinMessage[messageID;channelID?]` | Pin a message |
|
|
834
|
+
| `$unpinMessage[messageID;channelID?]` | Unpin a message |
|
|
835
|
+
| `$addReaction[messageID;emoji;channelID?]` | Add reaction to a specific message |
|
|
836
|
+
| `$messageContentOf[messageID;channelID?]` | Fetch text content of a specific message |
|
|
837
|
+
| `$messageAuthorOf[messageID;channelID?]` | Fetch author ID of a specific message |
|
|
838
|
+
| `$addAttachment[url;name?]` | Attach a file from a http(s) URL to the response (max 10) |
|
|
839
|
+
| `$addTextFile[fileName;content]` | Attach a custom text file generated on the fly (max 1 MB) |
|
|
840
|
+
| `$poll[question;hours;multi;option1;option2;...]` | Create a poll (hours 1-768, multi = true/false, 2-10 options) |
|
|
841
|
+
| `$sendWebhook[webhookURL;text;username?;avatarURL?]` | Send a message via a Discord Webhook URL |
|
|
842
|
+
| `$createThread[name;messageID?;autoArchiveMinutes?]` | Create a thread (from a message if messageID is provided). Archive: 60/1440/4320/10080. Returns thread ID |
|
|
843
|
+
| `$archiveThread[threadID?;lock?]` | Archive a thread (lock = true to also lock it) |
|
|
844
|
+
| `$addThreadMember[userID;threadID?]` | Add a user to a thread |
|
|
845
|
+
| `$removeThreadMember[userID;threadID?]` | Remove a user from a thread |
|
|
846
|
+
| `$createForumPost[forumID;title;content]` | Create a post inside a forum channel. Returns thread ID |
|
|
847
|
+
|
|
848
|
+
### Server Management (Bans, Channels, Roles, Invites, Emojis, Events, Voice)
|
|
849
|
+
|
|
850
|
+
| Function | Description |
|
|
737
851
|
|---|---|
|
|
738
|
-
| `$unban[userID;
|
|
739
|
-
| `$isBanned[userID]` | true/false: user
|
|
740
|
-
| `$banCount` |
|
|
741
|
-
| `$createChannel[
|
|
742
|
-
| `$deleteChannel[channelID;
|
|
743
|
-
| `$setChannelName[channelID;
|
|
744
|
-
| `$setChannelTopic[channelID;
|
|
745
|
-
| `$lockChannel[channelID?;
|
|
746
|
-
| `$unlockChannel[channelID?;
|
|
747
|
-
| `$createInvite[channelID?;
|
|
748
|
-
| `$channelType[channelID?]` |
|
|
749
|
-
| `$createRole[
|
|
750
|
-
| `$deleteRole[roleID;
|
|
751
|
-
| `$setRoleName[roleID;
|
|
752
|
-
| `$setRoleColor[roleID;
|
|
753
|
-
| `$memberRoles[userID?]` |
|
|
754
|
-
| `$createEmoji[
|
|
755
|
-
| `$deleteEmoji[emojiID]` |
|
|
756
|
-
| `$createEvent[
|
|
757
|
-
| `$moveMember[userID;voiceChannelID]` |
|
|
758
|
-
| `$disconnectMember[userID]` |
|
|
759
|
-
| `$leaveServer[serverID?]` |
|
|
760
|
-
|
|
761
|
-
###
|
|
762
|
-
|
|
763
|
-
|
|
|
852
|
+
| `$unban[userID;reason?]` | Revoke a user's ban |
|
|
853
|
+
| `$isBanned[userID]` | true/false: whether the user is currently banned in this server |
|
|
854
|
+
| `$banCount` | Number of banned users (reads max top 1000) |
|
|
855
|
+
| `$createChannel[name;type?;parentID?;topic?]` | Create a channel. Types: text voice category announcement stage forum. Returns ID |
|
|
856
|
+
| `$deleteChannel[channelID;reason?]` | Delete a channel/thread (deleting the active channel makes sending the reply fail) |
|
|
857
|
+
| `$setChannelName[channelID;name;reason?]` | Change channel name |
|
|
858
|
+
| `$setChannelTopic[channelID;topic;reason?]` | Change channel topic |
|
|
859
|
+
| `$lockChannel[channelID?;reason?]` | Lock a channel: @everyone will be unable to send messages |
|
|
860
|
+
| `$unlockChannel[channelID?;reason?]` | Unlock a channel (reverts to default configurations) |
|
|
861
|
+
| `$createInvite[channelID?;maxAgeSeconds?;maxUses?]` | Create an invite link. Age 0-604800 (0 = infinite), maxUses 0-100. Returns URL |
|
|
862
|
+
| `$channelType[channelID?]` | Channel type string: text voice category announcement stage forum etc. |
|
|
863
|
+
| `$createRole[name;color?;hoist?;mentionable?;reason?]` | Create a role. Returns ID |
|
|
864
|
+
| `$deleteRole[roleID;reason?]` | Delete a role |
|
|
865
|
+
| `$setRoleName[roleID;name;reason?]` | Change role name |
|
|
866
|
+
| `$setRoleColor[roleID;color;reason?]` | Change role color (#hex / name / random) |
|
|
867
|
+
| `$memberRoles[userID?]` | Comma-separated list of member role IDs |
|
|
868
|
+
| `$createEmoji[name;url]` | Create a guild emoji from an image URL. Returns the ready-to-use emoji string |
|
|
869
|
+
| `$deleteEmoji[emojiID]` | Delete a server emoji |
|
|
870
|
+
| `$createEvent[name;startMs;endMs;location;description?]` | Create a scheduled guild event (external location type). Time in ms. Returns ID |
|
|
871
|
+
| `$moveMember[userID;voiceChannelID]` | Move a member to another voice channel |
|
|
872
|
+
| `$disconnectMember[userID]` | Disconnect a member from a voice channel |
|
|
873
|
+
| `$leaveServer[serverID?]` | Force the bot to leave a server. Bot owners only |
|
|
874
|
+
|
|
875
|
+
### Modals, Autocomplete & Target Scope
|
|
876
|
+
|
|
877
|
+
| Function | Description |
|
|
764
878
|
|---|---|
|
|
765
|
-
| `$addModal[customID;
|
|
766
|
-
| `$addTextInput[customID;label;
|
|
767
|
-
| `$modalValue[
|
|
768
|
-
| `$focusedValue` | Autocomplete:
|
|
769
|
-
| `$focusedOption` | Autocomplete:
|
|
770
|
-
| `$addChoice[
|
|
771
|
-
| `$targetID` | ID
|
|
772
|
-
| `$targetName` |
|
|
773
|
-
| `$targetContent` |
|
|
774
|
-
| `$messageFrom[
|
|
775
|
-
|
|
776
|
-
### Eval (
|
|
777
|
-
|
|
778
|
-
|
|
|
879
|
+
| `$addModal[customID;title]` | Show a pop-up form (modal). Must be the first response; other texts are ignored. Build inputs using $addTextInput |
|
|
880
|
+
| `$addTextInput[customID;label;style?;placeholder?;required?;min?;max?;initialValue?]` | Add an input field to a modal (max 5). Styles: short / paragraph |
|
|
881
|
+
| `$modalValue[columnCustomID]` | Retrieve submitted modal input text values (used inside bot.modal handlers) |
|
|
882
|
+
| `$focusedValue` | Autocomplete: text currently typed by the user |
|
|
883
|
+
| `$focusedOption` | Autocomplete: name of the option currently being focused |
|
|
884
|
+
| `$addChoice[name;value?]` | Autocomplete: add a dynamic choice (max 25). Default value = name |
|
|
885
|
+
| `$targetID` | Target ID: right-clicked user/message, or the target entity of an event (channel/role/thread/voice/ban) |
|
|
886
|
+
| `$targetName` | Target name (username / channel name / role name) |
|
|
887
|
+
| `$targetContent` | Target message content (right-click message context menu) |
|
|
888
|
+
| `$messageFrom[number]` | The entire message string starting from the N-th word (spaces and newlines are preserved) |
|
|
889
|
+
|
|
890
|
+
### Eval (Owner Only)
|
|
891
|
+
|
|
892
|
+
| Function | Description |
|
|
779
893
|
|---|---|
|
|
780
|
-
| `$eval[
|
|
781
|
-
| `$jsEval[
|
|
894
|
+
| `$eval[code]` | Dynamically execute wrapper-version ($function) syntax string during runtime. Requires eval: true and owner status |
|
|
895
|
+
| `$jsEval[javascriptCode]` | Dynamically execute native discord.js/JavaScript code. Variables: ctx client bot guild channel message user member interaction discord db require. Requires eval: true and owner status |
|
|
782
896
|
|
|
783
|
-
<!-- FUNCTIONS:
|
|
897
|
+
<!-- FUNCTIONS:START -->
|
|
784
898
|
|
|
785
899
|
---
|
|
786
900
|
|
|
787
|
-
##
|
|
901
|
+
## What is Not Supported Yet
|
|
788
902
|
|
|
789
|
-
|
|
903
|
+
This package does not cover 100% of discord.js capabilities. The following features are currently missing: database adapters other than JSON and MongoDB (SQLite, Redis, etc., though you can build your own adapter, see section 12), **voice/music support** (audio streaming), **sharding**, **AutoMod rules**, **stickers**, granular channel permission overrides, and Components V2. For these features, use `bot.client` (native discord.js client) or inject custom functionalities via `bot.addFunction`.
|
|
790
904
|
|
|
791
|
-
##
|
|
905
|
+
## Version History
|
|
792
906
|
|
|
793
|
-
- **1.
|
|
794
|
-
- **1.
|
|
907
|
+
- **1.2.0**: Plugin system architecture (`bot.use`, `bot.setDatabase`), official **MongoDB** plugin support (`easydc-js/mongodb`), `copyDatabase` migration toolkit for JSON files, `$incUserVar` and relative wrapper extensions (atomic number adjustment). `bot.getVar/setVar/resetVar` are now asynchronous.
|
|
908
|
+
- **1.1.0**: Added `$unban` and full guild management suites (channels, roles, invites, emojis, events, voice actions), edit/delete/pin message commands, file attachment mechanisms, poll generation, webhook triggers, threads & forums integration, modal setups, autocomplete parameters, context menus, user/role/channel dedicated selector components, 9 brand new lifecycle events, and `$eval` / `$jsEval` / `bot.evalCommand`. Default intents expanded to include `GuildModeration` and `GuildVoiceStates`.
|
|
909
|
+
- **1.0.0**: Initial release.
|
|
795
910
|
|
|
796
|
-
##
|
|
911
|
+
## License
|
|
797
912
|
|
|
798
913
|
MIT
|