wachan
Version:
Simpler way to code baileys.
665 lines (583 loc) • 34.9 kB
Markdown
[English](README.md) | Bahasa Indonesia
# wachan
Cara yang lebih simpel untuk meng-kode baileys.
## Peringatan Deprecation
Pada versi major berikutnya, semua fungsi respon (termasuk untuk command) akan disederhanakan sehingga memiliki 2 parameter saja:
- `context` - Ini akan berisi: `message`, `captures`, `group` dan `command`
- fungsi `next`
Penjelasan selengkapnya [di sini](#function-response)
## Daftar Isi
- [Instalasi](#instalasi)
- [Contoh](#contoh)
- [File Pengaturan](#file-pengaturan)
- [Pengaturan Awal](#pengaturan-awal)
- [Penjelasan](#penjelasan-tiap-item-di-pengaturan)
- [Objek Bot](#objek-bot)
- [Function Response](#function-response)
- [Objek Message](#objek-pesan-message)
- [Captures](#captures)
- [Value Yang Di Return](#value-yang-di-return)
- [Opsi Pengiriman Pesan](#opsi-pengiriman-pesan)
- [Mention User](#mention-user)
- [Data Grup](#data-grup)
- [Alur Receiver](#alur-receiver)
- [Enum Tipe Message](#enum-tipe-message)
- [Tools](#tools)
- [Commands](#commands-tool-requirewachancommands)
- [Sticker](#sticker-tool-requirewachansticker)
- [Custom Programming](#custom-programming)
- [Changelog](#changelog)
## Instalasi
```bash
npm install wachan
```
## Contoh
4 jenis input:
```javascript
const bot = require("wachan")
// 1) Input string: Deteksi pesan masuk yang punya teks persis dengan string
bot.onReceive("Hello", "Hi")
// 2) Input regex: Deteksi pesan masuk yang punya pola regex tersebut
bot.onReceive(/selamat (pagi|siang|sore|malam)/i, "halo")
// 3) Input function: Deteksi pesan jika hasil fungsinya true. (Fungsi filter pesan)
bot.onReceive((msg)=>msg.sender.id===OWNER_ID, "hello boss")
// 4) Input enum:
bot.onReceive(bot.messageType.video, "Pesan video diterima!")
```
3 Jenis respon:
```js
// 1) Respon string: Balas dengan pesan teks
bot.onReceive("Marco", "Polo")
// 2) Respon object: Lebih banyak opsi pengiriman
bot.onReceive("kirim gambar", {image:"buffer, url, atau path", caption:"Ini caption-nya"})
bot.onReceive("kirim video", {video:"...", caption:"..."})
bot.onReceive("kirim gif", {gif:"...", caption:"..."}) // file harus berupa video agar bisa bergerak (whatsapp tidak support file gif)
bot.onReceive("kirim audio", {audio:"..."})
bot.onReceive("kirim sticker", {sticker:"..."}) // file WebP
// 3) Respon function: Custom script
bot.onReceive("test", async (context, next) => {
// argument v1: message, captures, group, next
const { message, captures, group } = context
const options = {...} // Contoh
// 3 cara mengirim pesan:
// 1) Dengan bot.sendMessage()
await bot.sendMessage(TARGET_ID, "string untuk pesan teks")
await bot.sendMessage(TARGET_ID, options) // lebih banyak opsi pengiriman
// 2) Dengan message.reply()
await message.reply("string untuk pesan teks")
await message.reply(options) // lebih banyak opsi pengiriman
// 3) Me-return value (sama dengan message.reply)
return "string untuk pesan teks"
return options // lebih banyak opsi pengiriman
})
```
Event-event lain:
```js
// Ketika Wachan berhasil tersambung (diproses SEBELUM memproses pesan offline)
bot.onConnected(async () => {
await bot.sendText(targetId, "Wachan sudah terhubung!")
})
// Ketika Wachan sudah siap (diproses SETELAH memproses pesan offline)
bot.onReady(async () => {
await bot.sendText(targetId, "Selesai membaca semua pesan offline!")
})
```
Menjalankan bot:
```js
bot.start()
```
## File Pengaturan
### Pengaturan Awal
Saat pertama bot dijalankan, file pengaturan awal akan dibuat jika tidak ada.
```json
{
"receiveOfflineMessages": true,
"defaultBotName": "Wachan"
}
```
Pengaturan ini bisa diubah ketika bot berjalan dengan cara mengakses `bot.settings`. Untuk menyimpan perubahan supaya tetap berlaku ketika bot dijalankan berikutnya, gunakan `bot.settings.save()`.
#### Penjelasan tiap item di pengaturan:
- `receiveOfflineMessages`: Jika `true`, maka akan memproses pesan offline (pesan yang masuk ketika bot sedang off). Pesan yang dimaksud adalah yang dituliskan pada `bot.onReceive`.
- `defaultBotName`: Nama ini akan digunakan jika pesan bot sendiri tidak memiliki `message.sender.name`
## Objek Bot
Ini objek-objek yang di-export oleh wachan:<br><br>
`bot`: Objek bot wachan
- `bot.onConnected(callback)` - Menambahkan function yang akan dijalankan ketika wachan berhasil terkoneksi ke whatsapp, <b>sebelum</b> memproses pesan offline.
- `bot.onReady(callback)` - Menambahkan function yang akan dijalankan ketika bot sudah siap. Dijalankan <b>setelah</b> memproses pesan offline.
- `bot.onReceive(input, response)` - Menambahkan receiver (penerima pesan) yang akan merespon ke pesan yg ditentukan oleh input.
- `input`: bisa berupa string, regex, function, atau enum.
- string: akan mencocokkan teks yang persis pada isi pesan
- regex: akan mencocokkan pola teks pada isi pesan
- function, `input(message)`: akan memfilter pesan berdasarkan value yang di-return
- enum: cek `bot.messageType` untuk tipe-tipe yang ada:
`any`, `nonmedia`, `media`, `text`, `reaction`, `image`, `video`, `gif`, `audio`, `sticker`, `document`
- `response`: bisa berupa string, object, atau function.
- string: balas (dan meng-quote) pesan yang diterima dengan teks
- object: balas (dan meng-quote) pesan yang diterima dengan data dari object-nya. Lihat [di sini](#opsi-pengiriman-pesan)
- function: `response(context, next)`, jalankan fungsi. [Penjelasan](#function-response)
- me-return: sebuah objek `Receiver`. Receiver ini bisa dihapus dengan cara `receiver.remove()` untuk menghentikan respon yg dilakukannya.
- `bot.onReceiveReply(message, response)` - Menambahkan receiver yang akan merespon ke pesan yang mereply pesan yang diset di parameter `message`, atau ke pesan manapun jika parameter `message` tidak diset.
- `bot.onError(response)` - Tambahkan fungsi yang akan dieksekusi ketika error.
- `response` - Fungsi yang akan dijalankan, `response(error, context)`.
- `error` - Objek error.
- `context` - Objek yang berisi argument-argument dari fungsi respon:
- `message`
- `captures`
- `groupChat` (deprecated. gunakan `bot.getGroupData(id)`)
- `bot.waitForMessage(input, timeout)` - Menunggu munculnya pesan masuk sesuai input lalu me-return pesan tersebut.
- `input`: Sama seperti `input` di `bot.onReceive()` di atas.
- `timeout`: Batas waktu tunggu. Jika tidak ditemukan pesan dan waktu habis, `waitForMessage()` akan me-return `undefined`.
- `bot.sendMessage(targetId, optionsa)` - Kirim pesan
- `targetId` - ID chatroom tujuan
- `options` - bisa berupa string / object
- string: kirim pesan teks ini
- object: lebih banyak opsi pengiriman. Lihat di [sini](#opsi-pengiriman-pesan)
- `bot.showTyping(targetId)` - Tampilkan mode "typing" di suatu id chat
- `bot.showRecording(targetId)` - Show the "recording" di suatu id chat
- `bot.getGroupData(jid)` - Dapatkan informasi tentang grup.
- `bot.getUserData(id)` - Dapatkan data dari user dari JID / LID nya, jika bot sudah menyimpannya.
- `bot.getBotData()` - Dapatkan data bot (id, lid, nama)
- `bot.start(options)` - Jalankan bot. Options:
- `suppressBaileysLog` - Default `true`. Jika `true`, maka senyapkan log baileys di console.
- `phoneNumber` - String berisi nomor telepon (dengan kode negara, tanpa simbol dan spasi) untuk langsung menghubungkan ke nomor tersebut tanpa perlu diinput lagi di console.
- `configOverrides` - Objek config untuk meng-override (mengganti) konfigurasi pada fungsi makeWASocket dari baileys
- `bot.settings` - Pengaturan bot. Cek [di sini](#penjelasan-tiap-item-di-pengaturan)
- `bot.settings.receiveOfflineMessages`
- `bot.settings.defaultBotName`
- `bot.settings.save()` - Simpan pengaturan. Perlu dilakukan setelah memodifikasi settings di dalam program.
- `bot.getSocket()` - Ambil objek socket baileys.
- `bot.messageType` - Berisi enum untuk filter di receiver. Lihat di [sini](#enum-tipe-message)
## Fungsi Respon
Kamu bisa gunakan fungsi sebagai respon. Argument pertama adalah `context` dan kedua adalah fungsi `next` (cek [Alur Receiver](#alur-receiver)).
<br><br>Sebelumnya, argumen pertama adalah `message`, kedua adalah `captures` (jika ada), ketiga `group` (jika chat roomnya berupa grup chat), dan terakhir fungsi `next`. (Ini sudah deprecated. Kedepannya `message`, `captures`, dan `group` akan masuk ke dalam `context`).
```js
bot.onReceive("test", async function (context, next) {
// const { message, captures, group } = context
})
```
### Objek Pesan (Message)
`message`: Objek pesan Wachan
- `message.id` - ID dari objek pesan ini
- `message.room` - ID dari chatroom
- `message.isPrivate` - Apakah pesan ini adalah pesan pribadi (private message)
- `message.sender` - Objek pengirim (sender)
- `message.sender.id` - ID pengirim (berupa format `nomor-telepon@s.whatsapp.net`)
- `message.sender.lid` - LID pengirim (id tersembunyi untuk tiap user Whatsapp, dalam format `nomoracak@lid`)
- `message.sender.isMe` - `true` jika pengirimnya adalah bot sendiri
- `message.sender.name` - Username pengirim
- `message.sender.isAdmin` - `true`/`false` jika si pengirim adalah admin/bukan admin. `null` jika pesan ini pesan pribadi. (bukan di dalam grup)
- `message.timestamp` - Timestamp dari pesan ini dalam format Unix Timestamp.
- `message.type` - Jenis dari pesan ini. Bisa berupa: `"text"`, `"image"`, `"video"`, `"gif"`, `"audio"`, `"vn"`, `"sticker"`, `"document"`, `"reaction"`, `"buttons"`, `"buttonReply"`, `"contacts"`, `"poll"`, atau `"vote"`
- `message.isMedia` - `true` jika pesan ini adalah pesan media (type = `"image"`, `"video"`, `"gif"`, `"audio"`, `"vn"`, `"sticker"`, atau `"document"`)
- `message.downloadMedia(saveTo)` - Download media sebagai buffer. Jika path disediakan di parameter `saveTo`, maka filenya akan disimpan di situ.
- `message.streamMedia()` - Ambil objek stream dari media.
- `message.mimeType` - Mimetype dari pesan media.
- `message.fileName` - Nama file dari pesan dokumen.
- `message.fileSize` - Ukuran file dari pesan media. (dalam byte)
- `message.duration` - Durasi audio dan video (dalam detik)
- `message.width` - Lebar video
- `message.height` - Tinggi video
- `message.text` - Teks atau caption dari pesan
- `message.reaction` - Informasi tentang reaction, jika ini adalah pesan reaction
- `message.reaction.emoji` - Emoji yang digunakan
- `message.reaction.key` - Objek key dari pesan yang di-react
- `message.buttons` - Objek button. Sama seperti property `buttons` yang dibuat ketika mengirim pesan button ([cek di sini](#opsi-pengiriman-pesan))
- `message.title` - Judul pesan untuk pesan buttons
- `message.footer` - Footer pesan untuk pesan buttons
- `message.buttonReply` - Informasi tentang button yang diketuk
- `message.buttonReply.id` - ID yang diberikan ke button
- `message.buttonReply.text` - Teks yang tertulis di atas button
- `message.buttonReply.pos` - Posisi button (yang pertama adalah 0)
- `message.poll` - Informasi polling, jika ini adalah pesan polling
- `message.poll.title` - Judul polling
- `message.poll.options` - List opsi polling dalam array
- `message.poll.multiple` - `true` jika di polling ini bisa memilih lebih dari satu opsi
- `message.poll.votes` - Objek berisi opsi vote dan id dari voter-voter nya. Contoh: `{"opsi1":["1234@lid", "2345@lid"]}`
- `message.vote` - Informasi tentang perubahan polling (pengirim pesan melakukan voting/unvoting)
- `message.vote.pollId` - ID dari pesan polling nya
- `message.vote.list` - List opsi yang menjadi pilihan. Bisa juga berupa array kosong karena hasil dari unvoting.
- `message.contacts[]` - List kontak yang dikirim jika ini adalah pesan kontak
- `contact.name` - Nama kontak
- `contact.number` - Nomor telepon kontak
- `message.receivedOnline` - `true` jika pesan ini diterima ketika bot sedang online
- `message.edited` - Jika pesan ini diedit
- `message.edited.type` - Tipe pesan ini
- `message.edited.text` - Teks yang tertulis setelah diedit
- `message.reply(options)` - Balas ke pesan.
- `options` - Bisa berupa string / object
- string: balas dengan teks ini
- object: lebih banyak opsi pengiriman. Lihat di [sini](#opsi-pengiriman-pesan)
- `message.edit(newText)` - Edit teks dari pesan (hanya untuk pesan bot sendiri, dan jika masih bisa diedit, yaitu sebelum 15 menit setelah terkirim)
- `message.react(emoji)` - Kirim reaction ke pesan ini
- `emoji` - String berisi 1 emoji untuk dijadikan reaction. Gunakan string kosong untuk menghapus reaction.
- `message.delete()` - Hapus pesan ini. Note: Bot harus menjadi admin sebelum menghapus pesan-pesan yang ada di grup.
- `message.getQuoted()` - Me-return pesan yang di-quote oleh pesan ini. `null` jika tidak ada.
- `message.toBaileys()` - Me-return objek message asli dari modul baileys
### Captures
`captures` yaitu objek <b>(bukan array)</b> yang berisi string teks-teks yang diambil (di-capture) dengan regex. Jika tidak ada, maka objek-nya kosong.
Key dari objek nya tergantung pada regex-nya. Jika menggunakan capturing biasa dengan tanda kurung, maka hasilnya tersimpan pada key berupa angka (mulai dari 0). Jika menggunakan <i>named capture</i>, maka key-nya berupa string.
Regex Input|Teks yg diterima|Objek `captures`
-|-|-
`/Nama saya (\S+)\. Saya tinggal di (\S+)\./` | `"Nama saya Wachan. Saya tinggal di NPM.` | `{"0":"Wachan", "1":"NPM"}`
`/Nama saya (?<nama>\S+)\. Saya tinggal di (?<lokasi>\S+)\./` | `"Nama saya Wachan. Saya tinggal di NPM.` | `{"nama":"Wachan", "lokasi":"NPM"}`
<hr>
`captures.toArray()` bisa digunakan untuk mengubah objek `captures` ke array (agar bisa melakukan operasi array)
### Group
Argumentt kedua adalah `group`, objek yang berisi informasi tentang grup. Nilainya `null` jika pesan dikirim ke pesan pribadi. (Sudah deprecated sebagai argument ketiga dari response function, dan akan masuk ke dalam objek `context`).
Kamu bisa juga gunakan `bot.getGroupData(id)` untuk mendapatkan data grup lain.
### Value Yang Di-Return
Di dalam function response, kamu bisa me-return string/object:
- string: Membalas pesan yg diterima dengan teks ini.<br>Contoh:
```js
bot.onReceive("test", async () => {
const a = "bro"
return `Hello, ${a}!`
})
bot.onReceive("test", async ({msg}) => `Hello, ${msg.sender.name}!`)
```
- object: Bisa ditambahkan opsi lain.<br>Contoh:
```js
bot.onReceive("test", async () => {
return {text: "Text"}
})
```
## Opsi Pengiriman Pesan
Kesimpulannya, ada 4 cara mengirim pesan:
1. Menggunakan `bot.sendMessage(targetId, options)`
2. Menggunakan object di parameter kedua function `bot.onReceive(input, response)`, yaitu `response`.
3. Menggunakan `message.reply(options)`
4. Me-return object di dalam function response
Jika object-nya adalah string, maka pesan akan dikirim dalam bentuk teks. Tetapi jika berupa object dengan property-property di dalamnya, maka struktur object yang di-support adalah seperti berikut:
- `options` - Opsi pengiriman pesan
- `options.text` - Text/caption yang akan dikirim
- `options.quoted` - Pesan yang akan di-quote. Secara otomatis di-set ke pesan yang diterima (jika menggunakan cara 2, 3, 4). Bisa diganti maupun di-set ke `null`.
- `options.image` - Gambar yang akan dikirim. Bisa berupa buffer, url, path, maupun stream.
- `options.video` - Video yang akan dikirim. Bisa berupa buffer, url, path, maupun stream.
- `options.gif` - Video yang akan dikirim sebagai GIF. Bisa berupa buffer, url, path, maupun stream. (Whatsapp tidak support file GIF, jika kamu menggunakan file GIF, maka tidak akan bergerak gambarnya)
- `options.audio` - Audio yang akan dikirim. Bisa berupa buffer, url, path, maupun stream.
- `options.vn` - Audio yang akan dikirim sebagai Voice Note.
- `options.sticker` - File WebP yang akan dikirim sebagai stiker (buffer/url/path/stream)
- `options.document` - File yang akan dikirim sebagai pesan document. Pengaturan tambahan:
- `options.mimetype` - Mimetype dari file ini.
- `options.fileName` - Nama file yang ditampilkan untuk pesan document ini.
- `options.buttons[]` - Array berisi button (tombol-tombol). Setiap button memiliki property berikut.
- `button.type` - Jenis button: `reply`, `list`, `url`, `copy`, `call`.
- `button.text` - Teks button. Wajib untuk button jenis `reply`, `url`, `copy`, dan `call`.
- `button.id` - ID button. Wajib untuk button jenis `reply`.
- `button.url` - URL yang akan dikunjungi ketika button diketuk. Wajib untuk button jenis `url`.
- `button.code` - Kode yang akan dicopy ke keyboard ketika button diketuk. Wajib untuk button jenis `copy`.
- `button.phoneNumber` - Nomor yang akan dihubungi ketika button diketuk. Wajib untuk button jenis `call`.
- `button.title` - Judul menu list yang dimunculkan dari button jenis `list`.
- `button.sections[]` - Array berisi section dari menu list. Wajib untuk button jenis `list`. Setiap elemennya adalah objek `section`:
- `section.title` - Judul section
- `section.rows[]` - Array dari list item. Wajib ada di dalam section. Setiap elemennya adalah objek `row`:
- `row.id` - ID dari item. Wajib ada.
- `row.title` - Judul dari item. Wajib ada.
- `row.description` - Deskripsi item.
- `row.header` - Teks header dari item.
- `options.title` - Judul untuk pesan yang ber-button.
- `options.footer` - Tulisan kaki (footer) untuk pesan yang ber-button.
- `options.contacts[]` - Array berisi kontak. Tiap elemennya adalah objek `contact`:
- `contact.name` - Nama kontak yang ditampilkan.
- `contact.number` - Nomor kontak dalam string.
- `options.poll` - Objek poll untuk mengirim polling
- `options.poll.options[]` - Array berisi string dari opsi-opsi polling
- `options.poll.title` - Judul dari polling
- `options.poll.multiple` - Jika true, maka bisa memilih lebih dari 1 opsi
<b>Catatan:</b> Karena `bot.sendMessage()` dan `message.reply()` normalnya me-return sebuah object message yang berisi property `text`, jadi me-return hasil dari function-function tersebut bisa membuat bot mengirim pesan 2 kali:
```js
bot.onReceive("test", async (msg) => {
// ini akan mengirim 2 pesan
// 1. dari efek msg.reply()
// 2. dari hasil me-return message yg dibuat dari msg.reply()
return await msg.reply("ok")
})
```
### Mention User
Untuk me-mention user, kamu bisa tambahkan `@<user-lid>` di dalam teks pesanmu (tanpa `@lid`). Contoh: `msg.reply("Halo @1234567812345")`
### Data Grup
Untuk mengambil data grup, gunakan `bot.getGroupData(id)`. Mereturn berikut, jika ada:
- `group`
- `group.id` - ID grup
- `group.subject` - Subject (judul) grup
- `group.description` - Deskripsi grup
- `group.getParticipants()` - Ambil list peserta grup berupa array berisi objek-objek dengan struktur berikut:
- `participant`
- `participant.id` - ID peserta. Bisa berupa JID atau LID
- `participant.lid` - LID peserta
- `group.getAdmins()` - Ambil list khusus admin grup
- `group.getMembers()` - Ambil list khusus member (bukan admin)
- `group.getLink()` - Ambil link grup. Error jika link tidak dapat diakses oleh bot (sebagai non admin).
## Alur Receiver
Receiver diperiksa satu per satu menurut urutan ia di-register. Jika dua receiver bisa di-trigger oleh satu pesan yang sama, maka hanya receiver pertama yang akan dieksekusi.
```js
// Kedua receiver ini bisa di-trigger oleh pesan yang bertuliskan "tes123" tapi hanya yang pertama yang akan merespon
bot.onReceive("tes123", "Ini akan dikirimkan.")
bot.onReceive(/^tes/, "Ini tidak akan dikirimkan.")
```
Di dalam fungsi respon, kamu bisa lanjutkan alurnya ke receiver berikutnya dengan fungsi `next()` yang ada di parameter ke-4 (sudah deprecated sebagai argument ke-4, sekarang sudah jadi argument ke-2):
```js
bot.onReceive(/.*/, (ctx, next) => {
if (userAuthorized(ctx.message.sender.id)) next()
return "Kamu tidak punya akses!"
})
bot.onReceive("test", "Halo silakan masuk!")
```
### Memodifikasi Message
Objek `message` yang diteruskan ke fungsi respon adalah objek yang sama. Maka dari itu kamu bisa memodifikasi `message` ini dan perubahannya akan terlihat di fungsi-fungsi respon berikutnya.
```js
bot.onReceive(bot.messageType.any, ({message}, next) => {
message.watermark = "MyBot"
next()
})
bot.onReceive("test", ({message}) => {
return `Brought to you by ${message.watermark}`
})
```
## Enum Tipe Message
`bot.messageType` mempunyai enum-enum berikut:
- `any`: Ini sama seperti regex `/.*/` di dalam input receiver.
- `nonmedia`: Ini termasuk pesan `text` dan `reaction`.
- `media`: Ini termasuk `image`, `video`, `gif`, `audio`, `sticker` dan `document`.
- Lainnya: `text`, `reaction`, `image`, `video`, `gif`, `audio`, `sticker`, `document`.
## Tools
Kamu bisa import tools Yang berguna di berbagai skenario.
### Commands Tool `require("wachan/commands")`
Berguna untuk membuat command (perintah) yang berformat prefix-command-param yang populer di kalangan developer bot whatsapp. Contoh: `/search article`
<br>
Meng-export: `commands`
- `commands` - Commands Tool. Ketika diimport, akan otomatis menambah satu item pengaturan baru, `bot.settings.commandPrefixes`, yaitu array dari prefix-prefix yang bisa digunakan untuk menjalankan command.
- `commands.add(name, response, options)` - Tambah command baru
- `name` - Nama command-nya
- `response` - String/Object/Function
- sebagai string: Balas ke pesan command dengan teks
- sebagai object: Lebih banyak opsi pengiriman. [Cek di sini](#opsi-pengiriman-pesan)
- sebagai function: `response(context, next)`. [Cek di sini](#fungsi-respon). Dengan tambahan property di dalam `context` yaitu `command`.
- `context`
- `context.message` - Objek pesan
- `context.command` - Informasi command
- `context.command.prefix` - Prefix yang digunakan
- `context.command.name` - Nama command asalnya
- `context.command.usedName` - Nama command atau alias yang dipakai ketika menjalankan command
- `context.command.parameters` - Parameter command (dalam Array). Contoh: `/test a b c` -> params = ["a","b","c"]
- `context.command.description` - Deskripsi command
- `context.command.aliases` - Alias dari command ini (array)
- `context.command.hidden` - Apakah ini termasuk command yang disembunyikan dari menu generator
- dan property custom lain yang diset ketika membuat command tsb., yang ada di dalam `options`
- `next` - Function untuk berpindah ke receiver berikutnya. (Lihat [Alur Receiver](#alur-receiver))
- sebagai function (susunan sebelumnya, sudah deprecated): `response(message, params, command, prefix, group, bot)`
- `message` - Pesan perintah
- `params` - Parameter. Contoh: `/test a b c` -> params = ["a","b","c"]
- `command` - Nama command yang digunakan.
- `prefix` - Prefix yang digunakan
- `group` - Info tentang grup dimana perintah ini dijalankan
- `bot` - Objek bot yang sama dengan export utama wachan
- `options` - Opsi tambahan untuk command ini. Kamu bisa berikan data-data custom di dalam sini. Untuk data bawaannya yaitu sbb:
- `options.aliases` - Array alias untuk alternatif perintah
- `options.separator` - Karakter yang akan digunakan sebagai pemotong string parameter. Default spasi (`" "`)
- `options.description` - Deskripsi command
- `options.sectionName` - Nama section dari command ini. Ini digunakan untuk men-generate menu. (lihat di bawah di bagian `commands.generateMenu()`)
- `options.hidden` - Command ini tidak akan ditampilkan di menu dari hasil `commands.generateMenu()`
- `commands.fromFile(commandName, filePath)` - Tambah command baru dari file. File-nya harus berekstensi `.js` dan dari file tersebut di-export objek `cmdFile` dengan struktur seperti berikut:
- `cmdFile.response` - Mirip dengan parameter `response` pada `commands.add()`. Lihat di atas.
- `cmdFile.options` - Opsional. Mirip dengan parameter `options` pada `commands.add()`. Lihat di atas.
- `commands.addPrefix(prefix)` - Menambahkan prefix
- `commands.removePrefix(prefix)` - Menghapus salah satu prefix yang ada.
- `commands.getCommandInfo(commandName)` - Ambil info tentang suatu command yang sudah terdaftar.
- `commands.getCommands()` - Ambil info semua command yang sudah terdaftar.
- `commands.beforeEach(callback)` - Tambahkan callback yang akan dijalankan sebelum masuk ke setiap command. Ini berguna misalnya untuk otorisasi (contoh pengecekan owner/admin)
- `callback(context, next)` - Callback yang akan ditambahkan
- `context` - Sama seperti `context` saat menambahkan command baru dengan `commands.add()`
- `next` - Fungsi untuk melanjutkan ke callback berikutnya, atau masuk ke command jika sudah tidak ada lagi callback.
- `commands.generateMenu(options)` - Generate sebuah string berisi menu perintah yang otomatis berisi list perintah dan dikelompokkan berdasarkan section-nya. Opsi Generation:
- `options?.prefix` - Prefix yang akan ditampilkan. Secara default, prefix pertama di daftar prefix.
- `options?.header` - Judul menu. Catatan: Kamu perlu menambahkan newlines (`\n`) secara manual di ujunnya jika ingin memisahkan judul dan isi di baris berbeda. Secara default: `"> COMMAND LIST:\n\n"`
- `options?.sectionTitleFormat` - Gunakan ini untuk formatting judul tiap section. Gunakan `<<section>>` untuk menandai posisi teks nama section. Secara default: `"# <<section>>\n"` (Sama seperti tadi, tambahkan newline secara manual)
- `options?.sectionFooter` - Footer (bagian bawah/penutup) dari tiap section. Sekali lagi, newline perlu ditambahkan secara manual tetapi di awal. (Contoh: `"\n------"`). Secara default: `""` (string kosong)
- `options?.commandFormat` - Formatting dari setiap butir command. Gunakan `<<prefix>>`, `<<name>>`, dan `<<description>>` untuk menandai posisi prefix, nama command, dan deskripsi command. Secara default: ``"- `<<prefix>><<name>>`: <<description>>"``
- `options?.formatter` - Fungsi Formatter yang akan dipakai use, memerlukan 1 argument berisi informasi soal perintahnya. Jika fungsi ini mereturn falsy, maka `options.commandFormat` akan digunakan.
- `options?.commandSeparator` - Pemisah tiap item command. Secara default: `"\n"` (newline)
- `options?.sectionSeparator` - Pemisah antar section. Secara default: `"\n\n"`
- `options?.unsectionedFirst` - Jika `true` akan menampilkan command tanpa section lebih dulu, setelah itu command yang ada sectionnya. Jika `false` maka sebaliknya.
- `options?.noDescriptionPlaceholder` - String yang akan digunakan jika command tidak punya deskripsi.
Ini contoh string yang digenerate jika menggunakan formatting default:
```
> COMMAND LIST:
# Section A
- `/cmd1`: Description of the command.
- `/hello`: Say hello.
- `/wachan`: Awesome module.
# Section B
- `/this`: Is an example
- `/you`: Can imagine what it looks like in Whatsapp, I suppose.
- `/nodesc`: No description
```
Contoh Penggunaan:
```js
const cmd = require("wachan/commands")
cmd.add("multiply", function (context, next) {
// Susunan parameter lama: (msg, params)
const [a, b] = context.command.parameters
const result = Number(a) * Number(b)
return `The result of ${a}*${b} is ${result}`
})
// Akan merespon ketika ada yang mengetik:
// /multiply 4 5
// Bot akan mengalikan 4 and 5 lalu mengirimkan hasilnya di chat.
```
Contoh penggunaan `beforeEach()`:
```js
const cmd = require("wachan/commands")
cmd.beforeEach((context, next) => {
const { adminOnly } = context.command
const { isAdmin } = context.message.sender
if (adminOnly && !isAdmin) return `Hanya admin yang bisa menggunakan command ini!`
next()
})
cmd.add("special", async (context, next) {
return "Special command sudah dieksekusi!"
}, { adminOnly: true })
// Ketika user mengetik /special, maka akan dicek dulu apakah dia admin, jika tidak maka ditolak
```
### Sticker Tool `require("wachan/sticker")`
Kamu bisa gunakan ini untuk membuat sticker WebP yang siap pakai di WhatsApp.
<br>Exports: `sticker`
<br><br>`sticker` - Sticker tool
- `sticker.create(input, options)` - Buat stiker WebP dari input.
- `input` - Bisa string URL atau path, atau buffer gambar/video
- `options` - Opsi tambahan
- `options.pack` - Nama pack dari stiker ini. Bisa dilihat di bagian bawah jendela preview stiker di WhatsApp.
- `options.author` - Nama author dari stiker ini. Bisa dilihat di bagian bawah jendela preview stiker di WhatsApp.
- `options.size` - Panjang sisi stiker (lebar atau tingginya). Default 128 untuk video, dan 512 untuk selain video. Ini mempengaruhi ukuran stiker. Di Whatsapp ukuran stiker maksimum adalah 1MB.
- `options.mode` - Mode bagaimana gambar dimuat:
- `"crop"` - Crop / potong pinggir stiker sehingga menjadi persegi.
- `"fit"` - Tarik atau rapatkan stiker sehingga muat menjadi persegi.
- `"all"` - Tidak ada perubahan, muat semua bagian gambar dengan cara zoom out.
Contoh:
```js
const st = require("wachan/sticker")
const input = "url atau path gambar" // atau buffer
const sticker = await st.create(input, {
pack: "My stickers",
author: "Me",
mode: "crop"
})
await bot.sendMessage(targetRoom, { sticker })
```
## Custom Programming
Kamu bisa akses item-item ini untuk memprogram fungsi tambahan sendiri.
1. Objek socket milik baileys: `bot.getSocket()`
2. Objek pesan milik baileys: `message.toBaileys()`
3. `bot.start({ suppressBaileysLogs: false })` untuk menampilkan logs dari baileys di console
4. `bot.start({ configOverrides: {...} })` untuk meng-override (mengganti) konfigurasi pada baileys (parameter di fungsi makeWASocket)
<hr>
<br>
<br>
# Changelog
## [Belum Rilis]
### Ditambahkan
- `bot.showTyping()`
- `bot.showRecording()`
- `group.getLink()`
### Diubah
- Update ke baileys v7.0.0-rc12
## [1.15.0] 2026-02-08
### Ditambahkan
- `bot.getBotData()`
- `message.isPrivate`
- `message.streamMedia()`
- Kirim pesan media menggunakan objek stream
- Argument `context` pada fungsi respon sekarang berisi `group`
### Diperbaiki
- Koreksi id dan lid pada group participant
## [1.14.0] 2026-01-16
### Ditambahkan
- `message.fileName`
- `message.mimeType`
- `message.fileSize`
- `message.duration`
- `message.height`
- `message.width`
- `message.streamMedia()`
- `options.formatter` dari `commands.generateMenu(options)`
### Diperbaiki
- Hapus dependency: `ffmpeg-static`
## [1.13.0] 2026-01-02
### Ditambahkan
- `context.command.usedName`
- `bot.messageType.vn`
- tipe pesan `audio` dan `vn` dipisah
- `message.edit()`
- `bot.messageType.edit`
- `message.edited.type`
- `message.edited.text`
- `bot.onReceiveReply()`
### Diperbaiki
- `message.sender.id` dan `message.sender.lid` yang isinya tidak tepat
## [1.12.1] 2025-12-30
### Diubah
- Update versi baileys
## [1.12.0] 2025-12-14
### Ditambahkan
- `bot.getUserData()`
- `cmd.beforeEach()`
- Mengirim dan menerima kontak
- Mengirim dan menerima polling
- `options.configOverrides` pada parameter fungsi `start()`
### Diperbaiki
- Status admin dari user akan terupdate tanpa harus program direstart dulu
- Sekarang bisa menghapus reaction dengan menggunakan string kosong
### Akan Dihilangkan
- Parameter dari fungsi respon akan disederhanakan menjadi 2: `context` dan `next`. Ini juga akan berlaku untuk fungsi respon dari command.
## [1.11.0] 2025-11-09
### Ditambahkan
- `bot.getGroupData(jid)`
- `bot.messageType`
- `bot.onError()`
- Opsi `phoneNumber` di dalam `bot.start(option)`
- Jenis message baru `buttons`
- Argumen ke-4 di dalam fungsi respon, `next`
- `message.id`
- `message.delete()`
- `message.getQuoted()` sekarang sudah tersedia juga di message tanpa quoted, tetapi akan mereturn `null`
- `commands.getCommands()`
- Field baru `size` pada options di `sticker.create()`
## [1.10.0] - 2025-10-26
### Ditambahkan
- `message.react()`
- Tambah Sticker Tool: `require("wachan/sticker")`
- Argument ketiga di dalam fungsi respon, `group`
- Argument kelima dan keenam di dalam fungsi respon untuk command, `group` dan `bot`
- Opsi baru untuk registrasi command: `options.hidden`
### Diperbaiki
- Fix `message.downloadMedia(saveTo)` error jika menyediakan path file yang tidak ada
## [1.9.0] - 2025-10-19
### Ditambahkan
#### Tool Commands (`require("wachan/commands")`)
- Tambah `commands.fromFile()` dan `commands.fromFolder()`
- Tambah `commands.getCommandInfo()` dan `commands.generateMenu()`
## [1.8.0] - 2025-09-08
### Ditambahkan
- Tambah fitur Message Store. Ini akan menyimpan sementara pesan yang diterima. Bisa diatur batas penyimpanannya di settings. Penyimpanan ini berguna untuk memperbaiki beberapa bug yang memerlukan untuk pesan dipanggil kembali.
- Tambah pengaturan `bot.settings.messageStoreSize` (default: 1000)
- Tambah fitur `bot.waitForMessage()`
- Tambah fitur `message.timestamp`
- Tambah fitur `message.sender.lid`
- Tambah fitur `message.getQuoted()`
- Tambah tool Commands `require("wachan/commands")`
### Diperbaiki
- Update Baileys ke versi `6.7.19`
- `message.receivedOnline` sekarang sudah bisa bernilai `false`
## [1.7.0] - 2025-08-23
### Ditambahkan
- Support pesan sticker
- Support pesan document
- `bot.onReceive()` sekarang me-return objek `Receiver`.
- Objek `Receiver` yang dibuat dari `bot.onReceive()` bisa dihapus dengan method `.remove()`.
### Diperbaiki
- Mengirim ke id @lid tidak lagi menyebabkan error
## [1.6.0] - 2025-08-12
### Ditambahkan
- Support pesan video
- Support pesan gif
- Support pesan audio