@xbibzlibrary/whatsbibz 1.3.0 → 1.3.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/CHANGELOG.md +128 -93
- package/README.id.md +374 -0
- package/README.md +288 -194
- package/SECURITY.md +91 -0
- package/lib/BibzWhats/client.js +12 -4
- package/lib/BibzWhats/version.js +2 -2
- package/lib/Defaults/index.js +1 -1
- package/lib/Utils/browser-utils.js +2 -2
- package/lib/Utils/generics.js +1 -1
- package/package.json +20 -6
package/README.md
CHANGED
|
@@ -1,280 +1,374 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://
|
|
3
|
-
onerror="this.src='assets/logo/preview.png'">
|
|
2
|
+
<img src="https://cdn.jsdelivr.net/gh/XbibzOfficial777/whatsbibz@main/assets/logo/preview.png" alt="WhatsBibz" width="360">
|
|
4
3
|
</p>
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
<h1 align="center">WhatsBibz</h1>
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
WhatsApp Web multi-device library for Node.js — a maintained fork of Baileys with a high-level client,
|
|
9
|
+
custom pairing codes, self-healing sessions, and a linked-device identity that is configurable or chosen automatically.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/@xbibzlibrary/whatsbibz"><img src="https://img.shields.io/npm/v/%40xbibzlibrary%2Fwhatsbibz?label=npm&color=0a6958" alt="npm version"></a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/@xbibzlibrary/whatsbibz"><img src="https://img.shields.io/npm/dm/%40xbibzlibrary%2Fwhatsbibz?color=0a6958" alt="npm downloads"></a>
|
|
15
|
+
<a href="https://github.com/XbibzOfficial777/whatsbibz/actions/workflows/ci.yml"><img src="https://github.com/XbibzOfficial777/whatsbibz/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
16
|
+
<a href="#requirements"><img src="https://img.shields.io/badge/node-%E2%89%A5%2020-0a6958" alt="Node.js >= 20"></a>
|
|
17
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-0a6958" alt="MIT"></a>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
<p align="center">
|
|
21
|
+
<b>English</b> · <a href="README.id.md">Bahasa Indonesia</a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Table of contents
|
|
27
|
+
|
|
28
|
+
- [Why WhatsBibz](#why-whatsbibz)
|
|
29
|
+
- [Requirements](#requirements)
|
|
30
|
+
- [Installation](#installation)
|
|
31
|
+
- [Quick start](#quick-start)
|
|
32
|
+
- [The high-level client: `createBibzWhats()`](#the-high-level-client-createbibzwhats)
|
|
33
|
+
- [Options](#options)
|
|
34
|
+
- [Events](#events)
|
|
35
|
+
- [Properties and methods](#properties-and-methods)
|
|
36
|
+
- [Connection lifecycle](#connection-lifecycle)
|
|
37
|
+
- [Linked-device identity](#linked-device-identity)
|
|
38
|
+
- [Automatic mode (default)](#automatic-mode-default)
|
|
39
|
+
- [Custom mode](#custom-mode)
|
|
40
|
+
- [What WhatsApp accepts](#what-whatsapp-accepts)
|
|
41
|
+
- [Sending and reading messages](#sending-and-reading-messages)
|
|
42
|
+
- [Low-level API (Baileys-compatible)](#low-level-api-baileys-compatible)
|
|
43
|
+
- [TypeScript](#typescript)
|
|
44
|
+
- [Migrating from Baileys / ourin-baileys](#migrating-from-baileys--ourin-baileys)
|
|
45
|
+
- [Troubleshooting](#troubleshooting)
|
|
46
|
+
- [Testing](#testing)
|
|
47
|
+
- [Project structure](#project-structure)
|
|
48
|
+
- [Versioning and compatibility](#versioning-and-compatibility)
|
|
49
|
+
- [Contributing](#contributing)
|
|
50
|
+
- [Security](#security)
|
|
51
|
+
- [License](#license)
|
|
52
|
+
|
|
53
|
+
## Why WhatsBibz
|
|
54
|
+
|
|
55
|
+
WhatsBibz is a full fork of [Baileys](https://github.com/WhiskeySockets/Baileys) v7 (via `ourin-baileys@9.0.21`), patched up to the current upstream `master`, plus a layer that solves the things every bot author ends up rewriting:
|
|
56
|
+
|
|
57
|
+
| Problem | What WhatsBibz does |
|
|
58
|
+
|---|---|
|
|
59
|
+
| Pairing "succeeds" but the phone never shows a notification | `requestPairingCode()` waits for the server's acknowledgement. Rejections (`400`, `429`) and timeouts surface as errors instead of a fake success. |
|
|
60
|
+
| Linked-device name gets rejected by the server (`428` before QR, `400` at pairing) | Identity is **configurable** (`identity: 'archLinux:Chrome'`) or **automatic**: the most stable profile is used first and the client rotates to the next one only when the server rejects it. The working profile is persisted so the device name never changes between restarts. |
|
|
61
|
+
| Corrupt or logged-out sessions loop forever | `401 / 500 / 411 / corrupt` → session folder wiped, new credentials, re-pair — bounded by `maxSessionWipes`. |
|
|
62
|
+
| `companion_reg_refresh` notifications kill unpaired sessions | Handled inside the socket (no `postinstall` patches). |
|
|
63
|
+
| Leaked timers after `close()`, ghost reconnects | `close()` cancels every scheduled reconnect; verified over 40 create→close cycles. |
|
|
64
|
+
| TypeScript users get an empty `WAProto/index.d.ts` from upstream | Complete declarations for all 217 `proto` namespaces; `tsc --strict` passes with `skipLibCheck: false`. |
|
|
11
65
|
|
|
12
|
-
|
|
13
|
-
> (`createBibzWhats`, `BIBZWHATS_*`); alias `createWhatsBibz` juga tersedia.
|
|
66
|
+
Everything from Baileys is still exported — existing code keeps working with only the import specifier changed.
|
|
14
67
|
|
|
15
|
-
|
|
16
|
-
Baileys v7 (basis `ourin-baileys@9.0.21`) dengan lapisan API tingkat tinggi,
|
|
17
|
-
pairing code custom, self-healing session, dan handler protokol terbaru
|
|
18
|
-
(`companion_reg_refresh`) yang **sudah tertanam di source** (tidak perlu
|
|
19
|
-
patch `postinstall`).
|
|
68
|
+
## Requirements
|
|
20
69
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- `
|
|
70
|
+
- **Node.js ≥ 20** (tested on 20, 22, 24 and 26)
|
|
71
|
+
- ESM only (`"type": "module"` or dynamic `import()`)
|
|
72
|
+
- Optional peers: `sharp` (media thumbnails), `qrcode-terminal` (ASCII QR fallback), `link-preview-js`, `jimp`, `audio-decode`, `@roamhq/wrtc` (VoIP)
|
|
24
73
|
|
|
25
|
-
##
|
|
74
|
+
## Installation
|
|
26
75
|
|
|
27
76
|
```bash
|
|
28
77
|
npm install @xbibzlibrary/whatsbibz
|
|
29
|
-
# atau lokal (vendored di proyek):
|
|
30
|
-
npm install ./BibzWhats
|
|
31
78
|
```
|
|
32
79
|
|
|
33
|
-
|
|
34
|
-
sebagai vendored `bibzwhats` (`"bibzwhats": "file:./BibzWhats"`), cukup ganti specifier-nya —
|
|
35
|
-
API-nya sama persis.
|
|
36
|
-
|
|
37
|
-
Dependensi opsional (peer): `sharp` (thumbnail media), `qrcode-terminal`
|
|
38
|
-
(QR ASCII saat fallback), `link-preview-js`, `jimp`, `audio-decode`,
|
|
39
|
-
`@roamhq/wrtc` (VoIP).
|
|
40
|
-
|
|
41
|
-
## Mulai cepat — `createBibzWhats()`
|
|
80
|
+
## Quick start
|
|
42
81
|
|
|
43
82
|
```js
|
|
44
83
|
import { createBibzWhats, extractMessage, sendText } from '@xbibzlibrary/whatsbibz';
|
|
45
84
|
|
|
46
85
|
const client = await createBibzWhats({
|
|
47
|
-
phone: '6281234567890',
|
|
48
|
-
pairingCode: 'XBIBZPRO',
|
|
49
|
-
authDir: '
|
|
50
|
-
printQR: true, // QR ASCII bila pairing code tak kunjung diterima
|
|
86
|
+
phone: '6281234567890', // bot number, digits with country code
|
|
87
|
+
pairingCode: 'XBIBZPRO', // optional: custom 8-character code (A–Z, 0–9)
|
|
88
|
+
authDir: 'whatsbibz-session',
|
|
51
89
|
});
|
|
52
90
|
|
|
53
|
-
client.on('pairing-code', (code
|
|
54
|
-
console.log(`PAIRING CODE: ${code} ${custom ? '(custom)' : '(acak)'}`));
|
|
91
|
+
client.on('pairing-code', (code) => console.log('Enter this code on your phone:', code));
|
|
55
92
|
|
|
56
93
|
client.on('ready', (sock) => {
|
|
57
|
-
console.log('terhubung sebagai', sock.user?.id);
|
|
58
94
|
sock.ev.on('messages.upsert', async ({ messages, type }) => {
|
|
59
95
|
if (type !== 'notify') return;
|
|
60
96
|
for (const m of messages) {
|
|
61
97
|
if (m.key.fromMe) continue;
|
|
62
98
|
const item = extractMessage(m);
|
|
63
99
|
if (item?.type === 'text' && /^ping$/i.test(item.text)) {
|
|
64
|
-
await sendText(sock, m.key.remoteJid, '
|
|
100
|
+
await sendText(sock, m.key.remoteJid, 'pong', { quoted: m });
|
|
65
101
|
}
|
|
66
102
|
}
|
|
67
103
|
});
|
|
68
104
|
});
|
|
69
105
|
```
|
|
70
106
|
|
|
71
|
-
`client`
|
|
107
|
+
On the phone: **Settings → Linked devices → Link a device → Link with phone number instead**, then type the code. Leave `phone` empty to get a QR code instead (`client.on('qr', ...)`, or `printQR: true` to print it in the terminal).
|
|
72
108
|
|
|
73
|
-
|
|
74
|
-
|---|---|---|
|
|
75
|
-
| `pairing-code` | `(code, {custom, fallback})` | kode siap dimasukkan di HP |
|
|
76
|
-
| `qr` | `(qr)` | fallback QR (setelah `qrFallbackAfterMs`, atau langsung bila `phone` kosong) |
|
|
77
|
-
| `ready` | `(sock)` | socket **baru** siap dipakai — pasang handler di sini. Dipancarkan saat start **dan tiap reconnect** (socket lama mati, listener ikut hilang). Set `readyOnEveryConnect:false` untuk perilaku lama (sekali) |
|
|
78
|
-
| `first-ready` | `(sock)` | hanya sekali seumur client |
|
|
79
|
-
| `open` / `close` | `(sock)` / `({status, error})` | tiap kali koneksi buka/tutup |
|
|
80
|
-
| `user` | `(digits)` | nomor bot terdeteksi (persist bila perlu) |
|
|
81
|
-
| `reconnecting` | `({delay, attempt, fresh})` | reconnect dijadwalkan |
|
|
82
|
-
| `session-wiped` | `(reason)` | sesi dihapus (401/500/411/korup) |
|
|
83
|
-
| `give-up` | `(message)` | berhenti mencoba — perlu campur tangan manusia |
|
|
84
|
-
|
|
85
|
-
Properti/metode: `client.sock` (socket aktif; berubah setelah reconnect),
|
|
86
|
-
`client.isConnected()`, `client.close()`, `client.logout()`.
|
|
87
|
-
|
|
88
|
-
### Perilaku bawaan
|
|
89
|
-
|
|
90
|
-
- **Versi WA Web terbaru** diambil di setiap connect (`fetchLatestWaWebVersion`) — server menolak pairing dari klien yang versinya tertinggal. Bila fetch gagal, versi **tidak diturunkan** (dipakai versi bawaan library `BIBZWHATS_WA_WEB_VERSION`, diperbarui 2026-09-03 → `2.3000.1046721733`; upstream issue #2777: versi lama = 408 loop).
|
|
91
|
-
- **Pairing code diverifikasi server**: `requestPairingCode()` menunggu jawaban `companion_hello` (upstream PR #2769). Penolakan (`400 bad-request`, `429 rate-overlimit`) atau timeout kini **terlihat sebagai error** dan `creds.me` tidak tersimpan untuk perangkat yang tak pernah diakui — dulu kode "sukses" palsu muncul tapi notifikasi tautkan perangkat tidak pernah datang di HP.
|
|
92
|
-
- `companion_platform_display` **divalidasi WhatsApp dengan allow-list**. Sejak 1.2.0 library menurunkannya otomatis ke nilai yang pasti valid (`Browsers.macOS` → `"Chrome (Mac OS)"`, `Browsers.archLinux` → `"Chrome (Linux)"`, nama produk → OS host). Override manual tetap dihormati apa adanya — lihat § Identitas platform.
|
|
93
|
-
- **515 restartRequired** setelah pairing = normal → reconnect otomatis 2 dtk.
|
|
94
|
-
- **401 loggedOut / 500 badSession / 411 / sesi korup** → folder sesi dihapus, kredensial baru, pairing ulang (maks. `maxSessionWipes`, default 3). Identitas perangkat yang sudah terbukti diterima (`identity.json`) **tidak** ikut dihapus.
|
|
95
|
-
- **401 saat pairing masih tertunda** (koneksi putus setelah kode terbit, lalu sambung ulang) dikenali terpisah: kredensial diganti dan kode diminta ulang dalam 2 s, tanpa mengurangi kuota `maxSessionWipes`. Event `reconnecting` membawa `pairingPending: true`.
|
|
96
|
-
- **Reconnect** biasa dengan backoff 10 s × percobaan (maks. 60 s, `maxReconnectAttempts` = 10); koneksi yang sudah sehat lalu putus jaringan mencoba lagi dalam 1 s dulu.
|
|
97
|
-
- **`client.close()` bersih**: reconnect terjadwal dibatalkan, tidak ada timer tersisa — proses bisa keluar sendiri (diuji 40 siklus create→close).
|
|
98
|
-
- **Pairing controller**: satu request in-flight, refresh 150 dtk (kode yang sedang diketik tidak hangus), custom code ditolak → fallback acak sekali, 428/429 → backoff eksponensial sampai 10 menit.
|
|
99
|
-
- **IPv4 dipaksa** untuk upload media (`forceIPv4`, bisa dimatikan).
|
|
100
|
-
- Cache metadata grup 5 menit (`cachedGroupMetadata`) — hemat query saat kirim ke grup.
|
|
101
|
-
- **Tidak ada auto-follow channel/newsletter diam-diam** (`autoFollowNewsletterOnConnect` default `false`).
|
|
102
|
-
|
|
103
|
-
Semua opsi bisa dioverride; opsi mentah `makeWASocket` lewat `socketConfig`.
|
|
104
|
-
|
|
105
|
-
## API tingkat rendah (kompatibel Baileys)
|
|
109
|
+
A runnable example lives in [`example/ping-bot.js`](example/ping-bot.js).
|
|
106
110
|
|
|
107
|
-
|
|
108
|
-
import makeWASocket, { useMultiFileAuthState, DisconnectReason, fetchLatestWaWebVersion, downloadMediaMessage } from '@xbibzlibrary/whatsbibz';
|
|
109
|
-
```
|
|
111
|
+
## The high-level client: `createBibzWhats()`
|
|
110
112
|
|
|
111
|
-
|
|
112
|
-
`useMultiFileAuthState`, `DisconnectReason`, `downloadMediaMessage`, `proto`,
|
|
113
|
-
`Browsers`, `jidNormalizedUser`, interactive message (`sock.sendMessage(jid, { interactiveButtons: [...] })`),
|
|
114
|
-
album, newsletter, `Button`/`Carousel`/`AIRich` builder, `VoipClient`, dll.
|
|
113
|
+
`createBibzWhats(options)` returns a Promise of an `EventEmitter`-based client that owns the socket for you: it fetches the current WhatsApp Web version, resolves the device identity, requests the pairing code, reconnects with back-off, wipes broken sessions and re-pairs.
|
|
115
114
|
|
|
116
|
-
|
|
117
|
-
(alias `sock.ourin` dipertahankan), `Browsers.whatsbibz('Chrome')` tersedia (alias `Browsers.bibzwhats`).
|
|
115
|
+
### Options
|
|
118
116
|
|
|
119
|
-
|
|
117
|
+
| Option | Type | Default | Description |
|
|
118
|
+
|---|---|---|---|
|
|
119
|
+
| `phone` | `string` | — | Bot number in digits with country code. Required for pairing codes; omit for QR. |
|
|
120
|
+
| `pairingCode` | `string` | random | Custom code, exactly 8 characters `A–Z0–9`. If the server refuses a custom code the client falls back to a random one once. |
|
|
121
|
+
| `authDir` | `string` | `'bibzwhats-session'` | Folder for credentials, signal keys and `identity.json`. |
|
|
122
|
+
| `identity` | `'auto' \| string \| [os, browser, version]` | `'auto'` | Linked-device identity. See [Linked-device identity](#linked-device-identity). |
|
|
123
|
+
| `browser` | `[os, browser, version]` | `null` | Legacy alias of `identity` (explicit tuple). |
|
|
124
|
+
| `maxIdentityRotations` | `number` | `4` | Automatic mode: how many alternative profiles to try before giving up. |
|
|
125
|
+
| `companionPlatformDisplay` | `string \| null` | `null` | Override the `companion_platform_display` sent at pairing. Only set this if you know the value is on WhatsApp's allow-list. |
|
|
126
|
+
| `logger` | `{ info, warn, error, debug, ok }` | console | Any object with those methods (all optional). |
|
|
127
|
+
| `printQR` | `boolean` | `false` | Print the QR as ASCII when a QR is shown (requires `qrcode-terminal`). |
|
|
128
|
+
| `socketConfig` | `Partial<SocketConfig>` | `{}` | Raw `makeWASocket` options merged last — full escape hatch. |
|
|
129
|
+
| `fetchLatestVersion` | `boolean` | `true` | Fetch the current WhatsApp Web version on every connect. The built-in version is never downgraded. |
|
|
130
|
+
| `forceIPv4` | `boolean` | `true` | Force IPv4 for media uploads. |
|
|
131
|
+
| `readyOnEveryConnect` | `boolean` | `true` | Emit `ready` for every new socket (first connect and each reconnect). |
|
|
132
|
+
| `maxReconnectAttempts` | `number` | `10` | Consecutive failed reconnects before `give-up`. |
|
|
133
|
+
| `reconnectStepMs` / `reconnectMaxMs` | `number` | `10000` / `60000` | Linear back-off: `step × attempt`, capped at `max`. |
|
|
134
|
+
| `restartDelayMs` | `number` | `2000` | Delay after `515 restartRequired` (normal after pairing) and after an identity rotation. |
|
|
135
|
+
| `maxSessionWipes` | `number` | `3` | Session wipes (401/500/411/corrupt) before `give-up`. |
|
|
136
|
+
| `wipeReconnectDelayMs` | `number` | `10000` | Delay before reconnecting with fresh credentials. |
|
|
137
|
+
| `qrFallbackAfterMs` | `number` | `90000` | With `phone` set, show a QR if no pairing code was accepted within this time. |
|
|
138
|
+
| `pairingRequestDelayMs` | `number` | `20000` | If the server sends no QR at all, request a pairing code directly after this delay. |
|
|
139
|
+
| `groupMetadataTtlMs` | `number` | `300000` | Cache TTL for group metadata used when sending to groups. |
|
|
140
|
+
|
|
141
|
+
Defaults are exported as `BIBZWHATS_DEFAULTS`.
|
|
142
|
+
|
|
143
|
+
### Events
|
|
144
|
+
|
|
145
|
+
| Event | Payload | When |
|
|
146
|
+
|---|---|---|
|
|
147
|
+
| `pairing-code` | `(code, { custom, fallback })` | The server accepted a pairing code request. `custom` = your code was used; `fallback` = server refused the custom code and a random one was issued. |
|
|
148
|
+
| `qr` | `(qr)` | A QR string is available (immediately without `phone`, or after `qrFallbackAfterMs`). |
|
|
149
|
+
| `ready` | `(sock)` | A **new socket** is ready. Attach your message handlers here — sockets are replaced on reconnect and old listeners die with them. |
|
|
150
|
+
| `first-ready` | `(sock)` | Like `ready`, but only once per client. |
|
|
151
|
+
| `open` | `(sock)` | Connection opened (every time). |
|
|
152
|
+
| `user` | `(digits)` | The bot's own number became known. |
|
|
153
|
+
| `close` | `({ status, error })` | Connection closed. `status` is the `DisconnectReason` code. |
|
|
154
|
+
| `reconnecting` | `({ delay, attempt, fresh, identity?, pairingPending? })` | A reconnect is scheduled. `fresh` = with new credentials; `identity` = the profile after a rotation; `pairingPending` = the previous pairing was still pending on the server (see lifecycle). |
|
|
155
|
+
| `identity-changed` | `({ browser, linkedDeviceName, pairingDisplay, pairingDisplayAccepted, profileId, reason })` | Automatic mode only: the server rejected the previous profile and the next one is in use. |
|
|
156
|
+
| `session-wiped` | `(reason)` | The session folder was deleted (`'401 loggedOut'`, `'500 badSession'`, `'411'`, `'sesi korup'`, `'401 pairing tertunda'`). |
|
|
157
|
+
| `give-up` | `(message)` | The client stopped trying. Human intervention is needed (wrong number, blocked IP, …). |
|
|
158
|
+
| `connection.update` | `(update)` | Raw Baileys connection update, forwarded. |
|
|
159
|
+
|
|
160
|
+
### Properties and methods
|
|
161
|
+
|
|
162
|
+
| Member | Description |
|
|
163
|
+
|---|---|
|
|
164
|
+
| `client.sock` | The current socket (`null` before the first connect; changes on reconnect). |
|
|
165
|
+
| `client.identity` | `{ mode: 'auto' \| 'custom', source, profileId, browser, linkedDeviceName, pairingDisplay, pairingDisplayAccepted, tried: [{ id, reason }] }` |
|
|
166
|
+
| `client.options` | Effective options after defaults. |
|
|
167
|
+
| `client.isConnected()` | `true` while the socket is open. |
|
|
168
|
+
| `client.close()` | Close the socket and cancel scheduled reconnects. Leaves no timers behind. |
|
|
169
|
+
| `client.logout()` | Log the device out on the server and delete the session folder. |
|
|
170
|
+
|
|
171
|
+
### Connection lifecycle
|
|
120
172
|
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
173
|
+
```
|
|
174
|
+
connect ──► QR / pairing code ──► 515 restartRequired ──► reconnect (2 s) ──► open ──► ready
|
|
175
|
+
│ │
|
|
176
|
+
│ 428 before QR / 405 (identity rejected) auto → next profile, 2 s │ network drop → 1 s, then back-off
|
|
177
|
+
│ 400 at pairing (identity rejected) auto → next profile, 2 s │ 401 registered → wipe, re-pair
|
|
178
|
+
│ 401 with pairing pending new credentials, 2 s │
|
|
179
|
+
└─ other close codes ── back-off 10 s × attempt (max 60 s, 10 attempts) ── give-up
|
|
128
180
|
```
|
|
129
181
|
|
|
130
|
-
|
|
131
|
-
- `sendMedia(sock, jid, content, {quoted, fallbackToDocument})` — bila media ditolak, dikirim ulang sebagai dokumen.
|
|
132
|
-
- `extractMessage(m)` — `{type, text, participant, mentions, quoted, imageMsg|audioMsg|...}`; unwrap ephemeral/view-once/edited otomatis; tombol/list/poll/interactive response → `type: 'button' | 'poll'`.
|
|
133
|
-
- `LidMap` — peta LID ↔ nomor (`learnFromMessage(m)`, `canonical(jid)`, `variants(jid)`, `toJSON()/fromJSON()`).
|
|
182
|
+
Details worth knowing:
|
|
134
183
|
|
|
135
|
-
|
|
184
|
+
- **515 after pairing is normal.** The server asks the client to restart; the client reconnects after `restartDelayMs`.
|
|
185
|
+
- **401 with a pending pairing.** If the connection drops right after a pairing code was issued, the server answers the next connect with `401`. This is not a wrong number: the client replaces the credentials and requests a new code within 2 s. This path does not count towards `maxSessionWipes`.
|
|
186
|
+
- **Identity rotation happens only before the device is registered.** Once linked, the identity is locked — changing it would look like a different device to the phone.
|
|
187
|
+
- **Session wipes keep `identity.json`** when the identity was already accepted (`qr-received`, `pairing-accepted`, `open`), so the device name stays the same after re-pairing.
|
|
136
188
|
|
|
137
|
-
|
|
138
|
-
`pair-device-rotate-qr` yang menyita material registrasi perangkat yang belum
|
|
139
|
-
paired. BibzWhats menanganinya di `lib/Socket/socket.js`: rotate adv secret
|
|
140
|
-
(32 byte CSPRNG) → `creds.update` → render ulang QR **ref yang sama** (pool ref
|
|
141
|
-
tidak habis). Bila `creds.me` sudah ada (pairing code sudah diminta / pair
|
|
142
|
-
sukses) adv secret dipertahankan agar verifikasi tidak rusak.
|
|
189
|
+
## Linked-device identity
|
|
143
190
|
|
|
144
|
-
|
|
145
|
-
(`import ... from '@xbibzlibrary/whatsbibz'`).
|
|
191
|
+
The tuple `browser = [os, browser, version]` decides what the phone shows under **Linked devices**, and part of it is validated by WhatsApp at pairing time.
|
|
146
192
|
|
|
147
|
-
|
|
193
|
+
### Automatic mode (default)
|
|
148
194
|
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
WAProto/ protobuf WhatsApp
|
|
195
|
+
```js
|
|
196
|
+
const client = await createBibzWhats({ phone }); // identity: 'auto'
|
|
197
|
+
client.on('identity-changed', (i) => console.log('switched to', i.linkedDeviceName, 'because', i.reason));
|
|
198
|
+
console.log(client.identity);
|
|
199
|
+
// { mode: 'auto', profileId: 'macos-chrome', linkedDeviceName: 'Chrome (Mac OS)',
|
|
200
|
+
// pairingDisplay: 'Chrome (Mac OS)', pairingDisplayAccepted: true, tried: [] }
|
|
156
201
|
```
|
|
157
202
|
|
|
158
|
-
|
|
203
|
+
The client starts with the profile that has the best track record and switches only on a rejection signal (`428` before QR, `400 bad-request` at pairing, `405`):
|
|
159
204
|
|
|
160
|
-
|
|
161
|
-
|
|
205
|
+
| Order | Profile | Shown on the phone | Sent at pairing |
|
|
206
|
+
|---|---|---|---|
|
|
207
|
+
| 1 | `macos-chrome` | Chrome (Mac OS) | Chrome (Mac OS) |
|
|
208
|
+
| 2 | `macos-safari` | Safari (Mac OS) | Safari (Mac OS) |
|
|
209
|
+
| 3 | `windows-chrome` | Chrome (Windows) | Chrome (Windows) |
|
|
210
|
+
| 4 | `linux-chrome` | Chrome (Linux) | Chrome (Linux) |
|
|
211
|
+
| 5 | `ubuntu-chrome` | Chrome (Ubuntu) | Chrome (Ubuntu) |
|
|
212
|
+
| 6 | `macos-firefox` | Firefox (Mac OS) | Firefox (Mac OS) |
|
|
213
|
+
| 7 | `windows-edge` | Edge (Windows) | Edge (Windows) |
|
|
214
|
+
| 8 | `archlinux-chrome` | Chrome (Arch Linux) | Chrome (Linux) |
|
|
162
215
|
|
|
163
|
-
|
|
164
|
-
tertinggi (`Mac OS / Chrome`), lalu **berpindah sendiri** bila server menolaknya — `428` sebelum QR,
|
|
165
|
-
`400 bad-request` saat pairing kode, atau `405` — ke profil berikutnya (`Mac OS/Safari` → `Windows/Chrome`
|
|
166
|
-
→ `Linux/Chrome` → `Ubuntu/Chrome` → …). Profil yang terbukti bekerja disimpan di `<authDir>/identity.json`
|
|
167
|
-
sehingga setelah restart identitasnya tetap sama (nama perangkat di HP tidak berubah-ubah).
|
|
216
|
+
The profile that works is written to `<authDir>/identity.json` and reused on the next start. Delete that file (or the whole `authDir`) to start over.
|
|
168
217
|
|
|
169
|
-
|
|
170
|
-
const client = await createBibzWhats({ phone }); // identity: 'auto'
|
|
171
|
-
client.on('identity-changed', (i) => console.log('ganti identitas →', i.linkedDeviceName, i.reason));
|
|
172
|
-
console.log(client.identity);
|
|
173
|
-
// { mode:'auto', profileId:'macos-chrome', linkedDeviceName:'Chrome (Mac OS)',
|
|
174
|
-
// pairingDisplay:'Chrome (Mac OS)', pairingDisplayAccepted:true, tried:[] }
|
|
175
|
-
```
|
|
218
|
+
### Custom mode
|
|
176
219
|
|
|
177
|
-
|
|
178
|
-
server menolaknya kamu mendapat log error yang jelas, bukan identitas lain. Semua bentuk ini setara:
|
|
220
|
+
A custom identity is used **as is** and never replaced silently. If the server rejects it you get a clear error in the log, not a different device name.
|
|
179
221
|
|
|
180
222
|
```js
|
|
181
|
-
createBibzWhats({ phone, identity: Browsers.archLinux('Chrome') });
|
|
182
|
-
createBibzWhats({ phone, identity: ['Arch Linux', 'Firefox', '6.16.4'] });
|
|
183
|
-
createBibzWhats({ phone, identity: 'archLinux:Firefox' });
|
|
184
|
-
createBibzWhats({ phone, identity: 'Mac OS/Safari/15.6.1' });
|
|
185
|
-
createBibzWhats({ phone, identity: 'linux-chrome' });
|
|
186
|
-
createBibzWhats({ phone, browser: ['Mac OS', 'Chrome', '14.4.1'] });
|
|
223
|
+
createBibzWhats({ phone, identity: Browsers.archLinux('Chrome') }); // preset tuple
|
|
224
|
+
createBibzWhats({ phone, identity: ['Arch Linux', 'Firefox', '6.16.4'] }); // free tuple
|
|
225
|
+
createBibzWhats({ phone, identity: 'archLinux:Firefox' }); // "preset:Browser"
|
|
226
|
+
createBibzWhats({ phone, identity: 'Mac OS/Safari/15.6.1' }); // "OS/Browser/Version"
|
|
227
|
+
createBibzWhats({ phone, identity: 'linux-chrome' }); // profile id
|
|
228
|
+
createBibzWhats({ phone, browser: ['Mac OS', 'Chrome', '14.4.1'] }); // legacy alias
|
|
187
229
|
```
|
|
188
230
|
|
|
189
|
-
|
|
190
|
-
atau trio `BIBZ_DEVICE_OS="Arch Linux" BIBZ_DEVICE_BROWSER="Chrome" BIBZ_DEVICE_VERSION="6.16"`. `BIBZ_BROWSER=auto`
|
|
191
|
-
memaksa mode otomatis. Prioritas: opsi di kode → env → otomatis.
|
|
231
|
+
Environment variables work without code changes — priority is option → env → auto:
|
|
192
232
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
| `macos-desktop` / `windows-desktop` (hanya bila diminta eksplisit; butuh `syncFullHistory`) | Desktop (…) | Chrome (…) |
|
|
233
|
+
```bash
|
|
234
|
+
BIBZ_BROWSER="archLinux:Chrome" # or "Arch Linux/Firefox/6.16", or "auto"
|
|
235
|
+
# or the trio
|
|
236
|
+
BIBZ_DEVICE_OS="Arch Linux" BIBZ_DEVICE_BROWSER="Chrome" BIBZ_DEVICE_VERSION="6.16"
|
|
237
|
+
```
|
|
199
238
|
|
|
200
|
-
|
|
201
|
-
`parseBrowserSpec`, `identityFromEnv`, `IDENTITY_PROFILES`, `describeIdentity`, `createIdentityRotator`.
|
|
239
|
+
An empty version is filled per OS (Mac OS `15.6.1`, Windows `10.0.22631`, Linux `6.12.44`, other `1.0.0`).
|
|
202
240
|
|
|
203
|
-
|
|
241
|
+
Presets on `Browsers`: `macOS`, `windows`, `ubuntu`, `linux`, `archLinux`, `android` (experimental), `appropriate` (follows the host OS, distro-aware via `/etc/os-release`), `whatsbibz`.
|
|
204
242
|
|
|
205
|
-
|
|
206
|
-
tempat dengan aturan berbeda, dan BibzWhats menangani ketiganya:
|
|
243
|
+
### What WhatsApp accepts
|
|
207
244
|
|
|
208
|
-
|
|
209
|
-
|---|---|---|---|
|
|
210
|
-
| `DeviceProps.os` (= `browser[0]`) | teks di *Perangkat tertaut* di HP | bebas | dikirim apa adanya: **"Mac OS"**, **"Arch Linux"** |
|
|
211
|
-
| `companion_platform_display` (pairing kode) | validasi `link_code_companion_reg` | **allow-list** — tak dikenal = `400 bad-request`, HP tak dapat notifikasi | diturunkan otomatis ke padanan valid (`derivePairingDisplay`) |
|
|
212
|
-
| `WebInfo.webSubPlatform` (`Desktop` + `syncFullHistory`) | jenis klien desktop | `DARWIN`/`APP_STORE` **ditutup** (428 sebelum QR), `WIN_HYBRID`/`WEB_BROWSER` OK | Mac OS Desktop → `WEB_BROWSER` (riwayat penuh tetap via `requireFullSync`) |
|
|
245
|
+
The identity is used in three places with different rules. Measured against production servers on 2026-09-03:
|
|
213
246
|
|
|
214
|
-
|
|
215
|
-
|
|
247
|
+
| Where | Used for | Server rule | WhatsBibz behaviour |
|
|
248
|
+
|---|---|---|---|
|
|
249
|
+
| `DeviceProps.os` (`browser[0]`) | Text under *Linked devices* | Free text | Sent unchanged — "Arch Linux" shows as "Arch Linux" |
|
|
250
|
+
| `companion_platform_display` (pairing code) | Validation of the pairing request | **Allow-list**; unknown values → `400`, the phone never gets a notification | Derived automatically to a valid value (`derivePairingDisplay`): Arch Linux → `Chrome (Linux)` |
|
|
251
|
+
| `WebInfo.webSubPlatform` (`Desktop` + `syncFullHistory`) | Desktop client type | `DARWIN` / `APP_STORE` are closed (`428` before QR); `WIN_HYBRID` / `WEB_BROWSER` work | Mac OS Desktop → `WEB_BROWSER`, full history still requested |
|
|
216
252
|
|
|
217
|
-
|
|
218
|
-
|
|
253
|
+
| Accepted | Rejected (`400`) |
|
|
254
|
+
|---|---|
|
|
255
|
+
| OS: Mac OS, macOS, Windows, Linux, Ubuntu, Debian, Fedora, CentOS, Gentoo, Manjaro, Chromium OS, Android, iOS | OS: Arch Linux, Arch, GNU/Linux, Mac OS X, Linux Mint, openSUSE, Kali, NixOS, Pop!_OS, FreeBSD, Chrome OS, any product name |
|
|
256
|
+
| Browser: Chrome, Chromium, Firefox, Safari, Edge, Opera, Brave, Vivaldi, Arc | Browser: Desktop, any product name |
|
|
219
257
|
|
|
220
|
-
|
|
221
|
-
await createBibzWhats({ phone, browser: Browsers.archLinux('Chrome') });
|
|
258
|
+
Helpers: `derivePairingDisplay(browser)`, `isPairingDisplayAccepted(str)`, `lintIdentity({ browser, companionPlatformDisplay })`, `resolveDeviceIdentity(opts)`, `parseBrowserSpec(spec)`, `identityFromEnv(env)`, `describeIdentity(browser)`, `IDENTITY_PROFILES`.
|
|
222
259
|
|
|
223
|
-
|
|
224
|
-
await createBibzWhats({ phone, browser: Browsers.appropriate('Chrome') });
|
|
260
|
+
## Sending and reading messages
|
|
225
261
|
|
|
226
|
-
|
|
262
|
+
```js
|
|
263
|
+
import {
|
|
264
|
+
sendText, sendMedia, react, presence, sendWithRetry, splitText, whatsappify,
|
|
265
|
+
extractMessage, unwrapMessage, messageTimestampMs,
|
|
266
|
+
LidMap, digitsOf, pnJid, lidJid, isGroupJid, isLidJid, sameUser, normalizeJid,
|
|
267
|
+
} from '@xbibzlibrary/whatsbibz';
|
|
227
268
|
```
|
|
228
269
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
| Diterima | Ditolak (400) |
|
|
270
|
+
| Helper | What it does |
|
|
232
271
|
|---|---|
|
|
233
|
-
|
|
|
234
|
-
|
|
|
272
|
+
| `sendText(sock, jid, text, { quoted, format, maxLen })` | Splits long text (≤ 4000 chars per message), retries 3×, converts Markdown to WhatsApp formatting when `format: true`. Returns `{ ok, ids, error? }`. |
|
|
273
|
+
| `sendMedia(sock, jid, content, { quoted, fallbackToDocument })` | Sends image/video/audio/document; if the media is refused it is re-sent as a document. |
|
|
274
|
+
| `react(sock, jid, key, emoji)` | Reacts to a message. |
|
|
275
|
+
| `presence(sock, jid, state)` | `composing`, `recording`, `paused`, `available`, `unavailable`. |
|
|
276
|
+
| `sendWithRetry(sock, jid, content, options, { attempts })` | Generic `sendMessage` with retry. |
|
|
277
|
+
| `extractMessage(m)` | Normalises any incoming message to `{ type, text, participant, mentions, quoted, imageMsg \| videoMsg \| … , buttonId, pollName, … }`. Unwraps ephemeral, view-once and edited wrappers. |
|
|
278
|
+
| `LidMap` | Maps LID ↔ phone JIDs: `learnFromMessage(m)`, `canonical(jid)`, `variants(jid)`, `toJSON()` / `fromJSON()`. |
|
|
235
279
|
|
|
236
|
-
|
|
237
|
-
`resolvePairingOs(os)`, `lintIdentity({browser, companionPlatformDisplay})`, `hostOsLabel()`,
|
|
238
|
-
`linuxDistroName()`. Opsi socket baru: `companionPlatformId`, `webSubPlatform` (override eksplisit).
|
|
280
|
+
The raw `sock.sendMessage(jid, content)` supports everything Baileys does: text, image, video, audio, document, sticker, sticker packs, location, contacts, polls, reactions, edits, deletes, pins, forwards, view-once, interactive buttons, product and event messages, newsletters. Builders `Button`, `Carousel` and `AIRich` are exported.
|
|
239
281
|
|
|
240
|
-
|
|
282
|
+
## Low-level API (Baileys-compatible)
|
|
241
283
|
|
|
242
|
-
|
|
284
|
+
```js
|
|
285
|
+
import makeWASocket, {
|
|
286
|
+
useMultiFileAuthState, makeCacheableSignalKeyStore, fetchLatestWaWebVersion,
|
|
287
|
+
DisconnectReason, Browsers, downloadMediaMessage, proto, jidNormalizedUser,
|
|
288
|
+
} from '@xbibzlibrary/whatsbibz';
|
|
243
289
|
|
|
244
|
-
|
|
290
|
+
const { state, saveCreds } = await useMultiFileAuthState('session');
|
|
291
|
+
const { version } = await fetchLatestWaWebVersion();
|
|
292
|
+
const sock = makeWASocket({ version, auth: state, browser: Browsers.macOS('Chrome') });
|
|
293
|
+
sock.ev.on('creds.update', saveCreds);
|
|
294
|
+
```
|
|
245
295
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
| versi WA Web bawaan `2.3000.1046721733` | web.whatsapp.com (2026-09-03) | fallback tidak lagi tertinggal |
|
|
250
|
-
| `requestPairingCode` pakai `query()`, `creds.me` setelah ACK, `companionPlatformDisplay` | PR #2769 | pairing kode gagal kini terdeteksi, sesi tidak teracuni |
|
|
251
|
-
| tctoken: atribut `t`, token kedaluwarsa/tanpa timestamp dibuang, bersarang di `<picture>`, tidak untuk JID sendiri | rc11+, #2607 | `profilePictureUrl` & kirim 1:1 sesuai WA Web |
|
|
252
|
-
| guard `protocolMessage` self-only (history sync / app-state key / LID migration / PDO) | rc12 | pengirim asing tidak bisa memalsukan state lokal |
|
|
253
|
-
| `Browsers.android()` + platform ANDROID (eksperimental) | #2201 | companion Android (bisa terima view-once) |
|
|
254
|
-
| `DARWIN` → `WEB_BROWSER` untuk `Browsers.macOS('Desktop')`; `companion_platform_display` allow-list; `Browsers.archLinux/linux`; `appropriate()` sadar distro | pengukuran BibzWhats 2026-09-03 (belum ada di upstream) | Mac OS Desktop tidak lagi 428; Arch Linux bisa pairing kode |
|
|
255
|
-
| `groupOnlineCount` di presence grup | #2545 | data tambahan `presence.update` |
|
|
256
|
-
| `<presence/>` tidak dikirim pada `creds.update` parsial | PR #2789 | `markOnlineOnConnect:false` dihormati, notifikasi HP tidak tersedot |
|
|
257
|
-
| `downloadContentFromMessage` mengutamakan `directPath` | PR #2778 | hindari `ENOTFOUND a.whatsapp.net` |
|
|
258
|
-
| `lottieStickerMessage` di-unwrap | PR #2776 | stiker Lottie terdeteksi sebagai sticker |
|
|
259
|
-
| guard `dispatcher` fetch (hanya Undici) | #2557 | `https.Agent` tidak bikin fetch error |
|
|
260
|
-
| `ev.destroy()`, `signalRepository.close()`, `registerSocketEndHandler` | #2191 | tidak bocor memori setelah reconnect berulang |
|
|
261
|
-
| `whatsapp-rust-bridge` 0.5.5 | upstream rc14 | dukungan CPU tanpa SIMD |
|
|
262
|
-
|
|
263
|
-
Cek sendiri kapan saja: `node -e "import('@xbibzlibrary/whatsbibz').then(m=>m.fetchLatestWaWebVersion().then(console.log))"`.
|
|
296
|
+
Everything from Baileys v7 / ourin-baileys is exported under the same names. Renames: `Dugong` → `BibzWhatsEngine`, `sock.ourin` → `sock.bibz` (`sock.ourin` kept as an alias). Extra socket options: `companionPlatformDisplay`, `companionPlatformId`, `webSubPlatform`.
|
|
297
|
+
|
|
298
|
+
Additions on top of upstream `master` (see [CHANGELOG.md](CHANGELOG.md) for sources): `WIN32 → WIN_HYBRID` for Windows Desktop, `requestPairingCode` via `query()` with `creds.me` set only after the ACK, tctoken handling, self-only `protocolMessage` guards, `groupOnlineCount`, no `<presence/>` on partial `creds.update`, `directPath`-first media downloads, Lottie sticker unwrapping, `ev.destroy()` / `signalRepository.close()` on socket end, `whatsapp-rust-bridge` 0.5.5.
|
|
264
299
|
|
|
265
300
|
## TypeScript
|
|
266
301
|
|
|
267
|
-
|
|
268
|
-
`tsc --strict`, `moduleResolution: NodeNext`, dan `skipLibCheck: false` — tidak perlu `@types` tambahan selain `@types/node`.
|
|
302
|
+
Type declarations ship with the package, including a complete `WAProto/index.d.ts`. Verified with `tsc --strict`, `moduleResolution: NodeNext` and `skipLibCheck: false`; the only extra you need is `@types/node`.
|
|
269
303
|
|
|
270
304
|
```ts
|
|
271
305
|
import { createBibzWhats, type BibzWhatsClient, type ResolvedIdentity } from '@xbibzlibrary/whatsbibz';
|
|
306
|
+
|
|
272
307
|
const client: BibzWhatsClient = await createBibzWhats({ phone: '628…', identity: 'archLinux:Chrome' });
|
|
273
308
|
client.on('identity-changed', (i) => console.log(i.linkedDeviceName));
|
|
274
309
|
```
|
|
275
310
|
|
|
276
|
-
##
|
|
311
|
+
## Migrating from Baileys / ourin-baileys
|
|
312
|
+
|
|
313
|
+
1. `npm uninstall baileys ourin-baileys && npm install @xbibzlibrary/whatsbibz`
|
|
314
|
+
2. Replace the import specifier. Every export keeps its name.
|
|
315
|
+
3. Remove any `postinstall` patch scripts for `companion_reg_refresh` — the handler is built in.
|
|
316
|
+
4. Optional: replace your own connect/reconnect/pairing loop with `createBibzWhats()`.
|
|
317
|
+
|
|
318
|
+
## Troubleshooting
|
|
319
|
+
|
|
320
|
+
| Symptom | Cause | Fix |
|
|
321
|
+
|---|---|---|
|
|
322
|
+
| Pairing code printed, phone shows nothing | Old libraries print the code before the server confirms it. WhatsBibz only emits `pairing-code` after the ACK — if you still see nothing, the number is wrong or the IP is rate-limited. | Check the digits (country code, no `+`, no leading `0`). Wait 15 minutes if you retried many times (`429`). |
|
|
323
|
+
| `428` immediately, no QR | The advertised identity is refused (e.g. `DARWIN` sub-platform). | Leave `identity` unset (auto rotates), or pick a profile from the table above. |
|
|
324
|
+
| `400 bad-request` at pairing | `companion_platform_display` not on the allow-list. | Don't override `companionPlatformDisplay`; the derived value is always valid. |
|
|
325
|
+
| `401` right after a reconnect while pairing | Previous pairing still pending on the server. | Handled automatically (`reconnecting` with `pairingPending: true`). |
|
|
326
|
+
| `408` loop | WhatsApp Web version too old. | Keep `fetchLatestVersion: true` (default) or update the package. |
|
|
327
|
+
| `give-up` after 3 session wipes | Not a session problem: unregistered number, wrong digits or blocked IP. | Verify the number is active on WhatsApp; try another network. |
|
|
328
|
+
| Handlers stop working after a reconnect | Handlers were attached to the old socket. | Attach them inside `client.on('ready', sock => …)`. |
|
|
329
|
+
| Process won't exit | Something else keeps the loop alive — the client leaves no timers after `close()`. | Check your own intervals; `client.close()` before `process.exit`. |
|
|
330
|
+
|
|
331
|
+
## Testing
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
npm test # 55 offline tests (protocol, identity, pairing controller, lifecycle) — no network
|
|
335
|
+
npm run check # export surface sanity check
|
|
336
|
+
npm run test:live # 11 tests against real WhatsApp servers (no phone needed; uses fictional Ofcom numbers)
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
The live suite covers QR, pairing acknowledgement, automatic rotation on `428` and `400`, custom identities, negative controls and a forced network drop. Full results: [VERIFIKASI-IDENTITAS-2026-09-03.md](VERIFIKASI-IDENTITAS-2026-09-03.md) (Indonesian).
|
|
340
|
+
|
|
341
|
+
## Project structure
|
|
342
|
+
|
|
343
|
+
```
|
|
344
|
+
lib/
|
|
345
|
+
BibzWhats/ client.js (createBibzWhats), device-identity.js, pairing.js, send.js, extract.js, jid.js
|
|
346
|
+
Socket/ socket.js, engine.js, messages-send.js, messages-recv.js, groups.js, newsletter.js, ...
|
|
347
|
+
Utils/ platform-identity.js, browser-utils.js, messages-media.js, use-multi-file-auth-state.js, ...
|
|
348
|
+
Defaults/ Signal/ Types/ WABinary/ WAM/ WAUSync/ VoIP/ Modded/
|
|
349
|
+
WAProto/ protobuf definitions (index.js + complete index.d.ts)
|
|
350
|
+
assets/logo/ logo, icons, favicon
|
|
351
|
+
example/ ping-bot.js
|
|
352
|
+
test/ node:test suites (offline + live)
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
## Versioning and compatibility
|
|
356
|
+
|
|
357
|
+
- Semantic versioning. Breaking changes only in a major release.
|
|
358
|
+
- Built-in WhatsApp Web version is refreshed with every release and fetched live on every connect.
|
|
359
|
+
- Supported Node.js: current LTS lines and current release (20 / 22 / 24 / 26 at the time of writing).
|
|
360
|
+
- Changes are listed in [CHANGELOG.md](CHANGELOG.md).
|
|
361
|
+
|
|
362
|
+
## Contributing
|
|
363
|
+
|
|
364
|
+
Bug reports, measurements against the WhatsApp servers and pull requests are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) first — it explains the test requirements and how to run the live suite safely. Everyone participating is expected to follow the [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
365
|
+
|
|
366
|
+
## Security
|
|
367
|
+
|
|
368
|
+
Do not open public issues for vulnerabilities. See [SECURITY.md](SECURITY.md).
|
|
369
|
+
|
|
370
|
+
## License
|
|
371
|
+
|
|
372
|
+
MIT — © 2026 Xbibz Developer. Based on Baileys, MIT © Rajeh Taher / WhiskeySockets — see [LICENSE](LICENSE) and [LICENSE.upstream](LICENSE.upstream).
|
|
277
373
|
|
|
278
|
-
|
|
279
|
-
- WhatsApp Web API tidak resmi — gunakan nomor khusus, hindari spam (risiko banned).
|
|
280
|
-
- Lisensi MIT (WhatsBibz/BibzWhats) di atas MIT Baileys — lihat `LICENSE` dan `LICENSE.upstream`.
|
|
374
|
+
WhatsBibz is not affiliated with, endorsed by, or supported by WhatsApp or Meta. Use a dedicated number, respect WhatsApp's Terms of Service and do not send unsolicited messages.
|