@tryty/easydc-js 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +912 -2
- package/examples/advanced/lanjutan.js +60 -0
- package/examples/basic.js +100 -0
- package/examples/commands/ping.js +6 -0
- package/examples/commands/profil.js +28 -0
- package/examples/mongo.js +44 -0
- package/index.d.ts +150 -0
- package/mongodb.d.ts +31 -0
- package/package.json +53 -4
- package/src/bot.js +868 -0
- package/src/context.js +218 -0
- package/src/database.js +96 -0
- package/src/errors.js +38 -0
- package/src/functions/actions.js +103 -0
- package/src/functions/components.js +108 -0
- package/src/functions/control.js +142 -0
- package/src/functions/embed.js +71 -0
- package/src/functions/eval.js +73 -0
- package/src/functions/helpers.js +86 -0
- package/src/functions/index.js +29 -0
- package/src/functions/info.js +117 -0
- package/src/functions/interact.js +63 -0
- package/src/functions/manage.js +171 -0
- package/src/functions/messages.js +128 -0
- package/src/functions/text.js +118 -0
- package/src/functions/vars.js +41 -0
- package/src/index.js +20 -0
- package/src/interpreter.js +88 -0
- package/src/parser.js +168 -0
- package/src/plugins/mongodb.js +140 -0
- package/src/util.js +188 -0
package/README.md
CHANGED
|
@@ -1,3 +1,913 @@
|
|
|
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
|
+
|
|
5
|
+
```js
|
|
6
|
+
const { Bot } = require('easydc-js');
|
|
7
|
+
|
|
8
|
+
const bot = new Bot({ token: process.env.TOKEN, prefix: '!' });
|
|
9
|
+
|
|
10
|
+
bot.command({ name: 'ping', code: '🏓 Pong! $ping ms' });
|
|
11
|
+
|
|
12
|
+
bot.connect();
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Type `!ping` in Discord → the bot replies `🏓 Pong! 42 ms`.
|
|
16
|
+
|
|
17
|
+
> **Note:** This is an independent package, not an official part of discord.js. This package uses discord.js under the hood.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
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)
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 1. Installation
|
|
44
|
+
|
|
45
|
+
Requires **Node.js 18.17 or newer**.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm install easydc-js discord.js
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 2. Creating a Bot on Discord
|
|
52
|
+
|
|
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.
|
|
59
|
+
|
|
60
|
+
Store the token in environment variables, do not write it directly in your code:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Linux / macOS
|
|
64
|
+
TOKEN="your_token" node index.js
|
|
65
|
+
# Windows PowerShell
|
|
66
|
+
$env:TOKEN="your_token"; node index.js
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 3. Your First Bot
|
|
70
|
+
|
|
71
|
+
Create `index.js`:
|
|
72
|
+
|
|
73
|
+
```js
|
|
74
|
+
const { Bot } = require('easydc-js');
|
|
75
|
+
|
|
76
|
+
const bot = new Bot({
|
|
77
|
+
token: process.env.TOKEN,
|
|
78
|
+
prefix: '!',
|
|
79
|
+
timezone: 'Asia/Jakarta',
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
bot.variables({ money: 100 });
|
|
83
|
+
|
|
84
|
+
bot.command({
|
|
85
|
+
name: 'money',
|
|
86
|
+
code: '💰 $username has $getUserVar[money] coins',
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
bot.command({
|
|
90
|
+
name: 'work',
|
|
91
|
+
code: `
|
|
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]
|
|
95
|
+
`,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
bot.connect();
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
A complete example can be found in [`examples/basic.js`](examples/basic.js).
|
|
102
|
+
|
|
103
|
+
## 4. How the `$function` Syntax Works
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
$functionName[argument1;argument2;...]
|
|
107
|
+
```
|
|
108
|
+
|
|
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.
|
|
115
|
+
|
|
116
|
+
### Writing Special Characters
|
|
117
|
+
|
|
118
|
+
To write `$ [ ] ;` characters as literal text, escape them with a backslash:
|
|
119
|
+
|
|
120
|
+
| Write | Result |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `\$ping` | `$ping` (will not be executed) |
|
|
123
|
+
| `\[` `\]` | `[` `]` |
|
|
124
|
+
| `\;` | `;` (will not separate arguments) |
|
|
125
|
+
| `\` | `\` |
|
|
126
|
+
|
|
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.
|
|
129
|
+
|
|
130
|
+
> Inside JavaScript template strings (backticks `` ` ``), backslashes need to be **doubled**: `` `\$ping` ``. If you want to avoid this, use `$dollar`.
|
|
131
|
+
|
|
132
|
+
### Code Validation Before Bot Starts
|
|
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:
|
|
135
|
+
|
|
136
|
+
```
|
|
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)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## 5. Handler Types
|
|
143
|
+
|
|
144
|
+
### Prefix Commands
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
bot.command({ name: 'greet', aliases: ['hi', 'hello'], code: 'Hello $username!' });
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Arguments after the command name: `$message` (all), `$message[1]` (1st word), `$argsCount`.
|
|
151
|
+
|
|
152
|
+
### Slash Commands
|
|
153
|
+
|
|
154
|
+
```js
|
|
155
|
+
bot.slashCommand({
|
|
156
|
+
name: 'hello', // lowercase, no spaces
|
|
157
|
+
description: 'Greets someone',
|
|
158
|
+
options: [
|
|
159
|
+
{ name: 'name', description: 'Name', type: 'string', required: true },
|
|
160
|
+
{ name: 'age', description: 'Age', type: 'integer', minValue: 1 },
|
|
161
|
+
],
|
|
162
|
+
code: 'Hello, $option[name]!',
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
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.
|
|
169
|
+
|
|
170
|
+
### Buttons & Select Menus
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
bot.command({
|
|
174
|
+
name: 'button',
|
|
175
|
+
code: '$addButton[Click;primary;click_1]$addButton[Web;link;https://example.com]Choose:',
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
bot.button({ customId: 'click_*', code: '$ephemeral You pressed `$customID`' }); // * = wildcard
|
|
179
|
+
|
|
180
|
+
bot.command({
|
|
181
|
+
name: 'menu',
|
|
182
|
+
code: `Choose a fruit:
|
|
183
|
+
$addSelectMenu[fruit;Choose...]
|
|
184
|
+
$addSelectOption[Apple;apple;Red fruit]
|
|
185
|
+
$addSelectOption[Orange;orange]`,
|
|
186
|
+
});
|
|
187
|
+
bot.select({ customId: 'fruit', code: 'You chose: $interactionValues' });
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Use `$update` so that buttons/selects edit the original message instead of sending a new one.
|
|
191
|
+
|
|
192
|
+
### Events
|
|
193
|
+
|
|
194
|
+
| Short form | Executed when |
|
|
195
|
+
|---|---|
|
|
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:
|
|
211
|
+
|
|
212
|
+
```js
|
|
213
|
+
bot.onMemberJoin({ channel: 'CHANNEL_ID', code: 'Welcome $mention! We are now $memberCount people.' });
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## 6. Bot Options
|
|
217
|
+
|
|
218
|
+
```js
|
|
219
|
+
new Bot({
|
|
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
|
|
226
|
+
intents: 'default', // 'default' | 'all' | ['Guilds', ...]
|
|
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
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Default intents: `Guilds, GuildMessages, MessageContent, GuildMembers, GuildMessageReactions, DirectMessages, GuildModeration, GuildVoiceStates`.
|
|
238
|
+
|
|
239
|
+
Additional option: `eval: false` (turns on `$eval` / `$jsEval`, see [section 11](#11-eval-owner-only)).
|
|
240
|
+
|
|
241
|
+
## 7. Variables & Database
|
|
242
|
+
|
|
243
|
+
Variables are permanently stored in a JSON file (`easydc-data.json`). Declare them first with default values:
|
|
244
|
+
|
|
245
|
+
```js
|
|
246
|
+
bot.variables({ money: 0, bio: 'Not filled yet' });
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
| Function | Scope |
|
|
250
|
+
|---|---|
|
|
251
|
+
| `$getUserVar[name;userID?]` `$setUserVar[name;value;userID?]` `$resetUserVar` | per user |
|
|
252
|
+
| `$getServerVar` `$setServerVar` `$resetServerVar` | per server |
|
|
253
|
+
| `$getChannelVar` `$setChannelVar` `$resetChannelVar` | per channel |
|
|
254
|
+
| `$getGlobalVar` `$setGlobalVar` `$resetGlobalVar` | one for everyone |
|
|
255
|
+
|
|
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]`.
|
|
258
|
+
|
|
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.**
|
|
263
|
+
|
|
264
|
+
## 8. The `$if` Condition
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
$if[condition]
|
|
268
|
+
...
|
|
269
|
+
$elseif[condition]
|
|
270
|
+
...
|
|
271
|
+
$else
|
|
272
|
+
...
|
|
273
|
+
$endif
|
|
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.
|
|
278
|
+
|
|
279
|
+
```
|
|
280
|
+
$if[$getUserVar[money]>=100&&$isAdmin==true]
|
|
281
|
+
Rich and admin
|
|
282
|
+
$elseif[$getUserVar[money]>=100]
|
|
283
|
+
Rich
|
|
284
|
+
$else
|
|
285
|
+
Poor
|
|
286
|
+
$endif
|
|
287
|
+
```
|
|
288
|
+
|
|
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.
|
|
290
|
+
|
|
291
|
+
Other constraints: `$onlyIf[condition;message?]`, `$stop[message?]`, `$onlyPerms`, `$onlyAdmin`, `$onlyOwner`, `$onlyForIDs`, `$onlyInServer`, `$argsCheck`, `$cooldown`.
|
|
292
|
+
|
|
293
|
+
## 9. Embeds, Buttons, Select Menus
|
|
294
|
+
|
|
295
|
+
```js
|
|
296
|
+
bot.command({
|
|
297
|
+
name: 'info',
|
|
298
|
+
code: `
|
|
299
|
+
$title[Info $serverName]
|
|
300
|
+
$description[This server has $memberCount members.]
|
|
301
|
+
$color[#5865F2]
|
|
302
|
+
$thumbnail[$serverIcon]
|
|
303
|
+
$addField[Created;$discordTime[$serverCreatedAt;D];true]
|
|
304
|
+
$addField[Ping;$ping ms;true]
|
|
305
|
+
$footer[Requested by $username]
|
|
306
|
+
$addTimestamp
|
|
307
|
+
`,
|
|
308
|
+
});
|
|
309
|
+
```
|
|
310
|
+
|
|
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.
|
|
315
|
+
|
|
316
|
+
## 10. Advanced Features
|
|
317
|
+
|
|
318
|
+
### Modals (Pop-up Forms)
|
|
319
|
+
|
|
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).
|
|
321
|
+
|
|
322
|
+
```js
|
|
323
|
+
bot.slashCommand({
|
|
324
|
+
name: 'report',
|
|
325
|
+
description: 'Send a report',
|
|
326
|
+
code: `
|
|
327
|
+
$addModal[report_form;Report Form]
|
|
328
|
+
$addTextInput[title;Title;short;Keep it brief;true;3;50]
|
|
329
|
+
$addTextInput[content;Report content;paragraph]
|
|
330
|
+
`,
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
bot.modal({
|
|
334
|
+
customId: 'report_form', // card wildcards allowed: 'report_*'
|
|
335
|
+
code: '$ephemeral Thank you! Title: $modalValue[title] | Content: $modalValue[content]',
|
|
336
|
+
});
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
Maximum 5 inputs per modal. `$addTextInput[customID;label;style?;placeholder?;required?;min?;max?;initialValue?]`, styles are `short` or `paragraph`.
|
|
340
|
+
|
|
341
|
+
### Autocomplete (Dynamic Choices in Slash Commands)
|
|
342
|
+
|
|
343
|
+
```js
|
|
344
|
+
bot.slashCommand({
|
|
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]',
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
bot.autocomplete({
|
|
352
|
+
command: 'fruit',
|
|
353
|
+
option: 'name', // leave empty for all autocomplete options in that command
|
|
354
|
+
code: `
|
|
355
|
+
$if[$checkContains[apple;$toLowerCase[$focusedValue]]==true]$addChoice[Apple;apple]$endif
|
|
356
|
+
$addChoice[Orange;orange]
|
|
357
|
+
$addChoice[Mango;mangga]
|
|
358
|
+
`,
|
|
359
|
+
});
|
|
360
|
+
```
|
|
361
|
+
|
|
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`.
|
|
363
|
+
|
|
364
|
+
### Right-Click Menus (Context Menus)
|
|
365
|
+
|
|
366
|
+
```js
|
|
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.' });
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Appears under the *Apps* menu when a user right-clicks a user or a message. Automatically registered alongside slash commands.
|
|
372
|
+
|
|
373
|
+
### User / Role / Channel Select Menus
|
|
374
|
+
|
|
375
|
+
```
|
|
376
|
+
$addUserSelect[select_user;Select user;1;3]
|
|
377
|
+
$addRoleSelect[select_role]
|
|
378
|
+
$addMentionableSelect[select_anything]
|
|
379
|
+
$addChannelSelect[select_channel;Select channel;;;text,voice]
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Register handlers via `bot.select({ customId: 'select_user', code: 'Selected: $interactionValues' })`. Values are comma-separated IDs.
|
|
383
|
+
|
|
384
|
+
### Attachments, Polls, Webhooks
|
|
385
|
+
|
|
386
|
+
```
|
|
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]
|
|
391
|
+
```
|
|
392
|
+
|
|
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.
|
|
394
|
+
|
|
395
|
+
### Threads, Forums, and Guild Management
|
|
396
|
+
|
|
397
|
+
```
|
|
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
|
|
402
|
+
$createRole[VIP;#ff0000;true] $createInvite[;3600;10]
|
|
403
|
+
$createEvent[WatchParty;START_MS;END_MS;Voice 1;Description]
|
|
404
|
+
```
|
|
405
|
+
|
|
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.
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## 11. Eval (Owner Only)
|
|
411
|
+
|
|
412
|
+
Eval executes code inputted dynamically while the bot is running, which is useful for debugging. There are two types:
|
|
413
|
+
|
|
414
|
+
| Function | Code Language Executed |
|
|
415
|
+
|---|---|
|
|
416
|
+
| `$eval[code]` | Wrapper-version code, which uses this package's `$function` syntax |
|
|
417
|
+
| `$jsEval[code]` | JavaScript / **native discord.js** |
|
|
418
|
+
|
|
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`.
|
|
420
|
+
|
|
421
|
+
### Easiest Way to Use
|
|
422
|
+
|
|
423
|
+
```js
|
|
424
|
+
const bot = new Bot({
|
|
425
|
+
token: process.env.TOKEN,
|
|
426
|
+
owners: ['YOUR_DISCORD_ID'],
|
|
427
|
+
eval: true, // eval is DISABLED unless turned on here
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
bot.evalCommand(); // mounts the "eval" command (name can be changed: { name: 'e', aliases: ['ev'] })
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Then in Discord:
|
|
434
|
+
|
|
435
|
+
```
|
|
436
|
+
!eval $math[6*7] -> wrapper syntax version
|
|
437
|
+
!eval Hello $username from $serverName
|
|
438
|
+
!eval js client.guilds.cache.size -> native discord.js
|
|
439
|
+
!eval js guild.members.cache.filter(m => m.user.bot).size
|
|
440
|
+
!eval js const g = await client.guilds.fetch(guild.id);
|
|
441
|
+
return g.memberCount;
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Results are sent inside a code block (max ±1800 characters), errors are displayed as `❌ ...`, and **tokens are automatically censored** from the output.
|
|
445
|
+
|
|
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).
|
|
447
|
+
|
|
448
|
+
### ⚠️ Security Warnings
|
|
449
|
+
|
|
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.
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
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
|
|
565
|
+
|
|
566
|
+
```js
|
|
567
|
+
bot.addFunction({
|
|
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})`,
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
bot.command({ name: 'test', code: '$greetUser[Budi]' });
|
|
575
|
+
```
|
|
576
|
+
|
|
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.
|
|
579
|
+
|
|
580
|
+
## 14. Splitting Commands into Multiple Files
|
|
581
|
+
|
|
582
|
+
```
|
|
583
|
+
project/
|
|
584
|
+
├── index.js
|
|
585
|
+
└── commands/
|
|
586
|
+
├── general.js
|
|
587
|
+
└── moderation.js
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
```js
|
|
591
|
+
bot.loadCommands('./commands');
|
|
592
|
+
```
|
|
593
|
+
|
|
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).
|
|
595
|
+
|
|
596
|
+
```js
|
|
597
|
+
module.exports = [
|
|
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' },
|
|
602
|
+
];
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
## 15. Security
|
|
606
|
+
|
|
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).
|
|
612
|
+
|
|
613
|
+
## 16. Troubleshooting
|
|
614
|
+
|
|
615
|
+
| Issue | Cause / Solution |
|
|
616
|
+
|---|---|
|
|
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. |
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
## 17. List of All Functions
|
|
639
|
+
|
|
640
|
+
The `?` symbol means the argument is optional. This list is automatically generated from the source code (`npm run docs`).
|
|
641
|
+
|
|
642
|
+
<!-- FUNCTIONS:START -->
|
|
643
|
+
|
|
644
|
+
### Info (user, server, bot, message, time)
|
|
645
|
+
|
|
646
|
+
| Function | Description |
|
|
647
|
+
|---|---|
|
|
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 |
|
|
693
|
+
|---|---|
|
|
694
|
+
| `$math[expression]` | Safe evaluation. Supports + - * / % ^ ( ) sqrt abs round floor ceil min max pow pi e |
|
|
695
|
+
| `$sum[a;b;...]` | Sum of all numbers |
|
|
696
|
+
| `$sub[a;b]` | a - b |
|
|
697
|
+
| `$multiply[a;b;...]` | Multiply all numbers |
|
|
698
|
+
| `$divide[a;b]` | a / b |
|
|
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 |
|
|
734
|
+
|---|---|
|
|
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 |
|
|
763
|
+
|---|---|
|
|
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 |
|
|
784
|
+
|---|---|
|
|
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 |
|
|
800
|
+
|---|---|
|
|
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 |
|
|
813
|
+
|---|---|
|
|
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 |
|
|
830
|
+
|---|---|
|
|
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 |
|
|
851
|
+
|---|---|
|
|
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 |
|
|
878
|
+
|---|---|
|
|
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 |
|
|
893
|
+
|---|---|
|
|
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 |
|
|
896
|
+
|
|
897
|
+
<!-- FUNCTIONS:START -->
|
|
898
|
+
|
|
899
|
+
---
|
|
900
|
+
|
|
901
|
+
## What is Not Supported Yet
|
|
902
|
+
|
|
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`.
|
|
904
|
+
|
|
905
|
+
## Version History
|
|
906
|
+
|
|
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.
|
|
910
|
+
|
|
911
|
+
## License
|
|
912
|
+
|
|
913
|
+
MIT
|