@tryty/easydc-js 1.2.0 → 1.2.2

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 CHANGED
@@ -1,9 +1,9 @@
1
- # easydc-js
1
+ # @tryty/easydc-js
2
2
 
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.
3
+ Bot Discord **super mudah** di atas [discord.js](https://discord.js.org). Kamu cukup menulis perintah dengan sintaks `$fungsi[argumen]` seperti aoi.js, tanpa harus mengurus event, embed, tombol, atau database secara manual.
4
4
 
5
5
  ```js
6
- const { Bot } = require('easydc-js');
6
+ const { Bot } = require('@tryty/easydc-js');
7
7
 
8
8
  const bot = new Bot({ token: process.env.TOKEN, prefix: '!' });
9
9
 
@@ -12,66 +12,98 @@ bot.command({ name: 'ping', code: '🏓 Pong! $ping ms' });
12
12
  bot.connect();
13
13
  ```
14
14
 
15
- Type `!ping` in Discord → the bot replies `🏓 Pong! 42 ms`.
15
+ Ketik `!ping` di Discord → bot menjawab `🏓 Pong! 42 ms`.
16
16
 
17
- > **Note:** This is an independent package, not an official part of discord.js. This package uses discord.js under the hood.
17
+ > **Catatan:** ini package independen, bukan bagian resmi dari discord.js maupun aoi.js. Package ini memakai discord.js di belakang layar.
18
18
 
19
19
  ---
20
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)
21
+ ## Daftar isi
22
+
23
+ 1. [Instalasi](#1-instalasi)
24
+ - [Tanpa publish ke npm (file lokal)](#1b-memakai-tanpa-publish-ke-npm-file-lokal--host-panel)
25
+ 2. [Membuat bot di Discord](#2-membuat-bot-di-discord)
26
+ 3. [Bot pertama](#3-bot-pertama)
27
+ 4. [Cara kerja sintaks `$fungsi`](#4-cara-kerja-sintaks-fungsi)
28
+ 5. [Jenis handler](#5-jenis-handler)
29
+ 6. [Opsi Bot](#6-opsi-bot)
30
+ 7. [Variabel & database](#7-variabel--database)
31
+ 8. [Kondisi `$if`](#8-kondisi-if)
32
+ 9. [Embed, tombol, select menu](#9-embed-tombol-select-menu)
33
+ 10. [Fitur lanjutan: modal, autocomplete, menu klik-kanan, poll, thread, webhook](#10-fitur-lanjutan)
34
+ 11. [Eval (khusus owner)](#11-eval-khusus-owner)
35
+ 12. [Database & plugin (MongoDB)](#12-database--plugin-mongodb)
36
+ 13. [Membuat fungsi sendiri](#13-membuat-fungsi-sendiri)
37
+ 14. [Memisah command ke banyak file](#14-memisah-command-ke-banyak-file)
38
+ 15. [Keamanan](#15-keamanan)
39
+ 16. [Pemecahan masalah](#16-pemecahan-masalah)
40
+ 17. [Daftar semua fungsi](#17-daftar-semua-fungsi)
40
41
 
41
42
  ---
42
43
 
43
- ## 1. Installation
44
+ ## 1. Instalasi
44
45
 
45
- Requires **Node.js 18.17 or newer**.
46
+ Butuh **Node.js 18.17 atau lebih baru**.
46
47
 
47
48
  ```bash
48
- npm install easydc-js discord.js
49
+ npm install @tryty/easydc-js discord.js
49
50
  ```
50
51
 
51
- ## 2. Creating a Bot on Discord
52
+ ## 1b. Memakai tanpa publish ke npm (file lokal / host panel)
52
53
 
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.
54
+ Kalau package ini belum dipublish tetapi kode Anda sudah memakai `require('@tryty/easydc-js')`, pasang dari file lokal. Ada dua cara.
59
55
 
60
- Store the token in environment variables, do not write it directly in your code:
56
+ **Cara A: dependensi `file:` (disarankan, tahan restart panel)**
57
+
58
+ 1. Ekstrak zip, lalu letakkan folder package di dalam proyek bot, misalnya `bot/vendor/easydc-js/` (isinya `src`, `package.json`, dst.).
59
+ 2. Di `package.json` **proyek bot** (bukan package-nya), tambahkan:
60
+ ```json
61
+ {
62
+ "dependencies": {
63
+ "@tryty/easydc-js": "file:./vendor/easydc-js",
64
+ "discord.js": "^14.16.0",
65
+ "mongodb": "^6.0.0"
66
+ }
67
+ }
68
+ ```
69
+ 3. Jalankan `npm install`. Sekarang `require('@tryty/easydc-js')` dan `require('@tryty/easydc-js/mongodb')` berfungsi persis seperti setelah publish.
70
+
71
+ **Cara B: dari file `.tgz`**
72
+
73
+ ```bash
74
+ npm install ./tryty-easydc-js-1.3.0.tgz discord.js mongodb
75
+ ```
76
+
77
+ Jangan hanya menyalin folder ke `node_modules/@tryty/easydc-js` dengan tangan: panel yang menjalankan `npm install` saat start akan menghapus folder yang tidak tercatat di `package.json`.
78
+
79
+ Nama di `require` harus sama persis dengan nama di `dependencies`. Jika Anda tidak memakai nama ber-scope, ganti `"name"` di `package.json` package-nya dan semua `require`.
80
+
81
+ ---
82
+
83
+ ## 2. Membuat bot di Discord
84
+
85
+ 1. Buka <https://discord.com/developers/applications> → **New Application**.
86
+ 2. Menu **Bot** → **Reset Token** → salin token. **Jangan dibagikan ke siapa pun.**
87
+ 3. Di halaman yang sama, aktifkan **Privileged Gateway Intents**:
88
+ - **Message Content Intent** (wajib agar command berawalan `!` terbaca)
89
+ - **Server Members Intent** (untuk event member masuk/keluar & info member)
90
+ 4. Menu **OAuth2 → URL Generator** → centang `bot` dan `applications.commands` → pilih izin yang dibutuhkan → buka URL hasilnya untuk mengundang bot.
91
+
92
+ Simpan token di variabel lingkungan, jangan ditulis di kode:
61
93
 
62
94
  ```bash
63
95
  # Linux / macOS
64
- TOKEN="your_token" node index.js
96
+ TOKEN="token_kamu" node index.js
65
97
  # Windows PowerShell
66
- $env:TOKEN="your_token"; node index.js
98
+ $env:TOKEN="token_kamu"; node index.js
67
99
  ```
68
100
 
69
- ## 3. Your First Bot
101
+ ## 3. Bot pertama
70
102
 
71
- Create `index.js`:
103
+ Buat `index.js`:
72
104
 
73
105
  ```js
74
- const { Bot } = require('easydc-js');
106
+ const { Bot } = require('@tryty/easydc-js');
75
107
 
76
108
  const bot = new Bot({
77
109
  token: process.env.TOKEN,
@@ -79,835 +111,863 @@ const bot = new Bot({
79
111
  timezone: 'Asia/Jakarta',
80
112
  });
81
113
 
82
- bot.variables({ money: 100 });
114
+ bot.variables({ uang: 100 });
83
115
 
84
116
  bot.command({
85
- name: 'money',
86
- code: '💰 $username has $getUserVar[money] coins',
117
+ name: 'uang',
118
+ code: '💰 $username punya $getUserVar[uang] koin',
87
119
  });
88
120
 
89
121
  bot.command({
90
- name: 'work',
122
+ name: 'kerja',
91
123
  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]
124
+ $cooldown[1m;Istirahat dulu, tunggu %time%.]
125
+ $setUserVar[uang;$math[$getUserVar[uang]+25]]
126
+ Kamu dapat 25 koin! Total: $getUserVar[uang]
95
127
  `,
96
128
  });
97
129
 
98
130
  bot.connect();
99
131
  ```
100
132
 
101
- A complete example can be found in [`examples/basic.js`](examples/basic.js).
133
+ Contoh lengkap ada di [`examples/basic.js`](examples/basic.js).
102
134
 
103
- ## 4. How the `$function` Syntax Works
135
+ ## 4. Cara kerja sintaks `$fungsi`
104
136
 
105
137
  ```
106
- $functionName[argument1;argument2;...]
138
+ $namaFungsi[argumen1;argumen2;...]
107
139
  ```
108
140
 
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.
141
+ - Argumen dipisah dengan **titik koma** `;`.
142
+ - Fungsi boleh **bersarang**: `$toUpperCase[$username]`, `$math[$getUserVar[uang]*2]`.
143
+ - Nama fungsi **tidak peka huruf besar/kecil** (`$Username` = `$username`).
144
+ - Fungsi yang tidak butuh argumen ditulis tanpa kurung: `$ping`, `$serverName`.
145
+ - Hasil akhir seluruh teks (setelah semua `$fungsi` dijalankan) dikirim sebagai jawaban bot.
146
+ - Teks yang panjangnya lebih dari 2000 karakter otomatis dipecah jadi beberapa pesan.
115
147
 
116
- ### Writing Special Characters
148
+ ### Menulis karakter khusus
117
149
 
118
- To write `$ [ ] ;` characters as literal text, escape them with a backslash:
150
+ Untuk menulis karakter `$ [ ] ;` sebagai teks biasa, beri backslash di depannya:
119
151
 
120
- | Write | Result |
152
+ | Tulis | Hasil |
121
153
  |---|---|
122
- | `\$ping` | `$ping` (will not be executed) |
154
+ | `\$ping` | `$ping` (bukan dijalankan) |
123
155
  | `\[` `\]` | `[` `]` |
124
- | `\;` | `;` (will not separate arguments) |
125
- | `\` | `\` |
156
+ | `\;` | `;` (tidak memisah argumen) |
157
+ | `\\` | `\` |
126
158
 
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.
159
+ Atau pakai fungsi `$semicolon`, `$leftBracket`, `$rightBracket`, `$dollar`.
160
+ Tanda `$` yang diikuti angka atau spasi (misal `harga $5`) otomatis dianggap teks biasa.
129
161
 
130
- > Inside JavaScript template strings (backticks `` ` ``), backslashes need to be **doubled**: `` `\$ping` ``. If you want to avoid this, use `$dollar`.
162
+ > Di dalam template string JavaScript (tanda `` ` ``), backslash perlu **digandakan**: `` `\\$ping` ``. Jika tidak mau repot, pakai `$dollar`.
131
163
 
132
- ### Code Validation Before Bot Starts
164
+ ### Kode dicek sebelum bot menyala
133
165
 
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:
166
+ Saat `bot.connect()` dipanggil, **semua kode diperiksa dulu**. Kalau ada fungsi salah ketik, jumlah argumen salah, atau `$if` tanpa `$endif`, bot **tidak login** dan kamu mendapat daftar lengkap masalahnya, contoh:
135
167
 
136
168
  ```
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)
169
+ Ditemukan 2 masalah pada kode:
170
+ - command "ban": Fungsi $bann tidak dikenal (baris 3, kolom 1)
171
+ - command "cek": $if tidak ditutup, tambahkan $endif (baris 1, kolom 1)
140
172
  ```
141
173
 
142
- ## 5. Handler Types
174
+ ## 5. Jenis handler
143
175
 
144
- ### Prefix Commands
176
+ ### Command prefix
145
177
 
146
178
  ```js
147
- bot.command({ name: 'greet', aliases: ['hi', 'hello'], code: 'Hello $username!' });
179
+ bot.command({ name: 'sapa', aliases: ['hai', 'halo'], code: 'Halo $username!' });
148
180
  ```
149
181
 
150
- Arguments after the command name: `$message` (all), `$message[1]` (1st word), `$argsCount`.
182
+ Argumen setelah nama command: `$message` (semua), `$message[1]` (kata ke-1), `$argsCount`.
151
183
 
152
- ### Slash Commands
184
+ ### Slash command
153
185
 
154
186
  ```js
155
187
  bot.slashCommand({
156
- name: 'hello', // lowercase, no spaces
157
- description: 'Greets someone',
188
+ name: 'halo', // huruf kecil, tanpa spasi
189
+ description: 'Menyapa seseorang',
158
190
  options: [
159
- { name: 'name', description: 'Name', type: 'string', required: true },
160
- { name: 'age', description: 'Age', type: 'integer', minValue: 1 },
191
+ { name: 'nama', description: 'Nama', type: 'string', required: true },
192
+ { name: 'umur', description: 'Umur', type: 'integer', minValue: 1 },
161
193
  ],
162
- code: 'Hello, $option[name]!',
194
+ code: 'Halo, $option[nama]!',
163
195
  });
164
196
  ```
165
197
 
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.
198
+ Tipe opsi: `string integer boolean user channel role mentionable number attachment`.
199
+ Slash command didaftarkan otomatis saat bot siap. Untuk uji coba cepat, isi `slashGuild: 'ID_SERVER'` (muncul seketika; kalau global bisa butuh waktu).
200
+ Jika proses lebih dari 3 detik, taruh `$defer` di awal kode.
169
201
 
170
- ### Buttons & Select Menus
202
+ ### Tombol & select menu
171
203
 
172
204
  ```js
173
205
  bot.command({
174
- name: 'button',
175
- code: '$addButton[Click;primary;click_1]$addButton[Web;link;https://example.com]Choose:',
206
+ name: 'tombol',
207
+ code: '$addButton[Klik;primary;klik_1]$addButton[Web;link;https://example.com]Pilih:',
176
208
  });
177
209
 
178
- bot.button({ customId: 'click_*', code: '$ephemeral You pressed `$customID`' }); // * = wildcard
210
+ bot.button({ customId: 'klik_*', code: '$ephemeral Kamu menekan `$customID`' }); // * = wildcard
179
211
 
180
212
  bot.command({
181
213
  name: 'menu',
182
- code: `Choose a fruit:
183
- $addSelectMenu[fruit;Choose...]
184
- $addSelectOption[Apple;apple;Red fruit]
185
- $addSelectOption[Orange;orange]`,
214
+ code: `Pilih buah:
215
+ $addSelectMenu[buah;Pilih...]
216
+ $addSelectOption[Apel;apel;Buah merah]
217
+ $addSelectOption[Jeruk;jeruk]`,
186
218
  });
187
- bot.select({ customId: 'fruit', code: 'You chose: $interactionValues' });
219
+ bot.select({ customId: 'buah', code: 'Kamu memilih: $interactionValues' });
188
220
  ```
189
221
 
190
- Use `$update` so that buttons/selects edit the original message instead of sending a new one.
222
+ Gunakan `$update` agar tombol/select mengubah pesan aslinya (bukan mengirim pesan baru).
191
223
 
192
- ### Events
224
+ ### Event
193
225
 
194
- | Short form | Executed when |
226
+ | Pendek | Dijalankan saat |
195
227
  |---|---|
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:
228
+ | `bot.onReady(code)` | bot siap |
229
+ | `bot.onMemberJoin(code)` | member masuk server |
230
+ | `bot.onMemberLeave(code)` | member keluar |
231
+ | `bot.onMessageDelete(code)` | pesan dihapus |
232
+ | `bot.onMessageUpdate(code)` | pesan diedit |
233
+ | `bot.onReactionAdd(code)` / `onReactionRemove` | reaksi ditambah / dihapus |
234
+ | `bot.onGuildJoin(code)` / `onGuildLeave` | bot masuk / keluar server |
235
+ | `bot.onMessage(code)` | setiap pesan yang **bukan** command |
236
+ | `bot.onMemberBan(code)` / `onMemberUnban` | user di-ban / ban dicabut (`$targetID`, `$targetName`) |
237
+ | `bot.onChannelCreate(code)` / `onChannelDelete` | channel dibuat / dihapus (`$targetName`) |
238
+ | `bot.onRoleCreate(code)` / `onRoleDelete` | role dibuat / dihapus (`$targetName`) |
239
+ | `bot.onThreadCreate(code)` | thread baru (jawaban dikirim ke thread itu) |
240
+ | `bot.onVoiceJoin(code)` / `onVoiceLeave` | member masuk / keluar voice (`$targetName` = nama voice). Pindah channel memicu keduanya |
241
+
242
+ Secara bawaan jawaban dikirim ke channel sistem server. Pilih channel lain dengan bentuk objek:
211
243
 
212
244
  ```js
213
- bot.onMemberJoin({ channel: 'CHANNEL_ID', code: 'Welcome $mention! We are now $memberCount people.' });
245
+ bot.onMemberJoin({ channel: 'ID_CHANNEL', code: 'Selamat datang $mention! Kita sekarang $memberCount orang.' });
214
246
  ```
215
247
 
216
- ## 6. Bot Options
248
+ ## 6. Opsi Bot
217
249
 
218
250
  ```js
219
251
  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
252
+ token: 'WAJIB',
253
+ prefix: '!', // atau ['!', '?']
254
+ mentionPrefix: true, // @bot command juga bisa
255
+ ignoreBots: true, // abaikan pesan dari bot lain
256
+ owners: ['ID_KAMU'], // untuk $onlyOwner dan $isOwner
257
+ timezone: 'Asia/Jakarta', // untuk $date
226
258
  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
259
+ status: { text: 'dengan kode', type: 'Playing', status: 'online' },
260
+ slashGuild: null, // ID server untuk slash cepat (null = global)
261
+ syncSlash: true, // daftarkan slash otomatis
262
+ database: { path: './easydc-data.json' }, // atau { memory: true }
263
+ messages: { cooldown: '⏳ Tunggu %time%.', error: '❌ Terjadi kesalahan.' },
264
+ debug: false, // true = tampilkan penyebab error di chat (hanya saat pengembangan!)
265
+ onError: (err, ctx) => {}, // tangani error sendiri
234
266
  });
235
267
  ```
236
268
 
237
- Default intents: `Guilds, GuildMessages, MessageContent, GuildMembers, GuildMessageReactions, DirectMessages, GuildModeration, GuildVoiceStates`.
269
+ Intent bawaan: `Guilds, GuildMessages, MessageContent, GuildMembers, GuildMessageReactions, DirectMessages, GuildModeration, GuildVoiceStates`.
238
270
 
239
- Additional option: `eval: false` (turns on `$eval` / `$jsEval`, see [section 11](#11-eval-owner-only)).
271
+ Opsi tambahan: `eval: false` (nyalakan `$eval` / `$jsEval`, lihat [bagian 11](#11-eval-khusus-owner)).
240
272
 
241
- ## 7. Variables & Database
273
+ ## 7. Variabel & database
242
274
 
243
- Variables are permanently stored in a JSON file (`easydc-data.json`). Declare them first with default values:
275
+ Variabel disimpan permanen di file JSON (`easydc-data.json`). Deklarasikan dulu dengan nilai awal:
244
276
 
245
277
  ```js
246
- bot.variables({ money: 0, bio: 'Not filled yet' });
278
+ bot.variables({ uang: 0, bio: 'Belum diisi' });
247
279
  ```
248
280
 
249
- | Function | Scope |
281
+ | Fungsi | Cakupan |
250
282
  |---|---|
251
- | `$getUserVar[name;userID?]` `$setUserVar[name;value;userID?]` `$resetUserVar` | per user |
283
+ | `$getUserVar[nama;userID?]` `$setUserVar[nama;nilai;userID?]` `$resetUserVar` | per user |
252
284
  | `$getServerVar` `$setServerVar` `$resetServerVar` | per server |
253
285
  | `$getChannelVar` `$setChannelVar` `$resetChannelVar` | per channel |
254
- | `$getGlobalVar` `$setGlobalVar` `$resetGlobalVar` | one for everyone |
286
+ | `$getGlobalVar` `$setGlobalVar` `$resetGlobalVar` | satu untuk semua |
255
287
 
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]`.
288
+ Semua nilai tersimpan sebagai **teks**. Gunakan `$math[...]` untuk berhitung.
289
+ Variabel sementara selama satu command: `$let[nama;nilai]` dan `$get[nama]`.
258
290
 
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.**
291
+ - Untuk memakai MongoDB lihat [bagian 12](#12-database--plugin-mongodb).
292
+ - Berkas database ditulis secara aman dan otomatis. Jika file rusak, ia **dicadangkan** (`*.corrupt-<waktu>`) dan bot mulai dari kosong, bukan crash.
293
+ - Untuk bot besar (ribuan user aktif) pertimbangkan database sungguhan; `Database` bawaan cocok untuk bot kecil sampai menengah.
294
+ - **Satu file database hanya boleh dipakai satu proses bot.**
263
295
 
264
- ## 8. The `$if` Condition
296
+ ## 8. Kondisi `$if`
265
297
 
266
298
  ```
267
- $if[condition]
299
+ $if[kondisi]
268
300
  ...
269
- $elseif[condition]
301
+ $elseif[kondisi]
270
302
  ...
271
303
  $else
272
304
  ...
273
305
  $endif
274
306
  ```
275
307
 
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.
308
+ Operator: `== != > < >= <=`, digabung dengan `&&` (dan) / `||` (atau). Tanpa tanda kurung.
309
+ Jika kedua sisi angka, dibandingkan sebagai angka (`10>9` benar); selain itu sebagai teks.
278
310
 
279
311
  ```
280
- $if[$getUserVar[money]>=100&&$isAdmin==true]
281
- Rich and admin
282
- $elseif[$getUserVar[money]>=100]
283
- Rich
312
+ $if[$getUserVar[uang]>=100&&$isAdmin==true]
313
+ Kaya dan admin
314
+ $elseif[$getUserVar[uang]>=100]
315
+ Kaya
284
316
  $else
285
- Poor
317
+ Miskin
286
318
  $endif
287
319
  ```
288
320
 
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.
321
+ **Aman dari injeksi:** nilai dinamis seperti `$message` tidak bisa dipakai pengguna untuk menyisipkan operator `&&`, `||`, dan sejenisnya ke dalam kondisi. Isi pesan pengguna selalu diperlakukan sebagai teks biasa.
290
322
 
291
- Other constraints: `$onlyIf[condition;message?]`, `$stop[message?]`, `$onlyPerms`, `$onlyAdmin`, `$onlyOwner`, `$onlyForIDs`, `$onlyInServer`, `$argsCheck`, `$cooldown`.
323
+ Pembatas lain: `$onlyIf[kondisi;pesan?]`, `$stop[pesan?]`, `$onlyPerms`, `$onlyAdmin`, `$onlyOwner`, `$onlyForIDs`, `$onlyInServer`, `$argsCheck`, `$cooldown`.
292
324
 
293
- ## 9. Embeds, Buttons, Select Menus
325
+ ## 9. Embed, tombol, select menu
294
326
 
295
327
  ```js
296
328
  bot.command({
297
329
  name: 'info',
298
330
  code: `
299
331
  $title[Info $serverName]
300
- $description[This server has $memberCount members.]
332
+ $description[Server ini punya $memberCount member.]
301
333
  $color[#5865F2]
302
334
  $thumbnail[$serverIcon]
303
- $addField[Created;$discordTime[$serverCreatedAt;D];true]
335
+ $addField[Dibuat;$discordTime[$serverCreatedAt;D];true]
304
336
  $addField[Ping;$ping ms;true]
305
- $footer[Requested by $username]
337
+ $footer[Diminta oleh $username]
306
338
  $addTimestamp
307
339
  `,
308
340
  });
309
341
  ```
310
342
 
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.
343
+ - Embed pertama dibuat otomatis; `$newEmbed` memulai embed berikutnya (maksimal 10).
344
+ - Warna: `#RRGGBB`, nama (`red green blue yellow orange purple pink white black grey blurple`), atau `random`.
345
+ - Tombol: maksimal 5 per baris, 5 baris per pesan. Baris baru dibuat otomatis, atau paksa dengan `$newRow`.
346
+ - Panjang teks dicek sesuai batas Discord, dengan pesan error yang jelas jika terlampaui.
315
347
 
316
- ## 10. Advanced Features
348
+ ## 10. Fitur lanjutan
317
349
 
318
- ### Modals (Pop-up Forms)
350
+ ### Modal (form pop-up)
319
351
 
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).
352
+ Modal harus menjadi respons **pertama** dari slash command, tombol, atau select menu (jangan pakai `$defer` sebelumnya; teks lain di command itu diabaikan).
321
353
 
322
354
  ```js
323
355
  bot.slashCommand({
324
- name: 'report',
325
- description: 'Send a report',
356
+ name: 'lapor',
357
+ description: 'Kirim laporan',
326
358
  code: `
327
- $addModal[report_form;Report Form]
328
- $addTextInput[title;Title;short;Keep it brief;true;3;50]
329
- $addTextInput[content;Report content;paragraph]
359
+ $addModal[lapor_form;Form Laporan]
360
+ $addTextInput[judul;Judul;short;Ringkas saja;true;3;50]
361
+ $addTextInput[isi;Isi laporan;paragraph]
330
362
  `,
331
363
  });
332
364
 
333
365
  bot.modal({
334
- customId: 'report_form', // card wildcards allowed: 'report_*'
335
- code: '$ephemeral Thank you! Title: $modalValue[title] | Content: $modalValue[content]',
366
+ customId: 'lapor_form', // boleh wildcard: 'lapor_*'
367
+ code: '$ephemeral Terima kasih! Judul: $modalValue[judul] | Isi: $modalValue[isi]',
336
368
  });
337
369
  ```
338
370
 
339
- Maximum 5 inputs per modal. `$addTextInput[customID;label;style?;placeholder?;required?;min?;max?;initialValue?]`, styles are `short` or `paragraph`.
371
+ Maksimal 5 kolom per modal. `$addTextInput[customID;label;gaya?;placeholder?;wajib?;min?;max?;nilaiAwal?]`, gaya `short` atau `paragraph`.
340
372
 
341
- ### Autocomplete (Dynamic Choices in Slash Commands)
373
+ ### Autocomplete (pilihan dinamis di slash command)
342
374
 
343
375
  ```js
344
376
  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]',
377
+ name: 'buah',
378
+ description: 'Pilih buah',
379
+ options: [{ name: 'nama', description: 'Nama buah', autocomplete: true }], // tidak bisa bersama "choices"
380
+ code: 'Kamu memilih $option[nama]',
349
381
  });
350
382
 
351
383
  bot.autocomplete({
352
- command: 'fruit',
353
- option: 'name', // leave empty for all autocomplete options in that command
384
+ command: 'buah',
385
+ option: 'nama', // kosongkan untuk semua opsi autocomplete di command itu
354
386
  code: `
355
- $if[$checkContains[apple;$toLowerCase[$focusedValue]]==true]$addChoice[Apple;apple]$endif
356
- $addChoice[Orange;orange]
357
- $addChoice[Mango;mangga]
387
+ $if[$checkContains[apel;$toLowerCase[$focusedValue]]==true]$addChoice[Apel;apel]$endif
388
+ $addChoice[Jeruk;jeruk]
389
+ $addChoice[Mangga;mangga]
358
390
  `,
359
391
  });
360
392
  ```
361
393
 
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`.
394
+ `$focusedValue` = teks yang sedang diketik. `$addChoice[nama;nilai?]` maksimal 25. Untuk opsi `integer`/`number`, nilai pilihan harus angka. Discord memberi waktu 3 detik, jadi jangan pakai `$wait`.
363
395
 
364
- ### Right-Click Menus (Context Menus)
396
+ ### Menu klik-kanan (context menu)
365
397
 
366
398
  ```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.' });
399
+ bot.contextMenu({ name: 'Lihat Profil', menu: 'user', code: '$ephemeral Profil: $targetName (ID $targetID)' });
400
+ bot.contextMenu({ name: 'Laporkan', menu: 'message', code: '$ephemeral Pesan "$targetContent" dari $targetName dilaporkan.' });
369
401
  ```
370
402
 
371
- Appears under the *Apps* menu when a user right-clicks a user or a message. Automatically registered alongside slash commands.
403
+ Muncul di menu *Apps* ketika pengguna klik kanan user atau pesan. Didaftarkan otomatis bersama slash command.
372
404
 
373
- ### User / Role / Channel Select Menus
405
+ ### Select menu user / role / channel
374
406
 
375
407
  ```
376
- $addUserSelect[select_user;Select user;1;3]
377
- $addRoleSelect[select_role]
378
- $addMentionableSelect[select_anything]
379
- $addChannelSelect[select_channel;Select channel;;;text,voice]
408
+ $addUserSelect[pilih_user;Pilih user;1;3]
409
+ $addRoleSelect[pilih_role]
410
+ $addMentionableSelect[pilih_apa_saja]
411
+ $addChannelSelect[pilih_channel;Pilih channel;;;text,voice]
380
412
  ```
381
413
 
382
- Register handlers via `bot.select({ customId: 'select_user', code: 'Selected: $interactionValues' })`. Values are comma-separated IDs.
414
+ Daftarkan handler dengan `bot.select({ customId: 'pilih_user', code: 'Dipilih: $interactionValues' })`. Nilainya berupa ID, dipisah koma.
383
415
 
384
- ### Attachments, Polls, Webhooks
416
+ ### Lampiran, polling, webhook
385
417
 
386
418
  ```
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]
419
+ $addAttachment[https://example.com/gambar.png;gambar.png]
420
+ $addTextFile[catatan.txt;isi file teks buatan sendiri]
421
+ $poll[Makan apa?;24;false;Nasi;Mie;Roti]
422
+ $sendWebhook[https://discord.com/api/webhooks/ID/TOKEN;Halo!;Nama Bot;https://example.com/avatar.png]
391
423
  ```
392
424
 
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.
425
+ Lampiran hanya dari URL `http(s)` atau teks buatan sendiri (bot tidak membaca file dari disk). `$poll[pertanyaan;jam;multi;opsi...]` butuh 2-10 opsi.
394
426
 
395
- ### Threads, Forums, and Guild Management
427
+ ### Thread, forum, dan manajemen server
396
428
 
397
429
  ```
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
430
+ $createThread[Diskusi;$messageID;1440] -> mengembalikan ID thread
431
+ $createForumPost[ID_FORUM;Judul;Isi]
432
+ $unban[ID;alasan] $isBanned[ID] $banCount
433
+ $createChannel[info;text;ID_KATEGORI;Topik] $lockChannel $unlockChannel
402
434
  $createRole[VIP;#ff0000;true] $createInvite[;3600;10]
403
- $createEvent[WatchParty;START_MS;END_MS;Voice 1;Description]
435
+ $createEvent[Nobar;MULAI_MS;SELESAI_MS;Voice 1;Deskripsi]
404
436
  ```
405
437
 
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.
438
+ Fungsi manajemen memakai **izin bot**, jadi lindungi dengan `$onlyPerms[...]` seperti di bagian [Keamanan](#15-keamanan). Daftar lengkapnya ada di bagian [Daftar semua fungsi](#17-daftar-semua-fungsi).
407
439
 
408
440
  ---
409
441
 
410
- ## 11. Eval (Owner Only)
442
+ ## 11. Eval (khusus owner)
411
443
 
412
- Eval executes code inputted dynamically while the bot is running, which is useful for debugging. There are two types:
444
+ Eval menjalankan kode yang diketik saat bot berjalan, berguna untuk debugging. Ada dua jenis:
413
445
 
414
- | Function | Code Language Executed |
446
+ | Fungsi | Bahasa kode yang dijalankan |
415
447
  |---|---|
416
- | `$eval[code]` | Wrapper-version code, which uses this package's `$function` syntax |
417
- | `$jsEval[code]` | JavaScript / **native discord.js** |
448
+ | `$eval[kode]` | kode versi port, yaitu sintaks `$fungsi` package ini |
449
+ | `$jsEval[kode]` | JavaScript / **discord.js asli** |
418
450
 
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`.
451
+ Di `$jsEval` tersedia variabel: `ctx` `client` `bot` `guild` `channel` `message` `user` `member` `interaction` `discord` (modul discord.js) `db` `require`. Ekspresi tunggal langsung dikembalikan hasilnya; untuk beberapa pernyataan, tulis `return`. Boleh memakai `await`.
420
452
 
421
- ### Easiest Way to Use
453
+ ### Cara pakai paling mudah
422
454
 
423
455
  ```js
424
456
  const bot = new Bot({
425
457
  token: process.env.TOKEN,
426
- owners: ['YOUR_DISCORD_ID'],
427
- eval: true, // eval is DISABLED unless turned on here
458
+ owners: ['ID_DISCORD_KAMU'],
459
+ eval: true, // eval MATI kecuali dinyalakan di sini
428
460
  });
429
461
 
430
- bot.evalCommand(); // mounts the "eval" command (name can be changed: { name: 'e', aliases: ['ev'] })
462
+ bot.evalCommand(); // memasang command "eval" (nama bisa diganti: { name: 'e', aliases: ['ev'] })
431
463
  ```
432
464
 
433
- Then in Discord:
465
+ Lalu di Discord:
434
466
 
435
467
  ```
436
- !eval $math[6*7] -> wrapper syntax version
437
- !eval Hello $username from $serverName
438
- !eval js client.guilds.cache.size -> native discord.js
468
+ !eval $math[6*7] -> kode versi port
469
+ !eval Halo $username dari $serverName
470
+ !eval js client.guilds.cache.size -> discord.js asli
439
471
  !eval js guild.members.cache.filter(m => m.user.bot).size
440
472
  !eval js const g = await client.guilds.fetch(guild.id);
441
473
  return g.memberCount;
442
474
  ```
443
475
 
444
- Results are sent inside a code block (max ±1800 characters), errors are displayed as `❌ ...`, and **tokens are automatically censored** from the output.
476
+ Hasil dikirim dalam blok kode (maksimal ±1800 karakter), error ditampilkan sebagai `❌ ...`, dan **token otomatis disensor** dari hasil.
445
477
 
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).
478
+ Bisa juga dipakai di command buatan sendiri: `$eval[$message]` dan `$jsEval[$message]`. Gunakan `$messageFrom[2]` untuk mengambil semua teks mulai kata ke-2 (spasi dan baris baru terjaga).
447
479
 
448
- ### ⚠️ Security Warnings
480
+ ### Tes semua fitur dengan satu command (selftest)
449
481
 
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.
482
+ Setelah bot online di server Anda, jalankan tes otomatis langsung di Discord asli. Ini cara tercepat untuk tahu apakah semuanya benar-benar jalan di bot Anda (bukan hanya di tes tiruan):
483
+
484
+ ```js
485
+ const bot = new Bot({ token: process.env.TOKEN, owners: ['ID_KAMU'] });
486
+ bot.selfTestCommand(); // atau bot.selfTestCommand({ ui: true })
487
+ bot.connect();
488
+ ```
489
+
490
+ | Ketik | Yang diuji |
491
+ |---|---|
492
+ | `!selftest` | Fungsi dasar (`$math`, `$if`, `$date`, dll.), **database** (simpan, baca, tambah, reset), dan **pengiriman** embed + tombol + select menu + select user, lampiran file, dan polling. Pesan uji lampiran dan polling dihapus otomatis. |
493
+ | `!selftest full` | Semua di atas, ditambah membuat lalu **menghapus** channel dan role sementara (nama, topik, kunci channel, undangan, edit/pin/reaksi pesan, thread). Channel/role sementara selalu dihapus walaupun ada langkah yang gagal. |
494
+
495
+ Hasilnya berupa daftar `✅` (lulus), `❌` (gagal, lengkap dengan pesan penyebabnya), dan `⚠️` (dilewati karena bot kurang izin). Kirim isi daftar `❌` ke pengembang untuk diperbaiki.
496
+
497
+ Yang tidak bisa diuji otomatis karena butuh klik manusia: tombol, modal, dan select menu pada pesan uji. Klik sendiri, masing-masing akan membalas `✅ ... berfungsi`. Dengan `ui: true` Anda juga mendapat `/tesauto` (ketik di opsi `buah` untuk melihat autocomplete) dan dua menu klik-kanan **Tes Profil** (klik kanan user) dan **Tes Pesan** (klik kanan pesan).
498
+
499
+ Command ini khusus owner dan punya jeda 10 detik. Hapus `bot.selfTestCommand()` bila sudah tidak diperlukan, terutama `ui: true` yang meninggalkan slash command dan menu klik-kanan di server.
500
+
501
+ Untuk menguji **kode package itu sendiri** (tanpa Discord) pakai `npm test` di folder package.
502
+
503
+ ### ⚠️ Peringatan keamanan
504
+
505
+ - **`$jsEval` memberi akses PENUH** ke bot dan mesin tempat bot berjalan: membaca file, variabel lingkungan, mengirim data keluar, bahkan mematikan proses. Eval hanya berjalan bila `eval: true` **dan** pengirim ada di `owners`; selain itu langsung ditolak.
506
+ - Isi `owners` hanya dengan ID **Anda sendiri**. Jangan beri akses kepada orang lain, termasuk "admin kepercayaan".
507
+ - Jika akun Discord owner dibajak, penyerang bisa mengambil alih server hosting. Aktifkan 2FA.
508
+ - Matikan `eval` (hapus `eval: true`) di bot produksi yang tidak membutuhkannya.
509
+ - Sensor token hanya pencegah kecelakaan, bukan pengaman: kode JS tetap bisa membaca token dan mengirimnya ke tempat lain.
510
+ - `$eval` bersarang dibatasi 3 tingkat. Perulangan tak berujung (`while(true){}`) di `$jsEval` tidak bisa dihentikan, dan akan membekukan bot sampai di-restart.
456
511
 
457
512
  ---
458
513
 
459
- ## 12. Database & Plugins (MongoDB)
514
+ ## 12. Database & plugin (MongoDB)
460
515
 
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.
516
+ Secara bawaan data variabel disimpan di file `easydc-data.json`. Untuk bot yang lebih serius (data tidak hilang saat hosting menghapus file, atau lebih dari satu server), pakai **MongoDB** lewat plugin.
462
517
 
463
- ### Install the MongoDB Plugin
518
+ ### Pasang plugin MongoDB
464
519
 
465
520
  ```bash
466
- npm install easydc-js discord.js mongodb
521
+ npm install @tryty/easydc-js discord.js mongodb
467
522
  ```
468
523
 
469
524
  ```js
470
- const { Bot } = require('easydc-js');
471
- const { mongodb } = require('easydc-js/mongodb');
525
+ const { Bot } = require('@tryty/easydc-js');
526
+ const { mongodb } = require('@tryty/easydc-js/mongodb');
472
527
 
473
528
  const bot = new Bot({ token: process.env.TOKEN, prefix: '!' });
474
529
 
475
530
  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)
531
+ uri: process.env.MONGO_URI, // mis. mongodb+srv://user:sandi@cluster0.xxxx.mongodb.net
532
+ dbName: 'botku', // nama database (dibuat otomatis oleh MongoDB)
478
533
  }));
479
534
 
480
- bot.variables({ money: 100 });
481
- bot.command({ name: 'work', code: '$incUserVar[money;25]Your money is now $getUserVar[money]' });
535
+ bot.variables({ uang: 100 });
536
+ bot.command({ name: 'kerja', code: '$incUserVar[uang;25]Uangmu sekarang $getUserVar[uang]' });
482
537
 
483
538
  bot.connect();
484
539
  ```
485
540
 
486
- That's the only change required: all `$getUserVar`, `$setUserVar`, etc., will automatically use MongoDB. `bot.use(...)` must be called **before** `bot.connect()`.
541
+ Hanya itu yang berubah: semua `$getUserVar`, `$setUserVar`, dll. otomatis memakai MongoDB. `bot.use(...)` harus dipanggil **sebelum** `bot.connect()`.
487
542
 
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**.
543
+ Cara mendapatkan MongoDB gratis: buat cluster di MongoDB Atlas (paket M0), buat user database, izinkan IP hosting Anda di *Network Access*, lalu salin *connection string*. Simpan di variabel lingkungan `MONGO_URI`, **jangan ditulis di kode**.
489
544
 
490
- ### Plugin Options
545
+ ### Opsi plugin
491
546
 
492
- | Option | Description |
547
+ | Opsi | Keterangan |
493
548
  |---|---|
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)`. |
549
+ | `uri` | Alamat MongoDB (wajib). |
550
+ | `dbName` | Nama database. Jika kosong dipakai nama dari URI, atau `test`. |
551
+ | `collection` | Nama collection, bawaan `easydc`. Tiap variabel = satu dokumen `{ _id, v, t }`. |
552
+ | `cache` | Bawaan `true`: data yang sudah dibaca disimpan di RAM supaya cepat. **Ubah ke `false` jika lebih dari satu proses bot memakai database yang sama**, kalau tidak data bisa basi. |
553
+ | `cacheLimit` | Maksimal kunci di cache (bawaan 10000). |
554
+ | `client` | `MongoClient` buatan sendiri (tidak ditutup otomatis oleh bot). |
555
+ | `clientOptions` | Opsi tambahan untuk `new MongoClient(uri, opsi)`. |
501
556
 
502
- If MongoDB cannot be reached, the bot **will not log in** and prints `Failed to connect to database: ...` (timeout is 10 seconds).
557
+ Jika MongoDB tidak bisa dihubungi, bot **tidak login** dan menampilkan pesan `Gagal terhubung ke database: ...` (batas tunggu 10 detik).
503
558
 
504
- ### Migrating Old Data (JSON → MongoDB)
559
+ ### Memindahkan data lama (JSON → MongoDB)
505
560
 
506
- A one-time script, run it in the bot's root folder before using the plugin:
561
+ Skrip sekali jalan, jalankan di folder bot sebelum memakai plugin:
507
562
 
508
563
  ```js
509
- const { Database, copyDatabase } = require('easydc-js');
510
- const { MongoDatabase } = require('easydc-js/mongodb');
564
+ const { Database, copyDatabase } = require('@tryty/easydc-js');
565
+ const { MongoDatabase } = require('@tryty/easydc-js/mongodb');
511
566
 
512
567
  (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();
568
+ const lama = new Database({ path: './easydc-data.json' });
569
+ const baru = new MongoDatabase({ uri: process.env.MONGO_URI, dbName: 'botku' });
570
+ await baru.connect();
571
+ console.log(await copyDatabase(lama, baru)); // { copied: 120, skipped: 0 }
572
+ await baru.close();
518
573
  })();
519
574
  ```
520
575
 
521
- Existing data in MongoDB will not be overwritten. Pass `{ overwrite: true }` as the third argument if you wish to overwrite it.
576
+ Data yang sudah ada di MongoDB tidak ditimpa. Tambahkan `{ overwrite: true }` sebagai argumen ketiga bila ingin menimpa.
522
577
 
523
- ### `$inc...Var`: Safely Incrementing Numbers
578
+ ### `$inc...Var`: tambah angka dengan aman
524
579
 
525
- The `$setUserVar[money;$math[$getUserVar[money]+10]]` pattern can **lose data** if two commands execute concurrently (both reading the old value). Instead, use:
580
+ Pola `$setUserVar[uang;$math[$getUserVar[uang]+10]]` bisa **kehilangan data** jika dua command berjalan bersamaan (keduanya membaca nilai lama). Gunakan:
526
581
 
527
582
  ```
528
- $incUserVar[money;10] $incUserVar[money;-5] (decrease)
583
+ $incUserVar[uang;10] $incUserVar[uang;-5] (kurangi)
529
584
  $incServerVar $incChannelVar $incGlobalVar
530
585
  ```
531
586
 
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.
587
+ `$incUserVar[nama;jumlah;userID?]` berjalan berurutan per variabel sehingga tidak saling menimpa. Perlindungan ini berlaku di dalam **satu proses bot**; jika Anda menjalankan beberapa proses bot pada database yang sama, tabrakan antar proses masih mungkin.
533
588
 
534
- ### Creating a Custom Plugin / Database Adapter
589
+ ### Membuat plugin / adapter database sendiri
535
590
 
536
- A plugin is either a function or an object `{ name, install(bot, options) }`; `install` must be synchronous.
591
+ Plugin adalah function atau object `{ name, install(bot, opsi) }`; `install` harus sinkron.
537
592
 
538
593
  ```js
539
594
  bot.use({
540
- name: 'hello',
595
+ name: 'halo',
541
596
  install(bot) {
542
- bot.addFunction({ name: '$hello', params: 0, run: () => 'Hello from plugin!' });
597
+ bot.addFunction({ name: '$halo', params: 0, run: () => 'Halo dari plugin!' });
543
598
  },
544
599
  });
545
600
  ```
546
601
 
547
- A database adapter (for Redis, SQLite, etc.) just needs to be an object with the following methods; all of them can be `async`:
602
+ Adapter database (untuk Redis, SQLite, dll.) cukup berupa object dengan method berikut; semuanya boleh `async`:
548
603
 
549
- | Method | Required | Description |
604
+ | Method | Wajib | Keterangan |
550
605
  |---|---|---|
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. |
606
+ | `get(key)` | ya | Kembalikan nilai (teks) atau `undefined` jika tidak ada. |
607
+ | `set(key, value)` | ya | Simpan nilai teks. |
608
+ | `delete(key)` | ya | Hapus kunci. |
609
+ | `keys(prefix?)` | tidak | Dibutuhkan oleh `copyDatabase`. |
610
+ | `connect()` / `close()` | tidak | Dipanggil sebelum login Discord / saat bot dimatikan. |
611
+ | `flush()` | tidak | Simpan data yang tertunda. |
557
612
 
558
- Install using `bot.setDatabase(adapter)` or `new Bot({ database: adapter })`.
613
+ Pasang dengan `bot.setDatabase(adapter)` atau `new Bot({ database: adapter })`.
559
614
 
560
- > **Changes from version 1.1:** `bot.getVar`, `bot.setVar`, `bot.resetVar` now return a **Promise** (use `await`). `$function` styled commands are unaffected.
615
+ > **Perubahan dari versi 1.1:** `bot.getVar`, `bot.setVar`, `bot.resetVar` kini mengembalikan **Promise** (pakai `await`). Command bergaya `$fungsi` tidak terpengaruh.
561
616
 
562
617
  ---
563
618
 
564
- ## 13. Creating Custom Functions
619
+ ## 13. Membuat fungsi sendiri
565
620
 
566
621
  ```js
567
622
  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})`,
623
+ name: '$salam',
624
+ params: 1, // jumlah argumen tepat (atau pakai min/max)
625
+ description: 'Menyapa seseorang',
626
+ run: (ctx, [nama]) => `Selamat datang, ${nama}! (diminta oleh ${ctx.user.username})`,
572
627
  });
573
628
 
574
- bot.command({ name: 'test', code: '$greetUser[Budi]' });
629
+ bot.command({ name: 'tes', code: '$salam[Budi]' });
575
630
  ```
576
631
 
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.
632
+ `run` boleh `async`. `ctx` berisi `bot`, `client`, `guild`, `channel`, `member`, `user`, `message`, `interaction`, `args`. Lempar `new Error('pesan')` bila gagal; pesan itu akan dicatat di log.
633
+ Opsi `override: true` mengganti fungsi bawaan.
579
634
 
580
- ## 14. Splitting Commands into Multiple Files
635
+ ## 14. Memisah command ke banyak file
581
636
 
582
637
  ```
583
- project/
638
+ proyek/
584
639
  ├── index.js
585
640
  └── commands/
586
- ├── general.js
587
- └── moderation.js
641
+ ├── umum.js
642
+ └── moderasi.js
588
643
  ```
589
644
 
590
645
  ```js
591
646
  bot.loadCommands('./commands');
592
647
  ```
593
648
 
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).
649
+ Setiap file mengekspor satu objek atau array. Tambahkan `type` untuk selain command biasa (`'slash'`, `'button'`, `'select'`, `'modal'`, `'autocomplete'`, `'contextMenu'`, atau nama event seperti `'memberJoin'`). Contoh lengkap: [`examples/advanced/lanjutan.js`](examples/advanced/lanjutan.js).
595
650
 
596
651
  ```js
597
652
  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' },
653
+ { name: 'halo', code: 'Halo $username' },
654
+ { type: 'slash', name: 'ping', description: 'Cek ping', code: '$ping ms' },
655
+ { type: 'button', customId: 'ok_*', code: 'Oke!' },
656
+ { type: 'memberJoin', code: 'Selamat datang $mention' },
602
657
  ];
603
658
  ```
604
659
 
605
- ## 15. Security
660
+ ## 15. Keamanan
606
661
 
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).
662
+ - **Jangan taruh token di kode** atau di GitHub. Pakai variabel lingkungan. Jika token bocor, segera *Reset Token* di Developer Portal.
663
+ - Fungsi aksi dan manajemen (`$ban`, `$unban`, `$kick`, `$timeout`, `$addRole`, `$clear`, `$sendDM`, `$createChannel`, `$deleteChannel`, `$deleteRole`, `$lockChannel`, `$leaveServer`, ...) memakai **izin bot**, bukan izin pengirim. **Selalu** lindungi dengan `$onlyPerms[...]`, `$onlyAdmin`, atau `$onlyOwner` di baris pertama command.
664
+ - Mention yang dikirim bot dibatasi ke user saja (`@everyone` dan role tidak akan menyebut siapa pun). Ubah lewat opsi `allowedMentions` bila perlu.
665
+ - Kalkulator `$math` tidak memakai `eval`, jadi aman dari eksekusi kode.
666
+ - Biarkan `debug: false` di produksi supaya detail error tidak tampil ke pengguna (tetap tercatat di konsol).
612
667
 
613
- ## 16. Troubleshooting
668
+ ## 16. Pemecahan masalah
614
669
 
615
- | Issue | Cause / Solution |
670
+ | Masalah | Penyebab / solusi |
616
671
  |---|---|
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. |
672
+ | Bot online tapi tidak merespons `!ping` | Aktifkan **Message Content Intent** di Developer Portal. |
673
+ | `Used disallowed intents` saat login | Aktifkan intent yang diminta di Developer Portal (Server Members / Message Content), atau kurangi `intents`. |
674
+ | Event member masuk/keluar tidak jalan | Aktifkan **Server Members Intent**. |
675
+ | Slash command tidak muncul | Undang bot dengan scope `applications.commands`. Pakai `slashGuild` agar langsung muncul; global bisa butuh waktu. |
676
+ | `Fungsi $xxx tidak dikenal` | Salah ketik. Jika maksudnya teks biasa, tulis `\$xxx` (atau `$dollar`). |
677
+ | `... membutuhkan N argumen` | Jumlah `;` tidak sesuai. Tulis `\;` bila `;` bagian dari teks. |
678
+ | Variabel "belum dideklarasikan" | Tambahkan di `bot.variables({ ... })` sebelum `bot.connect()`. |
679
+ | Tombol/select tidak merespons | Pastikan `customId` di tombol sama dengan di `bot.button({ customId })`. |
680
+ | `Missing Permissions` di log | Bot kurang izin / posisi role bot di bawah role target. |
681
+ | `Token belum diisi` | `process.env.TOKEN` kosong. Cek cara menjalankan di bagian 2. |
682
+ | Interaksi gagal ("This interaction failed") | Proses > 3 detik. Taruh `$defer` di awal. |
683
+ | Modal tidak muncul / "Modal harus jadi respons pertama" | Jangan pakai `$defer` atau kirim pesan sebelum `$addModal`. Modal hanya dari slash/tombol/select, bukan command prefix. |
684
+ | Autocomplete kosong | Opsi harus dibuat dengan `autocomplete: true`, dan handler `bot.autocomplete({ command, option })` cocok. Proses harus selesai < 3 detik. |
685
+ | `Package "mongodb" tidak ditemukan` | Jalankan `npm install mongodb` (di host panel: tambahkan `mongodb` ke *Additional Node Packages*). |
686
+ | `Gagal terhubung ke database` | Periksa `MONGO_URI`, user & sandi, dan izinkan IP hosting di MongoDB Atlas (*Network Access*). Sandi dengan karakter khusus (`@ : /`) harus di-URL-encode. |
687
+ | Data di MongoDB tidak berubah / terlihat basi | Ada lebih dari satu proses bot pada database yang sama: set `cache: false`. |
688
+ | "Hanya untuk owner" padahal sudah isi ID | (1) ID **wajib pakai tanda kutip**: `owners: ['123456789012345678']`; tanpa kutip angkanya membulat dan tidak cocok (versi 1.2.3+ langsung memberi error). (2) Salin **User ID** akunmu (Developer Mode → klik kanan profil → Copy User ID), bukan ID server/bot. (3) Lihat konsol panel: tertulis `[easydc] ... ID pengirim = "..."`, salin ID itu ke `owners`. |
689
+ | `$eval ... dimatikan` | Tambahkan `eval: true` dan `owners: ['ID_KAMU']` pada `new Bot({...})`. |
690
+ | Event ban / voice tidak jalan | Intent `GuildModeration` / `GuildVoiceStates` sudah aktif secara bawaan; jika kamu mengatur `intents` sendiri, tambahkan keduanya. |
635
691
 
636
692
  ---
637
693
 
638
- ## 17. List of All Functions
694
+ ## 17. Daftar semua fungsi
639
695
 
640
- The `?` symbol means the argument is optional. This list is automatically generated from the source code (`npm run docs`).
696
+ Tanda `?` berarti argumen opsional. Daftar ini dibuat otomatis dari kode (`npm run docs`).
641
697
 
642
698
  <!-- FUNCTIONS:START -->
643
699
 
644
- ### Info (user, server, bot, message, time)
700
+ ### Info (user, server, bot, pesan, waktu)
645
701
 
646
- | Function | Description |
702
+ | Fungsi | Keterangan |
647
703
  |---|---|
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 |
704
+ | `$username[userID?]` | Username (tanpa ID = pengirim) |
705
+ | `$usertag[userID?]` | Tag user |
706
+ | `$displayName[userID?]` | Nama tampilan (nickname server / nama global / username) |
707
+ | `$nickname[userID?]` | Nickname di server (kosong -> username) |
708
+ | `$authorID` | ID pengirim pesan / pengguna interaksi |
709
+ | `$userAvatar[userID?;ukuran?]` | URL avatar (ukuran 16-4096) |
710
+ | `$isBot[userID?]` | true/false: apakah user adalah bot |
711
+ | `$userCreatedAt[userID?]` | Waktu akun dibuat (ms) |
712
+ | `$mentioned[nomor;fallbackAuthor?]` | ID user yang di-mention ke-N (isi 2: yes = pakai pengirim bila tidak ada) |
713
+ | `$mention[userID?]` | Mention user, contoh <@123> |
714
+ | `$serverName` | Nama server |
715
+ | `$serverID` | ID server |
716
+ | `$serverIcon` | URL ikon server |
717
+ | `$memberCount` | Jumlah member server |
718
+ | `$ownerID` | ID pemilik server |
719
+ | `$serverCreatedAt` | Waktu server dibuat (ms) |
720
+ | `$roleCount` | Jumlah role |
721
+ | `$channelCount` | Jumlah channel |
722
+ | `$channelName[channelID?]` | Nama channel (tanpa ID = channel ini) |
723
+ | `$channelID` | ID channel saat ini |
724
+ | `$channelMention[channelID?]` | Mention channel, contoh <#123> |
725
+ | `$roleName[roleID]` | Nama role |
726
+ | `$roleMention[roleID]` | Mention role, contoh <@&123> |
727
+ | `$botID` | ID bot |
728
+ | `$botName` | Username bot |
729
+ | `$ping` | Ping websocket (ms) |
730
+ | `$uptime` | Lama bot menyala, contoh "1d 2h 3m 4s" |
731
+ | `$serverCount` | Jumlah server tempat bot berada |
732
+ | `$message[nomor?]` | Semua argumen setelah command, atau argumen ke-N |
733
+ | `$argsCount` | Jumlah argumen |
734
+ | `$messageID` | ID pesan / interaksi |
735
+ | `$messageContent` | Isi lengkap pesan pemicu |
736
+ | `$commandName` | Nama command yang berjalan |
737
+ | `$option[nama]` | Nilai opsi slash command |
738
+ | `$customID` | customId tombol/select yang ditekan |
739
+ | `$interactionValues[nomor?]` | Nilai yang dipilih di select menu |
740
+ | `$reactionEmoji` | Emoji pada event reaksi |
741
+ | `$timestamp` | Waktu sekarang (ms) |
742
+ | `$unix` | Waktu sekarang (detik) |
743
+ | `$date[format?;ms?]` | Tanggal/jam. Token: YYYY MM DD HH mm ss. Zona waktu dari opsi timezone |
744
+ | `$discordTime[ms?;gaya?]` | Format waktu Discord <t:..>. Gaya: t T d D f F R |
745
+
746
+ ### Teks, matematika & pengecekan
747
+
748
+ | Fungsi | Keterangan |
693
749
  |---|---|
694
- | `$math[expression]` | Safe evaluation. Supports + - * / % ^ ( ) sqrt abs round floor ceil min max pow pi e |
695
- | `$sum[a;b;...]` | Sum of all numbers |
750
+ | `$math[ekspresi]` | Hitung aman. Dukung + - * / % ^ ( ) sqrt abs round floor ceil min max pow pi e |
751
+ | `$sum[a;b;...]` | Jumlah semua angka |
696
752
  | `$sub[a;b]` | a - b |
697
- | `$multiply[a;b;...]` | Multiply all numbers |
753
+ | `$multiply[a;b;...]` | Kali semua angka |
698
754
  | `$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 |
755
+ | `$modulo[a;b]` | Sisa bagi a % b |
756
+ | `$round[angka;desimal?]` | Bulatkan angka |
757
+ | `$max[a;b;...]` | Angka terbesar |
758
+ | `$min[a;b;...]` | Angka terkecil |
759
+ | `$random[min;max]` | Bilangan bulat acak (inklusif) |
760
+ | `$randomText[a;b;...]` | Pilih salah satu teks secara acak |
761
+ | `$numberSeparator[angka;pemisah?]` | 1234567 -> 1,234,567 |
762
+ | `$toUpperCase[teks]` | HURUF BESAR |
763
+ | `$toLowerCase[teks]` | huruf kecil |
764
+ | `$capitalize[teks]` | Huruf pertama jadi besar |
765
+ | `$titleCase[teks]` | Huruf Pertama Tiap Kata Besar |
766
+ | `$trimSpace[teks]` | Hapus spasi di awal/akhir |
767
+ | `$length[teks]` | Jumlah karakter |
768
+ | `$reverse[teks]` | Balik urutan teks |
769
+ | `$repeat[teks;jumlah]` | Ulang teks (maks 100x) |
770
+ | `$substring[teks;awal;akhir?]` | Potong teks (indeks mulai 0) |
771
+ | `$replaceText[teks;cari;ganti;batas?]` | Ganti teks (semua, atau N pertama) |
772
+ | `$split[teks;pemisah;nomor]` | Ambil bagian ke-N setelah memecah teks |
773
+ | `$urlEncode[teks]` | Encode untuk URL |
774
+ | `$semicolon` | Karakter ; |
775
+ | `$leftBracket` | Karakter [ |
776
+ | `$rightBracket` | Karakter ] |
777
+ | `$dollar` | Karakter $ |
778
+ | `$isNumber[teks]` | true/false: apakah angka |
779
+ | `$checkContains[teks;cari1;cari2;...]` | true bila teks memuat salah satu kata |
780
+ | `$checkCondition[kondisi]` | true/false. Operator: == != > < >= <= && \|\| |
781
+ | `$hasRole[roleID;userID?]` | true/false: member punya role |
782
+ | `$hasPerms[izin1,izin2;userID?]` | true/false: member punya semua izin (nama izin discord.js) |
783
+ | `$isAdmin[userID?]` | true/false: member administrator |
784
+ | `$isOwner[userID?]` | true/false: user ada di daftar owners bot |
785
+ | `$isTrue[teks]` | true bila teks bernilai true/yes/1/on |
786
+
787
+ ### Kontrol alur & batasan
788
+
789
+ | Fungsi | Keterangan |
734
790
  |---|---|
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 |
791
+ | `$if[kondisi]` | Mulai blok kondisi. Tutup dengan $endif |
792
+ | `$elseif[kondisi]` | Kondisi alternatif |
793
+ | `$else` | Jika semua kondisi sebelumnya salah |
794
+ | `$endif` | Menutup blok $if |
795
+ | `$stop[pesan?]` | Hentikan eksekusi (opsional kirim pesan) |
796
+ | `$onlyIf[kondisi;pesan?]` | Lanjut hanya jika kondisi benar |
797
+ | `$onlyPerms[Izin1,Izin2;pesan?]` | Lanjut hanya jika pengirim punya semua izin (mis. BanMembers) |
798
+ | `$onlyBotPerms[Izin1,Izin2;pesan?]` | Lanjut hanya jika bot punya izin tersebut di server |
799
+ | `$onlyAdmin[pesan?]` | Lanjut hanya jika pengirim administrator |
800
+ | `$onlyOwner[pesan?]` | Lanjut hanya jika pengirim ada di opsi owners |
801
+ | `$onlyForIDs[id1,id2;pesan?]` | Lanjut hanya untuk user dengan ID tertentu |
802
+ | `$onlyInServer[pesan?]` | Lanjut hanya jika dipakai di server (bukan DM) |
803
+ | `$argsCheck[syarat;pesan?]` | Cek jumlah argumen. "2" = minimal 2; juga >=1 <=3 >1 <3 =2 |
804
+ | `$cooldown[waktu;pesan?]` | Cooldown per user per command. %time% di pesan = sisa waktu |
805
+ | `$wait[waktu]` | Tunggu sebentar (maks 60 detik) |
806
+ | `$deleteCommand` | Hapus pesan perintah milik pengirim setelah dijawab |
807
+ | `$deleteIn[waktu]` | Hapus jawaban bot setelah waktu tertentu (maks 24 jam) |
808
+ | `$ephemeral` | Slash/tombol: jawaban hanya terlihat oleh pengguna |
809
+ | `$reply` | Jawab dengan fitur reply pada pesan perintah |
810
+ | `$update` | Tombol/select: ubah pesan asal, bukan kirim pesan baru |
811
+ | `$typing` | Tampilkan "sedang mengetik" |
812
+ | `$defer` | Slash/tombol: tunda jawaban (untuk proses > 3 detik). Taruh $ephemeral sebelum ini bila perlu |
813
+ | `$let[nama;nilai]` | Simpan variabel sementara (hanya selama command berjalan) |
814
+ | `$get[nama]` | Ambil variabel sementara dari $let |
815
+
816
+ ### Variabel & database
817
+
818
+ | Fungsi | Keterangan |
763
819
  |---|---|
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 |
820
+ | `$setUserVar[nama;nilai;userID?]` | Simpan variabel user (harus dideklarasikan dengan bot.variables) |
821
+ | `$getUserVar[nama;userID?]` | Baca variabel user |
822
+ | `$resetUserVar[nama;userID?]` | Kembalikan variabel user ke nilai awal |
823
+ | `$incUserVar[nama;jumlah;userID?]` | Tambah variabel user berupa angka (jumlah negatif = kurangi). Aman dari tabrakan antar command. Tidak menampilkan apa pun |
824
+ | `$setServerVar[nama;nilai;serverID?]` | Simpan variabel server (harus dideklarasikan dengan bot.variables) |
825
+ | `$getServerVar[nama;serverID?]` | Baca variabel server |
826
+ | `$resetServerVar[nama;serverID?]` | Kembalikan variabel server ke nilai awal |
827
+ | `$incServerVar[nama;jumlah;serverID?]` | Tambah variabel server berupa angka (jumlah negatif = kurangi). Aman dari tabrakan antar command. Tidak menampilkan apa pun |
828
+ | `$setChannelVar[nama;nilai;channelID?]` | Simpan variabel channel (harus dideklarasikan dengan bot.variables) |
829
+ | `$getChannelVar[nama;channelID?]` | Baca variabel channel |
830
+ | `$resetChannelVar[nama;channelID?]` | Kembalikan variabel channel ke nilai awal |
831
+ | `$incChannelVar[nama;jumlah;channelID?]` | Tambah variabel channel berupa angka (jumlah negatif = kurangi). Aman dari tabrakan antar command. Tidak menampilkan apa pun |
832
+ | `$setGlobalVar[nama;nilai]` | Simpan variabel global |
833
+ | `$getGlobalVar[nama]` | Baca variabel global |
834
+ | `$resetGlobalVar[nama]` | Kembalikan variabel global ke nilai awal |
835
+ | `$incGlobalVar[nama;jumlah]` | Tambah variabel global berupa angka (jumlah negatif = kurangi) |
836
+
837
+ ### Embed
838
+
839
+ | Fungsi | Keterangan |
784
840
  |---|---|
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 |
841
+ | `$newEmbed` | Mulai embed baru (embed pertama dibuat otomatis). Maks 10 |
842
+ | `$title[teks]` | Judul embed (maks 256) |
843
+ | `$embedURL[url]` | Tautan pada judul embed |
844
+ | `$description[teks]` | Isi embed (maks 4096) |
845
+ | `$color[#hex|nama|random]` | Warna embed |
846
+ | `$footer[teks;ikonURL?]` | Footer embed (maks 2048) |
847
+ | `$author[nama;ikonURL?;url?]` | Penulis embed (maks 256) |
848
+ | `$thumbnail[url]` | Gambar kecil embed |
849
+ | `$image[url]` | Gambar besar embed |
850
+ | `$addField[nama;isi;inline?]` | Tambah field (maks 25; inline = true/false) |
851
+ | `$addTimestamp[ms?]` | Tambah cap waktu di embed (default: sekarang) |
852
+
853
+ ### Tombol & select menu
854
+
855
+ | Fungsi | Keterangan |
800
856
  |---|---|
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 |
857
+ | `$addUserSelect[customID;placeholder?;min?;max?]` | Select menu pilih user (nilai terpilih lewat $interactionValues) |
858
+ | `$addRoleSelect[customID;placeholder?;min?;max?]` | Select menu pilih role (nilai terpilih lewat $interactionValues) |
859
+ | `$addMentionableSelect[customID;placeholder?;min?;max?]` | Select menu pilih user atau role (nilai terpilih lewat $interactionValues) |
860
+ | `$addChannelSelect[customID;placeholder?;min?;max?;tipe?]` | Select menu pilih channel (nilai terpilih lewat $interactionValues). Tipe: text voice category announcement stage forum, pisah koma |
861
+ | `$newRow` | Mulai baris tombol baru (otomatis tiap 5 tombol) |
862
+ | `$addButton[label;gaya;customID/URL;nonaktif?;emoji?]` | Tambah tombol. Gaya: primary secondary success danger link |
863
+ | `$addSelectMenu[customID;placeholder?;min?;max?]` | Buat select menu (lanjutkan dengan $addSelectOption) |
864
+ | `$addSelectOption[label;nilai;deskripsi?;emoji?;default?]` | Tambah opsi ke select menu terakhir (maks 25) |
865
+
866
+ ### Aksi & moderasi
867
+
868
+ | Fungsi | Keterangan |
813
869
  |---|---|
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 |
870
+ | `$sendMessage[channelID;teks]` | Kirim pesan ke channel lain |
871
+ | `$sendDM[userID;teks]` | Kirim DM ke user |
872
+ | `$react[emoji1;emoji2;...]` | Beri reaksi pada pesan perintah |
873
+ | `$ban[userID;alasan?;hariHapusPesan?]` | Ban user (hapus pesan 0-7 hari) |
874
+ | `$kick[userID;alasan?]` | Kick member |
875
+ | `$timeout[userID;waktu;alasan?]` | Timeout member (maks 28 hari) |
876
+ | `$untimeout[userID;alasan?]` | Cabut timeout member |
877
+ | `$addRole[userID;roleID;alasan?]` | Beri role |
878
+ | `$removeRole[userID;roleID;alasan?]` | Cabut role |
879
+ | `$setNickname[userID;nickname]` | Ubah nickname (kosongkan untuk reset) |
880
+ | `$clear[jumlah]` | Hapus 1-100 pesan terakhir (maks umur 14 hari). Mengembalikan jumlah terhapus |
881
+ | `$slowmode[detik]` | Atur slowmode channel (0 = mati, maks 21600) |
882
+
883
+ ### Pesan, lampiran, polling, thread & webhook
884
+
885
+ | Fungsi | Keterangan |
830
886
  |---|---|
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 |
887
+ | `$editMessage[messageID;teks;channelID?]` | Edit pesan milik bot sendiri |
888
+ | `$deleteMessage[messageID;channelID?]` | Hapus satu pesan |
889
+ | `$pinMessage[messageID;channelID?]` | Sematkan (pin) pesan |
890
+ | `$unpinMessage[messageID;channelID?]` | Lepas pin pesan |
891
+ | `$addReaction[messageID;emoji;channelID?]` | Beri reaksi pada pesan tertentu |
892
+ | `$messageContentOf[messageID;channelID?]` | Isi teks pesan tertentu |
893
+ | `$messageAuthorOf[messageID;channelID?]` | ID pengirim pesan tertentu |
894
+ | `$addAttachment[url;nama?]` | Lampirkan file dari URL http(s) ke jawaban (maks 10) |
895
+ | `$addTextFile[namaFile;isi]` | Lampirkan file teks buatan sendiri (maks 1 MB) |
896
+ | `$poll[pertanyaan;jam;multi;opsi1;opsi2;...]` | Buat polling (jam 1-768, multi = true/false, 2-10 opsi) |
897
+ | `$sendWebhook[webhookURL;teks;username?;avatarURL?]` | Kirim pesan lewat URL webhook Discord |
898
+ | `$createThread[nama;messageID?;arsipOtomatisMenit?;channelID?]` | Buat thread (dari pesan bila messageID diisi; channelID = channel tempat pesan itu, bawaan channel ini). Arsip: 60/1440/4320/10080. Mengembalikan ID thread |
899
+ | `$archiveThread[threadID?;kunci?]` | Arsipkan thread (kunci = true untuk sekalian dikunci) |
900
+ | `$addThreadMember[userID;threadID?]` | Tambahkan user ke thread |
901
+ | `$removeThreadMember[userID;threadID?]` | Keluarkan user dari thread |
902
+ | `$createForumPost[forumID;judul;isi]` | Buat postingan di channel forum. Mengembalikan ID thread |
903
+
904
+ ### Manajemen server (ban, channel, role, undangan, emoji, event, voice)
905
+
906
+ | Fungsi | Keterangan |
851
907
  |---|---|
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 |
908
+ | `$unban[userID;alasan?]` | Cabut ban user |
909
+ | `$isBanned[userID]` | true/false: user sedang di-ban di server ini |
910
+ | `$banCount` | Jumlah user ter-ban (dibaca maks 1000 teratas) |
911
+ | `$createChannel[nama;tipe?;parentID?;topik?]` | Buat channel. Tipe: text voice category announcement stage forum. Mengembalikan ID |
912
+ | `$deleteChannel[channelID;alasan?]` | Hapus channel/thread (menghapus channel saat ini membuat jawaban gagal terkirim) |
913
+ | `$setChannelName[channelID;nama;alasan?]` | Ubah nama channel |
914
+ | `$setChannelTopic[channelID;topik;alasan?]` | Ubah topik channel |
915
+ | `$lockChannel[channelID?;alasan?]` | Kunci channel: @everyone tidak bisa mengirim pesan |
916
+ | `$unlockChannel[channelID?;alasan?]` | Buka kunci channel (kembali ke pengaturan semula) |
917
+ | `$createInvite[channelID?;umurDetik?;maxPakai?]` | Buat link undangan. Umur 0-604800 (0 = selamanya), maxPakai 0-100. Mengembalikan URL |
918
+ | `$channelType[channelID?]` | Tipe channel: text voice category announcement stage forum dst. |
919
+ | `$createRole[nama;warna?;hoist?;mentionable?;alasan?]` | Buat role. Mengembalikan ID |
920
+ | `$deleteRole[roleID;alasan?]` | Hapus role |
921
+ | `$setRoleName[roleID;nama;alasan?]` | Ubah nama role |
922
+ | `$setRoleColor[roleID;warna;alasan?]` | Ubah warna role (#hex / nama / random) |
923
+ | `$memberRoles[userID?]` | Daftar ID role member, dipisah koma |
924
+ | `$createEmoji[nama;url]` | Tambah emoji dari URL gambar. Mengembalikan emoji siap pakai |
925
+ | `$deleteEmoji[emojiID]` | Hapus emoji server |
926
+ | `$createEvent[nama;mulaiMs;selesaiMs;lokasi;deskripsi?]` | Buat scheduled event (di luar Discord). Waktu dalam ms (lihat $timestamp). Mengembalikan ID |
927
+ | `$moveMember[userID;voiceChannelID]` | Pindahkan member ke voice channel lain |
928
+ | `$disconnectMember[userID]` | Keluarkan member dari voice channel |
929
+ | `$leaveServer[serverID?]` | Bot keluar dari server. Hanya untuk owner bot |
930
+
931
+ ### Modal, autocomplete & sasaran
932
+
933
+ | Fungsi | Keterangan |
878
934
  |---|---|
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 |
935
+ | `$addModal[customID;judul]` | Tampilkan form pop-up (modal). Jadi respons pertama; teks lain diabaikan. Isi dengan $addTextInput |
936
+ | `$addTextInput[customID;label;gaya?;placeholder?;wajib?;min?;max?;nilaiAwal?]` | Tambah kolom isian ke modal (maks 5). Gaya: short / paragraph |
937
+ | `$modalValue[customIDKolom]` | Isi kolom modal yang dikirim pengguna (dipakai di handler bot.modal) |
938
+ | `$focusedValue` | Autocomplete: teks yang sedang diketik pengguna |
939
+ | `$focusedOption` | Autocomplete: nama opsi yang sedang diisi |
940
+ | `$addChoice[nama;nilai?]` | Autocomplete: tambah satu pilihan (maks 25). Nilai bawaan = nama |
941
+ | `$targetID` | ID sasaran: user/pesan yang diklik kanan, atau objek event (channel/role/thread/voice/ban) |
942
+ | `$targetName` | Nama sasaran (username / nama channel / nama role) |
943
+ | `$targetContent` | Isi pesan yang diklik kanan (context menu pesan) |
944
+ | `$messageFrom[nomor]` | Seluruh teks argumen mulai dari kata ke-N (spasi dan baris baru dipertahankan) |
945
+
946
+ ### Eval (khusus owner)
947
+
948
+ | Fungsi | Keterangan |
893
949
  |---|---|
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 |
950
+ | `$eval[kode]` | Jalankan kode versi port ($fungsi) dari teks saat berjalan. Khusus owner, butuh opsi eval: true |
951
+ | `$jsEval[kodeJavaScript]` | Jalankan kode discord.js/JavaScript asli. Variabel: ctx client bot guild channel message user member interaction discord db require. Khusus owner, butuh opsi eval: true |
896
952
 
897
- <!-- FUNCTIONS:START -->
953
+ <!-- FUNCTIONS:END -->
898
954
 
899
955
  ---
900
956
 
901
- ## What is Not Supported Yet
957
+ ## Yang belum didukung
902
958
 
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`.
959
+ Package ini belum mencakup seluruh discord.js. Belum ada: adapter database selain JSON dan MongoDB (SQLite, Redis, dll.; bisa dibuat sendiri, lihat bagian 12), **voice/musik** (memutar audio), **sharding**, **AutoMod rules**, **stiker**, pengaturan permission per-channel yang rinci, dan Components V2. Untuk itu pakai `bot.client` (client discord.js asli) atau tambahkan fungsi lewat `bot.addFunction`.
904
960
 
905
- ## Version History
961
+ ## Riwayat versi
906
962
 
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.
963
+ - **1.3.0**: plugin voice/musik (`@tryty/easydc-js/voice`, butuh Lavalink + `shoukaku`). Fungsi stop musik bernama `$stopMusic` karena `$stop` sudah dipakai fungsi inti.
964
+ - **1.2.3**: `owners` divalidasi (angka besar ditolak, mention/spasi dirapikan); penolakan owner mencatat ID pengirim ke konsol.
965
+ - **1.2.2**: nama package menjadi `@tryty/easydc-js`; panduan pemasangan dari file lokal.
966
+ - **1.2.1**: `bot.selfTestCommand()` (`!selftest`, tes otomatis di Discord asli); `$createThread` bisa membuat thread dari pesan di channel lain (argumen ke-4).
967
+ - **1.2.0**: sistem plugin (`bot.use`, `bot.setDatabase`), plugin **MongoDB** (`@tryty/easydc-js/mongodb`), `copyDatabase` untuk migrasi dari JSON, `$incUserVar` dan kawan-kawannya (tambah angka dengan aman). `bot.getVar/setVar/resetVar` kini async.
968
+ - **1.1.0**: `$unban` dan manajemen server (channel, role, undangan, emoji, event, voice), edit/hapus/pin pesan, lampiran, poll, webhook, thread & forum, modal, autocomplete, context menu, select user/role/channel, 9 event baru, `$eval` / `$jsEval` / `bot.evalCommand`. Intent bawaan bertambah `GuildModeration` dan `GuildVoiceStates`.
969
+ - **1.0.0**: rilis pertama.
910
970
 
911
- ## License
971
+ ## Lisensi
912
972
 
913
973
  MIT