sauruspro-bail 5.0.2 β 5.0.3
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 +318 -0
- package/docs/CHANGELOG.md +32 -43
- package/lib/Socket/socket.js +80 -51
- package/lib/index.js +14 -4
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# π¦ SAURUSPRO BAILEYS
|
|
4
|
+
|
|
5
|
+
**WhatsApp Web API untuk Node.js, lengkap dengan Rich Message, SPR, dan Newsletter Status**
|
|
6
|
+
|
|
7
|
+
<img src="https://cdn.saurus.qzz.io/image/EGYoX.png" width="140" alt="Sauruspro">
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+

|
|
11
|
+

|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## π Apa itu Baileys?
|
|
19
|
+
|
|
20
|
+
**Baileys** adalah library JavaScript/TypeScript yang berbicara langsung dengan server WhatsApp lewat **WebSocket**, sama seperti WhatsApp Web, tetapi **tanpa browser** dan tanpa Selenium/Puppeteer. Dengan Baileys kamu bisa membuat bot atau aplikasi yang:
|
|
21
|
+
|
|
22
|
+
- login sebagai *linked device* (perangkat tertaut) lewat **QR** atau **pairing code**,
|
|
23
|
+
- mengirim dan menerima pesan (teks, gambar, video, stiker, poll, dll),
|
|
24
|
+
- mengelola grup, komunitas, channel (newsletter), dan profil,
|
|
25
|
+
- berjalan ringan karena hanya memakai protokol multi-device, bukan emulasi browser.
|
|
26
|
+
|
|
27
|
+
**Sauruspro Baileys (`sauruspro-bail`)** adalah turunan Baileys dengan fitur tambahan:
|
|
28
|
+
|
|
29
|
+
| Fitur | Isi |
|
|
30
|
+
|---|---|
|
|
31
|
+
| π¬ **Rich Message** | `AIRich`, Carousel, Button, Native Flow, A2UI |
|
|
32
|
+
| π― **SPR (Selective Relay)** | Kirim pesan hanya ke device tertentu, pesan khusus per orang |
|
|
33
|
+
| π’ **Newsletter Status** | Kirim, react, hapus, dan ambil status Channel |
|
|
34
|
+
| πͺͺ **Greeting Card `/buss`** | Kartu sapaan untuk WhatsApp Business |
|
|
35
|
+
| π§© **Plugin system** | `sock.use(plugin)` dan fitur bawaan bisa dimatikan |
|
|
36
|
+
| π€ **Presence & Profile API** | `sock.presence.*` dan `sock.profile.*` yang lebih rapi |
|
|
37
|
+
| β‘ **Native crypto (opsional)** | X25519 dan XEdDSA lebih cepat jika `@zapo-js/native` terpasang |
|
|
38
|
+
|
|
39
|
+
> Beberapa fitur diadaptasi dari [zapo-js](https://github.com/vinikjkkj/zapo) (MIT).
|
|
40
|
+
|
|
41
|
+
## π¦ Info Paket
|
|
42
|
+
|
|
43
|
+
| | |
|
|
44
|
+
|---|---|
|
|
45
|
+
| Nama | `sauruspro-bail` |
|
|
46
|
+
| Modul | ESM (`"type": "module"`), bisa dipakai dari CommonJS (lihat di bawah) |
|
|
47
|
+
| Node.js | >= 20 |
|
|
48
|
+
| Telegram | [@lordsaurus](https://t.me/lordsaurus) |
|
|
49
|
+
|
|
50
|
+
## π Install
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install sauruspro-bail
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## π Menghubungkan ke WhatsApp (bot)
|
|
59
|
+
|
|
60
|
+
Ada dua cara login: **QR code** atau **pairing code** (kode 8 karakter yang dimasukkan di HP). Sesi disimpan di folder, jadi login hanya perlu sekali.
|
|
61
|
+
|
|
62
|
+
### Contoh lengkap (pairing code + reconnect)
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
import makeWASocket, {
|
|
66
|
+
useMultiFileAuthState,
|
|
67
|
+
DisconnectReason,
|
|
68
|
+
Browsers
|
|
69
|
+
} from 'sauruspro-bail'
|
|
70
|
+
|
|
71
|
+
const NOMOR = '628123456789' // format internasional, tanpa +, spasi, atau strip
|
|
72
|
+
|
|
73
|
+
async function start() {
|
|
74
|
+
const { state, saveCreds } = await useMultiFileAuthState('session')
|
|
75
|
+
|
|
76
|
+
const sock = makeWASocket({
|
|
77
|
+
auth: state,
|
|
78
|
+
browser: Browsers.ubuntu('Chrome') // dianjurkan untuk pairing code
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
// simpan kredensial setiap kali berubah
|
|
82
|
+
sock.ev.on('creds.update', saveCreds)
|
|
83
|
+
|
|
84
|
+
// minta pairing code hanya jika belum login
|
|
85
|
+
if (!sock.authState.creds.registered) {
|
|
86
|
+
const code = await sock.requestPairingCode(NOMOR)
|
|
87
|
+
console.log('Pairing code:', code.match(/.{1,4}/g).join('-'))
|
|
88
|
+
// HP: WhatsApp > Perangkat tertaut > Tautkan perangkat > Tautkan dengan nomor telepon
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// status koneksi + reconnect otomatis
|
|
92
|
+
sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
|
|
93
|
+
if (connection === 'open') console.log('β
Bot terhubung')
|
|
94
|
+
if (connection === 'close') {
|
|
95
|
+
const status = lastDisconnect?.error?.output?.statusCode
|
|
96
|
+
if (status === DisconnectReason.loggedOut) {
|
|
97
|
+
console.log('Logout. Hapus folder "session" lalu jalankan ulang.')
|
|
98
|
+
} else {
|
|
99
|
+
start() // koneksi putus, sambungkan lagi
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
// contoh membalas pesan
|
|
105
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
106
|
+
const msg = messages[0]
|
|
107
|
+
if (!msg?.message || msg.key.fromMe) return
|
|
108
|
+
const teks = msg.message.conversation || msg.message.extendedTextMessage?.text
|
|
109
|
+
if (teks === 'ping') {
|
|
110
|
+
await sock.sendMessage(msg.key.remoteJid, { text: 'pong' }, { quoted: msg })
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
start()
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Catatan pairing code
|
|
119
|
+
|
|
120
|
+
- Setiap pemanggilan `requestPairingCode` menghasilkan **kode acak baru**. Kamu juga bisa memakai kode sendiri: `requestPairingCode(NOMOR, 'ABCD1234')` (8 karakter, `A-Z` dan `0-9`).
|
|
121
|
+
- Nomor otomatis dibersihkan, jadi `+62 812-3456-789` tetap diterima.
|
|
122
|
+
- Jika sesi sudah login (`registered`), pairing ditolak. Hapus folder sesi untuk login ulang.
|
|
123
|
+
- Kode berlaku singkat. Kalau kedaluwarsa, panggil `requestPairingCode` lagi.
|
|
124
|
+
|
|
125
|
+
### Login dengan QR
|
|
126
|
+
|
|
127
|
+
Dengarkan event `connection.update` dan tampilkan `qr` (misalnya dengan paket `qrcode-terminal`):
|
|
128
|
+
|
|
129
|
+
```js
|
|
130
|
+
sock.ev.on('connection.update', ({ qr }) => {
|
|
131
|
+
if (qr) console.log('Scan QR ini di WhatsApp:', qr)
|
|
132
|
+
})
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Menyimpan sesi di SQLite (opsional)
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
import { useSqliteAuthState } from 'sauruspro-bail'
|
|
139
|
+
const { state, saveCreds } = await useSqliteAuthState('session.db')
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## π Memakai dari CommonJS (`require`)
|
|
145
|
+
|
|
146
|
+
Paket ini ESM. Dari file `.js`/`.cjs` biasa, ada dua cara:
|
|
147
|
+
|
|
148
|
+
**1. `import()` dinamis (semua versi Node 20+, paling aman)**
|
|
149
|
+
|
|
150
|
+
```js
|
|
151
|
+
// index.cjs
|
|
152
|
+
async function main() {
|
|
153
|
+
const { default: makeWASocket, useMultiFileAuthState } = await import('sauruspro-bail')
|
|
154
|
+
|
|
155
|
+
const { state, saveCreds } = await useMultiFileAuthState('session')
|
|
156
|
+
const sock = makeWASocket({ auth: state })
|
|
157
|
+
sock.ev.on('creds.update', saveCreds)
|
|
158
|
+
}
|
|
159
|
+
main()
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**2. `require()` langsung (Node 22.12+ atau Node 20.19+)**
|
|
163
|
+
|
|
164
|
+
```js
|
|
165
|
+
const baileys = require('sauruspro-bail')
|
|
166
|
+
const makeWASocket = baileys.default
|
|
167
|
+
const { useMultiFileAuthState } = baileys
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Pada Node versi lama, `require('sauruspro-bail')` akan error `ERR_REQUIRE_ESM`. Pakai cara pertama.
|
|
171
|
+
|
|
172
|
+
Mau ubah proyekmu jadi ESM saja? Tambahkan `"type": "module"` di `package.json` proyekmu lalu pakai `import`.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## π¬ Rich Message (AIRich)
|
|
177
|
+
|
|
178
|
+
Rich Message adalah balasan bergaya Meta AI: teks, kode, tabel, gambar, dan lainnya dalam satu pesan. Dibuat dengan builder `sock.AIRich`.
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
const rich = new sock.AIRich(sock)
|
|
182
|
+
|
|
183
|
+
rich
|
|
184
|
+
.addText('Halo! Ini **Rich Message** dari Sauruspro.')
|
|
185
|
+
.addCode('javascript', "console.log('halo dunia')")
|
|
186
|
+
.addTable([
|
|
187
|
+
['Fitur', 'Status'],
|
|
188
|
+
['SPR', 'Aktif'],
|
|
189
|
+
['Newsletter Status', 'Aktif']
|
|
190
|
+
])
|
|
191
|
+
|
|
192
|
+
await rich.send(jid)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Cara singkat tanpa builder:
|
|
196
|
+
|
|
197
|
+
```js
|
|
198
|
+
import { sendAIRichMessage } from 'sauruspro-bail'
|
|
199
|
+
|
|
200
|
+
await sendAIRichMessage(sock, jid, { text: 'Halo dari Rich Message!' })
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Builder lain yang tersedia: `sock.Carousel`, `sock.Button`, `sock.ButtonV2`, `sock.Toolkit`. Pesan `interactiveMessage`, `buttonsMessage`, `flowMessage`, dan `carouselMessage` juga bisa dikirim lewat `sock.sendMessage`.
|
|
204
|
+
|
|
205
|
+
> Rich Message memakai fitur WhatsApp yang bisa berubah. Tampilannya bergantung pada versi aplikasi penerima.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## π― SPR (Selective Relay)
|
|
210
|
+
|
|
211
|
+
SPR mengontrol **siapa membaca apa** dalam satu pesan grup. Tiap device penerima masuk salah satu peran:
|
|
212
|
+
|
|
213
|
+
| Peran | Yang diterima |
|
|
214
|
+
|---|---|
|
|
215
|
+
| `public` | pesan umum |
|
|
216
|
+
| `personal` | pesan khusus miliknya saja |
|
|
217
|
+
| `hidden` | tidak menerima apa-apa |
|
|
218
|
+
|
|
219
|
+
```js
|
|
220
|
+
// Sembunyikan pesan dari 1 orang
|
|
221
|
+
await sock.sPR(groupJid, { conversation: 'rahasia' }, {
|
|
222
|
+
mode: 'exclude', // 'include' = hanya target yang menerima
|
|
223
|
+
target: ['6281234567890@s.whatsapp.net']
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
// Pesan umum untuk semua, pesan lain khusus untuk A
|
|
227
|
+
await sock.sPR(groupJid, { conversation: 'info umum' }, {
|
|
228
|
+
personal: { '6281234567890@s.whatsapp.net': { conversation: 'info khusus kamu' } }
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
// Anggota lain lihat publicText, targetJid lihat privateText + foto profilnya
|
|
232
|
+
await sock.sPRPrivate(groupJid, targetJid, {
|
|
233
|
+
publicText: 'Pesan ini memiliki isi khusus untuk beberapa penerima.',
|
|
234
|
+
privateText: 'rahasia buat kamu'
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
// Tiap anggota menerima pesan sendiri, {name} menjadi @mention orang itu
|
|
238
|
+
await sock.sPRBroadcast(groupJid, { template: 'Halo {name}, ada pesan untukmu.', limit: 100 })
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Opsi lengkap dan penjelasan lebih dalam: **[docs/SPR.md](docs/SPR.md)**
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## π’ Newsletter Status
|
|
246
|
+
|
|
247
|
+
Kirim status ke **Channel (newsletter)** yang kamu admin-i. JID channel berakhiran `@newsletter`.
|
|
248
|
+
|
|
249
|
+
```js
|
|
250
|
+
const jid = '120363xxxxxxxxxxxxx@newsletter'
|
|
251
|
+
|
|
252
|
+
// Teks
|
|
253
|
+
const sent = await sock.newsletter.sendStatus(jid, { text: 'Halo Channel!' })
|
|
254
|
+
console.log(sent.newsletterStatusServerId) // dipakai untuk react / revoke
|
|
255
|
+
|
|
256
|
+
// Gambar atau video
|
|
257
|
+
await sock.newsletter.sendStatus(jid, {
|
|
258
|
+
image: { url: './foto.jpg' },
|
|
259
|
+
caption: 'Update terbaru'
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
// React ke status
|
|
263
|
+
await sock.newsletter.reactToStatus(jid, sent.newsletterStatusServerId, 'π₯')
|
|
264
|
+
|
|
265
|
+
// Hapus status
|
|
266
|
+
await sock.newsletter.revokeStatus(jid, statusId)
|
|
267
|
+
|
|
268
|
+
// Ambil daftar status
|
|
269
|
+
const list = await sock.newsletter.fetchStatuses(jid, { count: 20 })
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Semua fungsi juga tersedia langsung di socket: `sock.sendNewsletterStatus(...)`, `sock.sendNewsletterStatusReaction(...)`, dan seterusnya.
|
|
273
|
+
|
|
274
|
+
Dokumentasi jenis konten, opsi, dan error: lihat tipe di `lib/Utils/newsletter-status.d.ts`.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## π§© Fitur lain
|
|
279
|
+
|
|
280
|
+
```js
|
|
281
|
+
// Greeting Card /buss (hanya terlihat di WhatsApp Business)
|
|
282
|
+
await sock.sendGreetingCard(jid, {
|
|
283
|
+
text: 'wow', title: 'Judul Kartu', greeting: 'Hi Business',
|
|
284
|
+
imageUrl: 'https://.../img.jpg', contactUrl: 'https://wa.me/NOMOR'
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
// Presence & profile
|
|
288
|
+
await sock.presence.withTyping(jid, () => sock.sendMessage(jid, { text: 'halo' }))
|
|
289
|
+
await sock.profile.setStatus('Bot aktif')
|
|
290
|
+
|
|
291
|
+
// Plugin
|
|
292
|
+
import { definePlugin } from 'sauruspro-bail'
|
|
293
|
+
sock.use(definePlugin({ id: 'halo', setup: ({ extend }) => extend({ halo: () => 'hai' }) }))
|
|
294
|
+
// matikan fitur bawaan: makeWASocket({ disablePlugins: ['greeting-card'] })
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## π Dokumentasi
|
|
298
|
+
|
|
299
|
+
| File | Isi |
|
|
300
|
+
|---|---|
|
|
301
|
+
| [docs/SPR.md](docs/SPR.md) | Selective Relay lengkap |
|
|
302
|
+
| [docs/CHANGELOG.md](docs/CHANGELOG.md) | Riwayat versi |
|
|
303
|
+
|
|
304
|
+
## β οΈ Disclaimer
|
|
305
|
+
|
|
306
|
+
Library ini tidak berafiliasi dengan WhatsApp/Meta. Gunakan dengan bijak dan patuhi Terms of Service WhatsApp. Pengguna bertanggung jawab atas penggunaannya.
|
|
307
|
+
|
|
308
|
+
## π» Developer
|
|
309
|
+
|
|
310
|
+
<div align="center">
|
|
311
|
+
|
|
312
|
+
**Saurus / Dinonic**
|
|
313
|
+
|
|
314
|
+
Telegram [@lordsaurus](https://t.me/lordsaurus)
|
|
315
|
+
|
|
316
|
+
Made with β€οΈ by Saurus / Dinonic
|
|
317
|
+
|
|
318
|
+
</div>
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,64 +1,61 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 5.0.3
|
|
4
|
+
### Fixed
|
|
5
|
+
- **Pair code**: `requestPairingCode` diperbaiki.
|
|
6
|
+
- Nomor dibersihkan otomatis (`+62 812-3456-789` menjadi `628123456789`) dan divalidasi 7-15 digit.
|
|
7
|
+
- Menunggu socket terbuka dulu sebelum mengirim permintaan (tidak lagi error "Connection Closed" kalau dipanggil terlalu cepat).
|
|
8
|
+
- Setiap request membuat kode acak baru **dan** keypair ephemeral baru (sebelumnya keypair lama dipakai ulang).
|
|
9
|
+
- Kode custom dinormalkan ke huruf besar dan divalidasi `A-Z0-9` 8 karakter.
|
|
10
|
+
- Sesi yang sudah `registered` ditolak dengan pesan jelas.
|
|
11
|
+
- Jika pengiriman gagal, state pairing (kode, keypair, `me`) dikembalikan seperti semula.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- Versi di banner `lib/index.js` kini dibaca dari `package.json` (export `packageVersion`). Banner bisa dimatikan dengan env `SAURUS_NO_BANNER=1`.
|
|
15
|
+
- Info fitur di banner diperbarui.
|
|
16
|
+
- README baru: pengertian Baileys, koneksi (QR dan pairing code), pemakaian dari CommonJS, Rich Message, SPR, dan Newsletter Status.
|
|
17
|
+
|
|
3
18
|
## 5.0.2
|
|
4
19
|
### Added (dari zapo-js, MIT)
|
|
5
20
|
- **Greeting Card `/buss`**: `sock.sendGreetingCard(jid, { text, title, greeting, imageUrl, contactUrl, thumbnail?, sourceApp?, ref?, mentions?, adReply? }, sendOptions?)` dan `sock.buildGreetingCard(opts)`.
|
|
6
21
|
Pesan `extendedTextMessage` + `contextInfo.externalAdReply`; `sourceId`, `ctwaClid`, `ctaPayload` diacak tiap kirim. Kartu hanya tampil di WhatsApp Business; user biasa hanya melihat teks.
|
|
7
|
-
Contoh:
|
|
8
22
|
```js
|
|
9
23
|
await sock.sendGreetingCard(jid, {
|
|
10
24
|
text: 'wow', title: 'Megumin Dominada BUSI', greeting: 'Hi Business',
|
|
11
25
|
imageUrl: 'https://.../img.jpg', contactUrl: 'https://wa.me/NOMOR'
|
|
12
26
|
}, { quoted: null })
|
|
13
27
|
```
|
|
14
|
-
- **Group History Bundle** (`sock.GroupHistory
|
|
15
|
-
- **Meta AI Bot helpers** (`sock.MetaAIBot
|
|
16
|
-
- **Plugin system
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
sock.use(myPlugin)
|
|
22
|
-
```
|
|
23
|
-
- **Presence & Profile API**: `sock.presence` (`setOnline`, `setOffline`, `typing`, `recording`, `paused`, `subscribe`, `typeFor(jid, ms)`, `withTyping(jid, fn)`) dan `sock.profile` (`getPicture`, `setPicture`, `removePicture`, `getStatus`, `setStatus`, `setName`, `username.{get,set,delete,check,recommendations,setPin,find}`). Pembungkus dari fungsi socket yang sudah ada.
|
|
24
|
-
- **Akselerator kripto native opsional**: jika `@zapo-js/native` terpasang, X25519 dan XEdDSA (sign/verify) dipakai lewat native (NAPI lalu WASM); tanpa paket itu otomatis tetap JS (libsignal). Env `SAURUS_NATIVE_BACKEND` = `auto|napi|wasm|js|none`. Util: `isNativeCryptoActive()`.
|
|
28
|
+
- **Group History Bundle** (`sock.GroupHistory`): `encodeGroupHistoryBundle`, `decodeGroupHistoryBundle`, `streamGroupHistoryBundle`.
|
|
29
|
+
- **Meta AI Bot helpers** (`sock.MetaAIBot`): `BOT_KNOWN_JIDS`, `genBotMsgSecret`, `deriveBotChunkKey`, `decryptBotChunk`, `attachBotMetadata`, `attachBotThread`, `extractInvokedBotJid`, `buildBotInvokeProtoCopy`.
|
|
30
|
+
- **Plugin system**: `sock.use(plugin)`, `sock.removePlugin(id)`, `sock.hasPlugin(id)`, `sock.listPlugins()`, helper `definePlugin({ id, exposeAs?, setup(ctx), dispose? })`. Opsi socket `plugins: [...]` dan `disablePlugins: [...]`.
|
|
31
|
+
Fitur bawaan berupa plugin: `spr`, `greeting-card`, `group-history`, `meta-ai-bot`, `presence`, `profile`.
|
|
32
|
+
- **Presence & Profile API**: `sock.presence` (`setOnline`, `setOffline`, `typing`, `recording`, `paused`, `subscribe`, `typeFor`, `withTyping`) dan `sock.profile` (`getPicture`, `setPicture`, `removePicture`, `getStatus`, `setStatus`, `setName`, `username.*`).
|
|
33
|
+
- **Akselerator kripto native opsional**: jika `@zapo-js/native` terpasang, X25519 dan XEdDSA memakai native (NAPI lalu WASM), jika tidak tetap JS. Env `SAURUS_NATIVE_BACKEND=auto|napi|wasm|js|none`.
|
|
34
|
+
- **SPR**: opsi `personal` (pesan khusus per orang), `sPRPrivate`, `sPRBroadcast` (`{name}` + mention + foto profil), `getSPRTargets`, `loadSPRAvatars`, batas target 100 dengan hitungan overflow, cache foto, budget/timeout, konkurensi (diadaptasi dari plugin zapo-js).
|
|
25
35
|
|
|
26
36
|
### Fixed
|
|
27
|
-
-
|
|
37
|
+
- Kode pairing tanpa custom kini acak tiap request (sebelumnya selalu sama).
|
|
28
38
|
|
|
29
39
|
### Changed
|
|
30
|
-
- `lib/Utils/dinonic-spr.js` ditulis ulang
|
|
31
|
-
|
|
32
|
-
### Added (diadaptasi dari plugin zapo-js, MIT)
|
|
33
|
-
- Opsi `personal` pada `sPR`: pesan khusus per orang.
|
|
34
|
-
- `sPRPrivate`, `sPRBroadcast` (`{name}` + mention + foto profil), `getSPRTargets`, `loadSPRAvatars`.
|
|
35
|
-
- Batas target 100 + hitung overflow, cache foto, budget/timeout, konkurensi.
|
|
40
|
+
- `lib/Utils/dinonic-spr.js` ditulis ulang (sender key sekali pakai). API `sPR` / `selectiveRelay` tetap kompatibel.
|
|
36
41
|
- Reporting token memakai util resmi, tctoken memakai pengecekan expired.
|
|
37
42
|
|
|
38
43
|
## 5.0.1
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
### Added (fitur tambahan, by Saurus)
|
|
44
|
+
### Added
|
|
42
45
|
- **A2UI / Bloks widget**: `a2uiText`, `a2uiButton`, `a2uiCard`, `a2uiTabs`, `a2uiModal`, dll, plus `sendA2UI`, `sendBloksWidget`.
|
|
43
|
-
- **
|
|
44
|
-
- **
|
|
46
|
+
- **Builder** (`sock.DinonicBuilder`): Button, ButtonV2, Carousel, AIRich, Toolkit.
|
|
47
|
+
- **AIRich lengkap**, **HTML App** (`sendHtmlApp`, `sendHtmlDocument`), **Meta AI sections**, **Bot Signature**, **Native Flow**.
|
|
45
48
|
- **Modern Messages**: komentar, event invite, pertanyaan/jawaban, poll add option, scheduled call, undangan newsletter, status mention/reaction/audience.
|
|
46
|
-
- **Payment Messages** (payment reminder, split payment), **Scheduled Message
|
|
47
|
-
-
|
|
49
|
+
- **Payment Messages** (payment reminder, split payment), **Scheduled Message**, **Status Stickers** (musik, link, lokasi, pesan, channel).
|
|
50
|
+
- Handler `Socket/dinonic-handler.js`: Interactive/Carousel, Buttons, Flow, Group Story di `sendMessage`, plus `sock.sendStatusWhatsApp` dan `sock.getName`.
|
|
48
51
|
- Opsi socket: `rejectCalls`, `callRejectMessage`, `autoReadStatus`, `autoReadMessages`.
|
|
49
|
-
- `baileys-event-stream
|
|
52
|
+
- `baileys-event-stream` dan file `.d.ts` untuk modul baru.
|
|
50
53
|
|
|
51
54
|
### Changed
|
|
52
|
-
- Semua nama `dinolith` β `dinonic` (termasuk file `dinonic-spr.js`). Branding fitur tambahan diganti menjadi Saurus / Dinonic.
|
|
53
55
|
- **Newsletter Status** diganti dengan implementasi penuh (alias `prepareNewsletterStatusContent` dan `makeNewsletterStatusAttribution` tetap ada).
|
|
54
|
-
- Pesan `interactiveMessage`, `buttonsMessage`, `flowMessage`, `carouselMessage`/`cards` sekarang lewat handler
|
|
55
|
-
|
|
56
|
-
### Tidak dibawa
|
|
57
|
-
- Telegram adapter dan bridge, auto-follow channel (sudah ada di `Socket/newsletter.js`), registrasi mobile, mobile client, `phonenumber-mcc` (dasar Baileys lama).
|
|
56
|
+
- Pesan `interactiveMessage`, `buttonsMessage`, `flowMessage`, `carouselMessage`/`cards` sekarang lewat handler baru.
|
|
58
57
|
|
|
59
58
|
## 5.0.0
|
|
60
|
-
**Owner: Saurus / Dinonic**
|
|
61
|
-
|
|
62
59
|
### Added
|
|
63
60
|
- **Newsletter Status**: `sendNewsletterStatus`, `sendNewsletterStatusReaction`, `revokeNewsletterStatus`, `getNewsletterStatuses`, `getNewsletterStatusUpdates`, plus `sock.newsletter.{sendStatus, reactToStatus, revokeStatus, fetchStatuses, fetchStatusUpdates}`.
|
|
64
61
|
- File tipe `newsletter-status.d.ts` dan `dinonic-spr.d.ts`.
|
|
@@ -67,12 +64,4 @@
|
|
|
67
64
|
|
|
68
65
|
### Fixed
|
|
69
66
|
- `dinonic-spr.js` mengimpor `encodeSignedDeviceIdentity` dari `generics.js` (tidak ada), sehingga seluruh paket gagal load. Sekarang dari `validate-connection.js`.
|
|
70
|
-
- SPR:
|
|
71
|
-
- `package.json`: `"type": "module"` ditambahkan (kode ESM), duplikat `lru-cache` di devDependencies dihapus.
|
|
72
|
-
|
|
73
|
-
### Changed
|
|
74
|
-
- Versi `3.0.0` β `5.0.0`, author/owner `Saurus / Dinonic`.
|
|
75
|
-
- README ditulis ulang, banner menampilkan versi & owner.
|
|
76
|
-
|
|
77
|
-
### Notes
|
|
78
|
-
- Newsletter status diport dari diezyxhao-baileys 1.4.0 ke ESM; tidak mengubah `sendMessage`.
|
|
67
|
+
- SPR: fallback `conn.user` saat `authState.creds.me` kosong.
|
package/lib/Socket/socket.js
CHANGED
|
@@ -735,63 +735,92 @@ export const makeSocket = (config) => {
|
|
|
735
735
|
void end(new Boom(msg || 'Intentional Logout', { statusCode: DisconnectReason.loggedOut }));
|
|
736
736
|
};
|
|
737
737
|
const requestPairingCode = async (phoneNumber, customPairingCode) => {
|
|
738
|
-
if (
|
|
739
|
-
throw new
|
|
738
|
+
if (authState.creds.registered) {
|
|
739
|
+
throw new Boom('Sesi sudah terdaftar (registered). Hapus folder sesi untuk pairing ulang.', { statusCode: 400 });
|
|
740
740
|
}
|
|
741
|
-
//
|
|
742
|
-
const
|
|
743
|
-
|
|
741
|
+
// Nomor harus angka saja dengan kode negara (tanpa +, spasi, atau strip).
|
|
742
|
+
const digits = String(phoneNumber ?? '').replace(/\D/g, '');
|
|
743
|
+
if (digits.length < 7 || digits.length > 15) {
|
|
744
|
+
throw new Boom('Nomor tidak valid. Gunakan format internasional tanpa +, contoh: 628123456789', { statusCode: 400 });
|
|
745
|
+
}
|
|
746
|
+
let customCode;
|
|
747
|
+
if (customPairingCode) {
|
|
748
|
+
customCode = String(customPairingCode).toUpperCase();
|
|
749
|
+
if (!/^[A-Z0-9]{8}$/.test(customCode)) {
|
|
750
|
+
throw new Error('Custom pairing code must be exactly 8 chars (A-Z, 0-9)');
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
// Pastikan koneksi sudah terbuka sebelum mengirim permintaan pairing.
|
|
754
|
+
await waitForSocketOpen();
|
|
755
|
+
const previous = {
|
|
756
|
+
pairingCode: authState.creds.pairingCode,
|
|
757
|
+
pairingEphemeralKeyPair: authState.creds.pairingEphemeralKeyPair,
|
|
758
|
+
me: authState.creds.me
|
|
759
|
+
};
|
|
760
|
+
// Kode acak baru + keypair ephemeral baru di setiap request (tidak memakai ulang yang lama).
|
|
761
|
+
authState.creds.pairingCode = customCode ?? bytesToCrockford(randomBytes(5));
|
|
762
|
+
authState.creds.pairingEphemeralKeyPair = Curve.generateKeyPair();
|
|
744
763
|
authState.creds.me = {
|
|
745
|
-
id: jidEncode(
|
|
764
|
+
id: jidEncode(digits, 's.whatsapp.net'),
|
|
746
765
|
name: '~'
|
|
747
766
|
};
|
|
748
767
|
ev.emit('creds.update', authState.creds);
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
content: [
|
|
766
|
-
{
|
|
767
|
-
tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
|
|
768
|
-
attrs: {},
|
|
769
|
-
content: await generatePairingKey()
|
|
770
|
-
},
|
|
771
|
-
{
|
|
772
|
-
tag: 'companion_server_auth_key_pub',
|
|
773
|
-
attrs: {},
|
|
774
|
-
content: authState.creds.noiseKey.public
|
|
775
|
-
},
|
|
776
|
-
{
|
|
777
|
-
tag: 'companion_platform_id',
|
|
778
|
-
attrs: {},
|
|
779
|
-
content: getCompanionPlatformId(browser)
|
|
780
|
-
},
|
|
781
|
-
{
|
|
782
|
-
tag: 'companion_platform_display',
|
|
783
|
-
attrs: {},
|
|
784
|
-
content: `${browser[1]} (${browser[0]})`
|
|
768
|
+
try {
|
|
769
|
+
await sendNode({
|
|
770
|
+
tag: 'iq',
|
|
771
|
+
attrs: {
|
|
772
|
+
to: S_WHATSAPP_NET,
|
|
773
|
+
type: 'set',
|
|
774
|
+
id: generateMessageTag(),
|
|
775
|
+
xmlns: 'md'
|
|
776
|
+
},
|
|
777
|
+
content: [
|
|
778
|
+
{
|
|
779
|
+
tag: 'link_code_companion_reg',
|
|
780
|
+
attrs: {
|
|
781
|
+
jid: authState.creds.me.id,
|
|
782
|
+
stage: 'companion_hello',
|
|
783
|
+
should_show_push_notification: 'true'
|
|
785
784
|
},
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
785
|
+
content: [
|
|
786
|
+
{
|
|
787
|
+
tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
|
|
788
|
+
attrs: {},
|
|
789
|
+
content: await generatePairingKey()
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
tag: 'companion_server_auth_key_pub',
|
|
793
|
+
attrs: {},
|
|
794
|
+
content: authState.creds.noiseKey.public
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
tag: 'companion_platform_id',
|
|
798
|
+
attrs: {},
|
|
799
|
+
content: getCompanionPlatformId(browser)
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
tag: 'companion_platform_display',
|
|
803
|
+
attrs: {},
|
|
804
|
+
content: `${browser[1]} (${browser[0]})`
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
tag: 'link_code_pairing_nonce',
|
|
808
|
+
attrs: {},
|
|
809
|
+
content: '0'
|
|
810
|
+
}
|
|
811
|
+
]
|
|
812
|
+
}
|
|
813
|
+
]
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
catch (error) {
|
|
817
|
+
// Gagal kirim: kembalikan state lama supaya tidak tertinggal kode/keypair setengah jadi.
|
|
818
|
+
authState.creds.pairingCode = previous.pairingCode;
|
|
819
|
+
authState.creds.pairingEphemeralKeyPair = previous.pairingEphemeralKeyPair;
|
|
820
|
+
authState.creds.me = previous.me;
|
|
821
|
+
ev.emit('creds.update', authState.creds);
|
|
822
|
+
throw error;
|
|
823
|
+
}
|
|
795
824
|
return authState.creds.pairingCode;
|
|
796
825
|
};
|
|
797
826
|
async function generatePairingKey() {
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import makeWASocket from './Socket/index.js';
|
|
2
2
|
import chalk from "chalk";
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
// Versi diambil dari package.json supaya selalu sinkron.
|
|
7
|
+
export const packageVersion = require("../package.json").version;
|
|
3
8
|
|
|
4
9
|
const ascii = [
|
|
5
10
|
"β β β β β’β‘ β €β β’²β’Άβ‘β β €β’β‘β β β β β β β β β ",
|
|
@@ -22,13 +27,16 @@ const ascii = [
|
|
|
22
27
|
const info = [
|
|
23
28
|
{ label: "", value: "Baileys Saurus Pro", title: true },
|
|
24
29
|
{ label: "", value: "" },
|
|
25
|
-
{ label: "β¦", value: "
|
|
26
|
-
{ label: "β¦", value: "
|
|
27
|
-
{ label: "β¦", value: "Rich Message Support" },
|
|
30
|
+
{ label: "β¦", value: "Pairing Code & QR (kode acak, sudah diperbaiki)" },
|
|
31
|
+
{ label: "β¦", value: "Rich Message (AIRich, Carousel, Button)" },
|
|
28
32
|
{ label: "β¦", value: "SPR (Selective Relay)" },
|
|
29
33
|
{ label: "β¦", value: "Newsletter Status" },
|
|
34
|
+
{ label: "β¦", value: "Greeting Card /buss" },
|
|
35
|
+
{ label: "β¦", value: "Plugin System (sock.use)" },
|
|
36
|
+
{ label: "β¦", value: "Presence & Profile API" },
|
|
37
|
+
{ label: "β¦", value: "Native Crypto (opsional)" },
|
|
30
38
|
{ label: "", value: "" },
|
|
31
|
-
{ label: "Version", value:
|
|
39
|
+
{ label: "Version", value: `v${packageVersion}` },
|
|
32
40
|
{ label: "Owner", value: "Saurus / Dinonic" },
|
|
33
41
|
{ label: "Telegram", value: "t.me/lordsaurus" },
|
|
34
42
|
{ label: "WA Owner", value: "+62 895-6390-43495" }
|
|
@@ -45,6 +53,7 @@ const infoLines = info.map(({ label, value, title }) => {
|
|
|
45
53
|
});
|
|
46
54
|
|
|
47
55
|
const rows = Math.max(ascii.length, infoLines.length);
|
|
56
|
+
if (!process.env.SAURUS_NO_BANNER) {
|
|
48
57
|
console.log("\n");
|
|
49
58
|
for (let i = 0; i < rows; i++) {
|
|
50
59
|
const art = ascii[i] || "".padEnd(24);
|
|
@@ -52,6 +61,7 @@ for (let i = 0; i < rows; i++) {
|
|
|
52
61
|
console.log(" " + purple(art) + " " + text);
|
|
53
62
|
}
|
|
54
63
|
console.log("\n");
|
|
64
|
+
}
|
|
55
65
|
export * from '../WAProto/index.js';
|
|
56
66
|
export * from './Utils/index.js';
|
|
57
67
|
export * from './Types/index.js';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sauruspro-bail",
|
|
3
|
-
"version": "5.0.
|
|
4
|
-
"description": "Sauruspro Baileys -
|
|
3
|
+
"version": "5.0.3",
|
|
4
|
+
"description": "Sauruspro Baileys - WhatsApp Web API (Baileys) dengan SPR (Selective Relay), Newsletter Status, Rich Messages, Greeting Card, plugin system, dan pairing code.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"baileys",
|
|
7
7
|
"whatsapp",
|