@neelegirl/baileys 2.1.5 → 2.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,215 +1,1637 @@
1
- <div align="center">
1
+ <div align="center">
2
2
 
3
3
  # @neelegirl/baileys
4
4
 
5
- ### CJS-compatible WhatsApp Web API foundation for the Neelegirl ecosystem
5
+ ### CommonJS WhatsApp Web runtime for Neelegirl projects
6
+ ### Conservative merge strategy based on WhiskeySockets/Baileys
6
7
 
7
- [![Version](https://img.shields.io/badge/Version-2.1.5-ff69b4?style=for-the-badge)](https://www.npmjs.com/package/@neelegirl/baileys)
8
- [![Upstream](https://img.shields.io/badge/Upstream-WhiskeySockets%2FBaileys%207.0.0--rc.9-9b59b6?style=for-the-badge)](https://github.com/WhiskeySockets/Baileys)
9
- [![Node](https://img.shields.io/badge/Node-20%2B-2ea043?style=for-the-badge&logo=node.js)](https://nodejs.org)
10
- [![License](https://img.shields.io/badge/License-MIT-f97316?style=for-the-badge)](LICENSE)
8
+ [![npm version](https://img.shields.io/npm/v/@neelegirl/baileys?style=for-the-badge&color=ff69b4&logo=npm)](https://www.npmjs.com/package/@neelegirl/baileys)
9
+ [![node](https://img.shields.io/badge/node-%3E%3D20-2ea043?style=for-the-badge&logo=node.js)](https://nodejs.org)
10
+ [![license](https://img.shields.io/badge/license-MIT-f97316?style=for-the-badge)](LICENSE)
11
+ [![runtime](https://img.shields.io/badge/runtime-CommonJS-2563eb?style=for-the-badge)](https://www.npmjs.com/package/@neelegirl/baileys)
12
+ [![reference](https://img.shields.io/badge/reference-WhiskeySockets%2FBaileys-111827?style=for-the-badge)](https://github.com/WhiskeySockets/Baileys)
13
+
14
+ ---
11
15
 
12
16
  <p align="center">
13
- <img src="https://files.catbox.moe/phppor.JPG" width="760" alt="Neelegirl Baileys Header" />
17
+ <img src="https://files.catbox.moe/phppor.JPG" width="760" alt="@neelegirl/baileys" />
14
18
  </p>
15
19
 
16
- | Paket | Version | Basis |
20
+ | Package | Version | Main goal |
17
21
  |---|---:|---|
18
- | `@neelegirl/baileys` | `2.1.5` | `WhiskeySockets/Baileys v7.0.0-rc.9` |
22
+ | `@neelegirl/baileys` | `2.1.7` | Stable Neelegirl fork with preserved project-specific runtime behavior |
19
23
 
20
- [Installation](#installation) · [Quickstart](#quickstart) · [Funktionslogik](#funktionslogik) · [Aenderungen](#aenderungen--hinweise)
24
+ [Installation](#installation) · [Quickstart](#quickstart) · [Protected logic](#protected-logic) · [Device and LID notes](#device-and-lid-notes) · [Verified exports](#verified-exports) · [Release notes](#release-notes)
21
25
 
22
26
  </div>
23
27
 
24
28
  ---
25
29
 
26
- ## Inhaltsverzeichnis
30
+ ## Table of Contents
27
31
 
28
- - [Uebersicht](#uebersicht)
32
+ - [Overview](#overview)
33
+ - [Why this fork exists](#why-this-fork-exists)
34
+ - [Protected logic](#protected-logic)
35
+ - [What was updated in 2.1.6](#what-was-updated-in-216)
29
36
  - [Installation](#installation)
37
+ - [Imports](#imports)
30
38
  - [Quickstart](#quickstart)
31
- - [Funktionslogik](#funktionslogik)
32
- - [Aenderungen und Hinweise](#aenderungen--hinweise)
33
- - [libsignal im Stack](#libsignal-im-stack)
34
- - [Word2Web Hinweise](#word2web-hinweise)
35
- - [Kompatibilitaet und Grenzen](#kompatibilitaet-und-grenzen)
36
- - [Changelog](#changelog)
37
- - [Legal](#legal)
39
+ - [Session storage](#session-storage)
40
+ - [Socket configuration notes](#socket-configuration-notes)
41
+ - [Messages and media](#messages-and-media)
42
+ - [Device and LID notes](#device-and-lid-notes)
43
+ - [Event notes](#event-notes)
44
+ - [Verified exports](#verified-exports)
45
+ - [Known limits](#known-limits)
46
+ - [Release notes](#release-notes)
47
+ - [Disclaimer](#disclaimer)
38
48
 
39
- ---
49
+ ## Overview
40
50
 
41
- ## Uebersicht
51
+ `@neelegirl/baileys` is the local CommonJS-oriented Neelegirl fork of Baileys used in this stack. It is meant to keep existing Neelegirl-specific behavior stable while still absorbing compatible fixes from the public WhiskeySockets/Baileys project where that improves correctness.
42
52
 
43
- `@neelegirl/baileys` ist die CJS-orientierte Laufzeitbasis fuer das Neelegirl-Setup. Es uebernimmt die Socket-, Event-, Auth- und Message-Mechanik und bleibt dabei kompatibel zu bestehenden `require()`-Projekten.
53
+ This package was rechecked against the public WhiskeySockets/Baileys repository on `2026-03-19`. The merge strategy is conservative by design:
44
54
 
45
- Wichtige Punkte aus den bisherigen Projekt-READMEs, auf den echten Code gemappt:
55
+ - keep working Neelegirl runtime behavior
56
+ - adopt compatible fixes
57
+ - avoid blind upstream replacement
58
+ - avoid destructive refactors in project-critical paths
46
59
 
47
- - QR-Flow bleibt wie im Projekt vorgesehen erhalten.
48
- - Message-ID-Signatur mit `NEELE` bleibt erhalten.
49
- - LID/JID-bezogene Verarbeitung ist in den Socket/Signal-Pfaden aktiv.
50
- - npm-Update-Check ist enthalten (bei QR-Flow, nur einmal pro Prozess).
51
- - Aktuelle lokale WA-Web-Version: `[2, 3000, 1035194821]`.
60
+ ## Why this fork exists
52
61
 
53
- ---
62
+ The local package differs from upstream for practical reasons:
63
+
64
+ | Area | Intent |
65
+ |---|---|
66
+ | Module format | Keep CommonJS entrypoints and local consumer compatibility |
67
+ | QR flow | Preserve the existing project-specific QR behavior |
68
+ | Message IDs | Preserve `NEELE`-specific message-ID behavior |
69
+ | Device mapping | Keep project-specific platform and device labeling logic |
70
+ | Logging and watch behavior | Avoid breaking existing Neelegirl operational workflows |
71
+ | LID and JID handling | Extend carefully where current Baileys behavior improves compatibility |
72
+
73
+ ## Protected logic
74
+
75
+ The following logic was explicitly treated as protected during maintenance:
76
+
77
+ - QR-code generation and QR lifecycle
78
+ - `NEELE` message-ID generation and related custom handling
79
+ - existing Neelegirl branding and log output
80
+ - existing device, watch, and platform-specific behavior
81
+ - existing custom community and message-stub handling
82
+ - existing message-type behavior for conversation, extended text, media, and context handling
83
+
84
+ Nothing in those areas was blindly replaced with upstream code.
85
+
86
+ ## What was updated in 2.1.6
87
+
88
+ ### Runtime compatibility
89
+
90
+ - fixed the mismatch between `socket.js` expectations and the local Signal repository implementation
91
+ - added the missing runtime LID mapping store
92
+ - aligned session helpers required by the current local socket logic:
93
+ - `lidMapping`
94
+ - `validateSession`
95
+ - `deleteSession`
96
+ - `migrateSession`
97
+
98
+ ### History and identity handling
99
+
100
+ - history sync processing now collects `phoneNumberToLidMappings`
101
+ - inline bootstrap payloads are handled
102
+ - LID migration sync messages are processed conservatively
103
+ - session migration can now follow PN to LID transitions more cleanly
104
+
105
+ ### JID and device helpers
106
+
107
+ - restored and exposed helpers needed by newer Baileys compatibility work:
108
+ - `WAJIDDomains`
109
+ - `getServerFromDomainType`
110
+ - `isPnUser`
111
+ - `isJidMetaAI`
112
+ - `transferDevice`
113
+ - added a compatibility `browser-utils` re-export for `Browsers` and `getPlatformId`
114
+
115
+ ### Typings and docs
116
+
117
+ - refreshed multiple `.d.ts` files to match the actual current runtime more closely
118
+ - removed false README claims from older documentation
119
+ - replaced stale README imagery with the requested current project image
54
120
 
55
121
  ## Installation
56
122
 
123
+ Use npm:
124
+
57
125
  ```bash
58
126
  npm install @neelegirl/baileys
59
127
  ```
60
128
 
61
- Import:
129
+ Use yarn:
130
+
131
+ ```bash
132
+ yarn add @neelegirl/baileys
133
+ ```
134
+
135
+ Runtime requirement:
136
+
137
+ ```text
138
+ Node.js >= 20
139
+ ```
140
+
141
+ ## Imports
142
+
143
+ CommonJS:
62
144
 
63
145
  ```js
64
- // CommonJS
146
+ const makeWASocket = require('@neelegirl/baileys').default
65
147
  const {
66
- default: makeWASocket,
67
- useMultiFileAuthState,
68
- fetchLatestBaileysVersion,
69
- DisconnectReason,
70
148
  Browsers,
149
+ DisconnectReason,
150
+ fetchLatestBaileysVersion,
151
+ useMultiFileAuthState
71
152
  } = require('@neelegirl/baileys')
72
-
73
- // ESM (namespace import auf CJS-Export)
74
- import * as baileys from '@neelegirl/baileys'
75
153
  ```
76
154
 
77
- ---
155
+ ESM:
156
+
157
+ ```js
158
+ import makeWASocket, {
159
+ Browsers,
160
+ DisconnectReason,
161
+ fetchLatestBaileysVersion,
162
+ useMultiFileAuthState
163
+ } from '@neelegirl/baileys'
164
+ ```
78
165
 
79
166
  ## Quickstart
80
167
 
168
+ ### Start with QR
169
+
81
170
  ```js
171
+ const makeWASocket = require('@neelegirl/baileys').default
82
172
  const {
83
- default: makeWASocket,
84
- useMultiFileAuthState,
85
- fetchLatestBaileysVersion,
86
- DisconnectReason,
87
173
  Browsers,
174
+ DisconnectReason,
175
+ fetchLatestBaileysVersion,
176
+ useMultiFileAuthState
88
177
  } = require('@neelegirl/baileys')
89
178
 
90
- async function startBot() {
179
+ async function start() {
91
180
  const { state, saveCreds } = await useMultiFileAuthState('./auth_info')
92
181
  const { version } = await fetchLatestBaileysVersion()
93
182
 
94
183
  const sock = makeWASocket({
95
- auth: state,
96
184
  version,
97
- printQRInTerminal: true,
98
- browser: Browsers.ubuntu('Chrome'),
185
+ auth: state,
186
+ browser: Browsers.ubuntu('Neelegirl'),
187
+ printQRInTerminal: true
99
188
  })
100
189
 
101
190
  sock.ev.on('creds.update', saveCreds)
102
191
 
103
192
  sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
193
+ if (connection === 'open') {
194
+ console.log('connected')
195
+ }
196
+
104
197
  if (connection === 'close') {
105
198
  const code = lastDisconnect?.error?.output?.statusCode
106
- if (code !== DisconnectReason.loggedOut) {
107
- startBot()
199
+ const shouldReconnect = code !== DisconnectReason.loggedOut
200
+ if (shouldReconnect) {
201
+ start()
108
202
  }
109
- return
110
- }
111
-
112
- if (connection === 'open') {
113
- console.log('Connected to WhatsApp')
114
203
  }
115
204
  })
116
205
 
117
206
  sock.ev.on('messages.upsert', async ({ messages }) => {
118
- const msg = messages?.[0]
119
- const text = msg?.message?.conversation || msg?.message?.extendedTextMessage?.text || ''
120
- const jid = msg?.key?.remoteJid
121
- if (jid && text.toLowerCase() === 'ping') {
122
- await sock.sendMessage(jid, { text: 'pong' })
207
+ const msg = messages[0]
208
+ const text =
209
+ msg?.message?.conversation ||
210
+ msg?.message?.extendedTextMessage?.text ||
211
+ ''
212
+
213
+ if (text.toLowerCase() === 'ping') {
214
+ await sock.sendMessage(msg.key.remoteJid, { text: 'pong' })
123
215
  }
124
216
  })
125
217
  }
126
218
 
127
- startBot().catch(console.error)
219
+ start().catch(console.error)
128
220
  ```
129
221
 
130
- ---
222
+ ### Start with pairing code
223
+
224
+ ```js
225
+ const makeWASocket = require('@neelegirl/baileys').default
226
+ const {
227
+ Browsers,
228
+ fetchLatestBaileysVersion,
229
+ useMultiFileAuthState
230
+ } = require('@neelegirl/baileys')
231
+
232
+ async function startPairing() {
233
+ const { state, saveCreds } = await useMultiFileAuthState('./auth_pairing')
234
+ const { version } = await fetchLatestBaileysVersion()
235
+
236
+ const sock = makeWASocket({
237
+ version,
238
+ auth: state,
239
+ browser: Browsers.windows('Neelegirl'),
240
+ printQRInTerminal: false
241
+ })
131
242
 
132
- ## Funktionslogik
243
+ sock.ev.on('creds.update', saveCreds)
133
244
 
134
- ### Runtime und API
245
+ if (!sock.authState.creds.registered) {
246
+ const code = await sock.requestPairingCode('491234567890')
247
+ console.log('pairing code:', code)
248
+ }
249
+ }
135
250
 
136
- - Exporte aus `lib/index.js`:
137
- - `default` / `makeWASocket`
138
- - `Utils`, `Types`, `Store`, `Defaults`, `WABinary`, `WAM`, `WAUSync`, `WAProto`
139
- - CJS-first Struktur (`main: lib/index.js`, `types: lib/index.d.ts`)
251
+ startPairing().catch(console.error)
252
+ ```
140
253
 
141
- ### Ereignisse und Verbindung
254
+ ## Session storage
142
255
 
143
- - `connection.update`, `messages.upsert`, `messages.update`, `creds.update`
144
- - QR wird ueber den normalen Connection-Update-Flow ausgegeben
145
- - Reconnect-Steuerung erfolgt ueber Disconnect-Grund (`DisconnectReason`)
256
+ For development, `useMultiFileAuthState(...)` is the easiest storage helper:
146
257
 
147
- ### Auth und Session
258
+ ```js
259
+ const { state, saveCreds } = await useMultiFileAuthState('./auth_info')
260
+ ```
148
261
 
149
- - `useMultiFileAuthState` fuer persistente Session-Dateien
150
- - Signale/Keys laufen ueber die integrierten Signal-Utilities
262
+ The package also exports:
151
263
 
152
- ### Nachrichten und Hilfsfunktionen
264
+ - `useSingleFileAuthState`
265
+ - `useMongoFileAuthState`
266
+ - `makeInMemoryStore`
153
267
 
154
- - `sendMessage` fuer Text/Medien/reaktionen/polls usw.
155
- - Gruppen-, Community-, Newsletter- und Store-Utilities sind enthalten
156
- - LID/JID-Helfer (`jidDecode`, `jidEncode`, `isLidUser`) stehen ueber die Utility-Exports zur Verfuegung
268
+ If you build a custom store, the critical rule is simple:
157
269
 
158
- ---
270
+ - credential updates must be persisted
271
+ - key updates must be persisted
272
+ - ignoring key-store updates will eventually break message delivery
159
273
 
160
- ## Aenderungen & Hinweise
274
+ ## Socket configuration notes
161
275
 
162
- Diese README uebernimmt die Dokumentationslogik aus den zwei Quell-READMEs und passt sie auf den realen Paketstand an:
276
+ Useful socket options that remain especially relevant in this fork:
163
277
 
164
- - Funktionale Beschreibungen wurden beibehalten und auf echte Exporte reduziert.
165
- - Historische Hinweise wurden bereinigt, wenn sie veraltete Versionen nannten.
166
- - Keine nicht nachweisbaren Features aufgenommen.
278
+ | Option | Why it matters |
279
+ |---|---|
280
+ | `auth` | required session state |
281
+ | `version` | WA Web version selection |
282
+ | `browser` | affects platform/device presentation |
283
+ | `printQRInTerminal` | keeps the existing QR path active |
284
+ | `markOnlineOnConnect` | controls online presence behavior |
285
+ | `syncFullHistory` | enables broader history sync requests |
286
+ | `getMessage` | improves retry and message recovery scenarios |
287
+ | `cachedGroupMetadata` | avoids repeated group fetches |
167
288
 
168
- Technisch relevante Punkte:
289
+ Example:
169
290
 
170
- - QR-Logik unveraendert belassen.
171
- - `NEELE`-Message-ID-Signatur unveraendert belassen.
172
- - Update-Check auf npm-Registry aktiv.
173
- - WA-Web-Version-Datei auf aktuellen lokalen Stand aktualisiert.
291
+ ```js
292
+ const sock = makeWASocket({
293
+ version,
294
+ auth: state,
295
+ browser: Browsers.macOS('Desktop'),
296
+ printQRInTerminal: true,
297
+ markOnlineOnConnect: false,
298
+ syncFullHistory: true,
299
+ getMessage: async (key) => {
300
+ return store.loadMessage(key.remoteJid, key.id)
301
+ },
302
+ cachedGroupMetadata: async (jid) => groupCache.get(jid)
303
+ })
304
+ ```
174
305
 
175
- ---
306
+ ## Messages and media
307
+
308
+ ### Send a text message
176
309
 
177
- ## libsignal im Stack
310
+ ```js
311
+ await sock.sendMessage(jid, { text: 'hello' })
312
+ ```
178
313
 
179
- `@neelegirl/baileys` nutzt `@neelegirl/libsignal` fuer kryptografische Session-Bausteine (Identity, PreKeys, SessionState, Cipher-Operationen). Das ist die Grundlage fuer stabile Multi-Device-Kommunikation.
314
+ ### Reply to a message
180
315
 
181
- ---
316
+ ```js
317
+ await sock.sendMessage(
318
+ jid,
319
+ { text: 'this is a reply' },
320
+ { quoted: originalMessage }
321
+ )
322
+ ```
182
323
 
183
- ## Word2Web Hinweise
324
+ ### Send an image
184
325
 
185
- Es gibt in diesem Paket kein dediziertes Word2Web-Modul. Word2Web-spezifische Logik sollte nur dokumentiert/aktiviert werden, wenn sie in deiner Host-Anwendung wirklich implementiert ist.
326
+ ```js
327
+ await sock.sendMessage(jid, {
328
+ image: { url: './image.jpg' },
329
+ caption: 'sample'
330
+ })
331
+ ```
186
332
 
187
- ---
333
+ ### Send a document
188
334
 
189
- ## Kompatibilitaet und Grenzen
335
+ ```js
336
+ await sock.sendMessage(jid, {
337
+ document: { url: './report.pdf' },
338
+ mimetype: 'application/pdf',
339
+ fileName: 'report.pdf'
340
+ })
341
+ ```
190
342
 
191
- - Node.js: `>=20`
192
- - CJS-fokussiert, nicht als 1:1-ESM-Upstream-Ersatz dokumentiert
193
- - Die API ist auf bestehende Neelegirl-Consumer ausgerichtet
343
+ ### Send a reaction
194
344
 
195
- ---
345
+ ```js
346
+ await sock.sendMessage(jid, {
347
+ react: {
348
+ text: '❤',
349
+ key: message.key
350
+ }
351
+ })
352
+ ```
196
353
 
197
- ## Changelog
354
+ ### Download received media
198
355
 
199
- ### 2.1.5
356
+ ```js
357
+ const { downloadMediaMessage } = require('@neelegirl/baileys')
358
+
359
+ const buffer = await downloadMediaMessage(
360
+ message,
361
+ 'buffer',
362
+ {},
363
+ { logger: sock.logger, reuploadRequest: sock.updateMediaMessage }
364
+ )
365
+ ```
200
366
 
201
- - README inhaltlich mit den Desktop-Quellen zusammengefuehrt (ohne blindes Kopieren)
202
- - Funktionsbeschreibungen, Nutzungslogik und technische Hinweise auf realen Paketstand gemappt
203
- - Versions- und Abhaengigkeitsabgleich im Neelegirl-Stack aktualisiert
204
- - QR-Flow und `NEELE`-Message-ID-Verhalten unveraendert beibehalten
367
+ ## Device and LID notes
205
368
 
206
- ### 2.1.4
369
+ This fork intentionally does more than just plain PN handling.
207
370
 
208
- - Style-/Layout-Refresh fuer konsistente Projektdokumentation
209
- - Publish-Metadaten und CJS-Kompatibilitaet nachgezogen
371
+ ### Relevant helper exports
210
372
 
211
- ---
373
+ - `jidDecode`
374
+ - `jidEncode`
375
+ - `jidNormalizedUser`
376
+ - `isPnUser`
377
+ - `isLidUser`
378
+ - `isHostedPnUser`
379
+ - `isHostedLidUser`
380
+ - `transferDevice`
381
+ - `WAJIDDomains`
382
+
383
+ ### Example: inspect a JID
384
+
385
+ ```js
386
+ const { jidDecode } = require('@neelegirl/baileys')
387
+
388
+ const decoded = jidDecode('491234567890@s.whatsapp.net')
389
+ console.log(decoded)
390
+ ```
391
+
392
+ ### Example: preserve device while switching identity space
393
+
394
+ ```js
395
+ const { transferDevice } = require('@neelegirl/baileys')
396
+
397
+ const result = transferDevice(
398
+ '491234567890:5@s.whatsapp.net',
399
+ '1234567890@lid'
400
+ )
401
+ ```
402
+
403
+ ### Why this matters here
404
+
405
+ Neelegirl-specific code in this package already relies on richer identity handling around:
406
+
407
+ - `remoteJid`
408
+ - `remoteJidAlt`
409
+ - `participant`
410
+ - `participantAlt`
411
+ - sender normalization
412
+ - PN and LID mapping
413
+ - device labeling output
414
+
415
+ That is why the maintenance work kept those paths intact and only extended compatibility where necessary.
416
+
417
+ ## Event notes
418
+
419
+ Useful events in the current runtime:
420
+
421
+ ### Connection lifecycle
422
+
423
+ - `connection.update`
424
+ - `creds.update`
425
+
426
+ ### Message flow
427
+
428
+ - `messages.upsert`
429
+ - `messages.update`
430
+ - `messages.reaction`
431
+ - `message-receipt.update`
432
+
433
+ ### History and metadata
434
+
435
+ - `messaging-history.set`
436
+ - `contacts.upsert`
437
+ - `contacts.update`
438
+ - `chats.update`
439
+
440
+ ### Group and community related
441
+
442
+ - `groups.update`
443
+ - `group-participants.update`
444
+ - `group.join-request`
445
+ - `group.member-tag.update`
446
+ - `communities.update`
447
+
448
+ ### Example
449
+
450
+ ```js
451
+ sock.ev.on('messaging-history.set', ({ chats, contacts, messages, lidPnMappings }) => {
452
+ console.log({
453
+ chats: chats.length,
454
+ contacts: contacts.length,
455
+ messages: messages.length,
456
+ lidPnMappings: lidPnMappings?.length || 0
457
+ })
458
+ })
459
+ ```
460
+
461
+ ## Verified exports
462
+
463
+ The following items were verified in the currently prepared package before publish.
464
+
465
+ ### Socket and auth
466
+
467
+ - `makeWASocket`
468
+ - `useMultiFileAuthState`
469
+ - `useSingleFileAuthState`
470
+ - `useMongoFileAuthState`
471
+ - `makeInMemoryStore`
472
+
473
+ ### Version and browser helpers
474
+
475
+ - `fetchLatestBaileysVersion`
476
+ - `fetchLatestWaWebVersion`
477
+ - `Browsers`
478
+ - `getPlatformId`
479
+
480
+ ### JID and identity helpers
481
+
482
+ - `jidDecode`
483
+ - `jidEncode`
484
+ - `jidNormalizedUser`
485
+ - `isPnUser`
486
+ - `isLidUser`
487
+ - `isHostedPnUser`
488
+ - `isHostedLidUser`
489
+ - `isJidMetaAI`
490
+ - `transferDevice`
491
+ - `WAJIDDomains`
492
+
493
+ ### Message and media helpers
494
+
495
+ - `downloadMediaMessage`
496
+ - `downloadAndProcessHistorySyncNotification`
497
+ - `processHistoryMessage`
498
+ - `getHistoryMsg`
499
+ - `getContentType`
500
+ - `normalizeMessageContent`
501
+ - `generateWAMessage`
502
+ - `generateWAMessageContent`
503
+ - `generateWAMessageFromContent`
504
+
505
+ ### USync helpers
506
+
507
+ - `USyncQuery`
508
+ - `USyncUser`
509
+ - `USyncContactProtocol`
510
+ - `USyncLIDProtocol`
511
+ - `USyncDeviceProtocol`
512
+ - `USyncStatusProtocol`
513
+
514
+ ## Known limits
515
+
516
+ - this package is not a direct one-to-one mirror of every newest upstream internal API
517
+ - no restrictive `exports` map was added because that would risk breaking existing CommonJS consumers
518
+ - some upstream files remain intentionally absent because the local Neelegirl fork structure differs by design
519
+
520
+ ## Deep-dive: message handling
521
+
522
+ This fork pays extra attention to message handling because several Neelegirl-specific customizations already depend on richer metadata than a plain "text or media" abstraction.
523
+
524
+ ### Why message handling is sensitive here
525
+
526
+ The package needs to preserve behavior around:
527
+
528
+ - `conversation`
529
+ - `extendedTextMessage`
530
+ - `imageMessage`
531
+ - `videoMessage`
532
+ - `documentMessage`
533
+ - `contextInfo`
534
+ - `participant`
535
+ - `participantAlt`
536
+ - `remoteJid`
537
+ - `remoteJidAlt`
538
+ - normalized sender values
539
+ - device and platform labels
540
+
541
+ That is why the maintenance pass intentionally avoided broad message-processing rewrites.
542
+
543
+ ### Reading text safely
544
+
545
+ For many bots, the most robust quick read path is still:
546
+
547
+ ```js
548
+ const text =
549
+ message?.message?.conversation ||
550
+ message?.message?.extendedTextMessage?.text ||
551
+ ''
552
+ ```
553
+
554
+ This stays valid because the fork intentionally keeps compatibility with the most common text cases.
555
+
556
+ ### Example: normalize the sender view
557
+
558
+ ```js
559
+ const {
560
+ jidDecode,
561
+ jidNormalizedUser,
562
+ isLidUser,
563
+ isPnUser
564
+ } = require('@neelegirl/baileys')
565
+
566
+ function inspectSender(msg) {
567
+ const raw =
568
+ msg?.key?.participant ||
569
+ msg?.participant ||
570
+ msg?.key?.remoteJid ||
571
+ ''
572
+
573
+ const normalized = jidNormalizedUser(raw)
574
+ const decoded = jidDecode(raw)
575
+
576
+ return {
577
+ raw,
578
+ normalized,
579
+ decoded,
580
+ isPn: isPnUser(raw),
581
+ isLid: isLidUser(raw)
582
+ }
583
+ }
584
+ ```
585
+
586
+ ### Example: handle text, media, and fallback cleanly
587
+
588
+ ```js
589
+ function getPrimaryContent(msg) {
590
+ const m = msg?.message || {}
591
+
592
+ if (m.conversation) {
593
+ return { type: 'conversation', text: m.conversation }
594
+ }
595
+
596
+ if (m.extendedTextMessage?.text) {
597
+ return { type: 'extendedTextMessage', text: m.extendedTextMessage.text }
598
+ }
599
+
600
+ if (m.imageMessage) {
601
+ return {
602
+ type: 'imageMessage',
603
+ caption: m.imageMessage.caption || ''
604
+ }
605
+ }
606
+
607
+ if (m.videoMessage) {
608
+ return {
609
+ type: 'videoMessage',
610
+ caption: m.videoMessage.caption || ''
611
+ }
612
+ }
613
+
614
+ if (m.documentMessage) {
615
+ return {
616
+ type: 'documentMessage',
617
+ fileName: m.documentMessage.fileName || ''
618
+ }
619
+ }
620
+
621
+ return { type: 'unknown' }
622
+ }
623
+ ```
624
+
625
+ ### Conversation vs extended text
626
+
627
+ The classic split is still important:
628
+
629
+ | Field | Typical use |
630
+ |---|---|
631
+ | `conversation` | direct simple text |
632
+ | `extendedTextMessage.text` | richer text message with more surrounding metadata |
633
+
634
+ Bots that only read one of the two will still miss messages in practice.
635
+
636
+ ### Media notes
637
+
638
+ Current helpers still support common media workflows:
639
+
640
+ - send image
641
+ - send video
642
+ - send audio
643
+ - send sticker
644
+ - send document
645
+ - download received media
646
+ - request media re-upload when needed
647
+
648
+ ### Downloading media carefully
649
+
650
+ ```js
651
+ const {
652
+ downloadMediaMessage,
653
+ getContentType
654
+ } = require('@neelegirl/baileys')
655
+
656
+ sock.ev.on('messages.upsert', async ({ messages }) => {
657
+ const msg = messages[0]
658
+ if (!msg?.message) {
659
+ return
660
+ }
661
+
662
+ const type = getContentType(msg.message)
663
+ if (type === 'imageMessage') {
664
+ const buffer = await downloadMediaMessage(
665
+ msg,
666
+ 'buffer',
667
+ {},
668
+ {
669
+ logger: sock.logger,
670
+ reuploadRequest: sock.updateMediaMessage
671
+ }
672
+ )
673
+
674
+ console.log('downloaded image bytes:', buffer.length)
675
+ }
676
+ })
677
+ ```
678
+
679
+ ### Polls, reactions, edits
680
+
681
+ The runtime still supports event flows around:
682
+
683
+ - reactions
684
+ - poll updates
685
+ - message edits
686
+
687
+ This is another reason the current `process-message` path was updated only where necessary.
688
+
689
+ ## Deep-dive: device and browser behavior
690
+
691
+ Device identity matters more than many wrappers admit. In this fork it is especially relevant because the project already uses browser and device strings in a more opinionated way.
692
+
693
+ ### Browser helper examples
694
+
695
+ ```js
696
+ const { Browsers } = require('@neelegirl/baileys')
697
+
698
+ const webProfile = Browsers.ubuntu('Neelegirl')
699
+ const desktopProfile = Browsers.macOS('Desktop')
700
+ const mobileStyleProfile = Browsers.iOS('Neelegirl iOS')
701
+ ```
702
+
703
+ ### `getPlatformId`
704
+
705
+ The compatibility export `getPlatformId` exists so consumers do not have to guess how platform names map into the pairing flow.
706
+
707
+ ```js
708
+ const { getPlatformId } = require('@neelegirl/baileys')
709
+
710
+ console.log(getPlatformId('Chrome'))
711
+ console.log(getPlatformId('Desktop'))
712
+ ```
713
+
714
+ ### Why not flatten device logic
715
+
716
+ During maintenance, device logic was not "simplified" because doing that would risk losing:
717
+
718
+ - Web labels
719
+ - Desktop labels
720
+ - iOS labels
721
+ - Android labels
722
+ - hosted PN and hosted LID distinctions
723
+
724
+ ### Device-aware identity helpers
725
+
726
+ ```js
727
+ const {
728
+ jidDecode,
729
+ transferDevice
730
+ } = require('@neelegirl/baileys')
731
+
732
+ const from = '491234567890:5@s.whatsapp.net'
733
+ const to = '1234567890@lid'
734
+
735
+ console.log(jidDecode(from))
736
+ console.log(transferDevice(from, to))
737
+ ```
738
+
739
+ ### Practical device matrix
740
+
741
+ | Concern | Why it matters |
742
+ |---|---|
743
+ | browser string | affects how the client is presented |
744
+ | platform id | used in pairing-related flows |
745
+ | desktop-like browser | can influence history sync behavior |
746
+ | hosted device space | matters for some LID and hosted identity transitions |
747
+
748
+ ## Deep-dive: JID and LID handling
749
+
750
+ One of the biggest reasons to maintain this fork carefully is identity handling.
751
+
752
+ ### Common identity spaces
753
+
754
+ | Space | Example |
755
+ |---|---|
756
+ | PN user | `491234567890@s.whatsapp.net` |
757
+ | LID user | `1234567890@lid` |
758
+ | hosted PN | `491234567890:99@hosted` |
759
+ | hosted LID | `1234567890:99@hosted.lid` |
760
+
761
+ ### Helpers exposed by the current package
762
+
763
+ - `jidDecode`
764
+ - `jidEncode`
765
+ - `jidNormalizedUser`
766
+ - `isPnUser`
767
+ - `isLidUser`
768
+ - `isHostedPnUser`
769
+ - `isHostedLidUser`
770
+ - `getServerFromDomainType`
771
+ - `transferDevice`
772
+ - `WAJIDDomains`
773
+
774
+ ### Example: decode and route by identity type
775
+
776
+ ```js
777
+ const {
778
+ jidDecode,
779
+ isPnUser,
780
+ isLidUser,
781
+ isHostedPnUser,
782
+ isHostedLidUser
783
+ } = require('@neelegirl/baileys')
784
+
785
+ function classify(jid) {
786
+ return {
787
+ jid,
788
+ decoded: jidDecode(jid),
789
+ pn: !!isPnUser(jid),
790
+ lid: !!isLidUser(jid),
791
+ hostedPn: !!isHostedPnUser(jid),
792
+ hostedLid: !!isHostedLidUser(jid)
793
+ }
794
+ }
795
+ ```
796
+
797
+ ### Example: server from domain type
798
+
799
+ ```js
800
+ const {
801
+ WAJIDDomains,
802
+ getServerFromDomainType
803
+ } = require('@neelegirl/baileys')
804
+
805
+ console.log(getServerFromDomainType('s.whatsapp.net', WAJIDDomains.WHATSAPP))
806
+ console.log(getServerFromDomainType('s.whatsapp.net', WAJIDDomains.LID))
807
+ console.log(getServerFromDomainType('s.whatsapp.net', WAJIDDomains.HOSTED))
808
+ console.log(getServerFromDomainType('s.whatsapp.net', WAJIDDomains.HOSTED_LID))
809
+ ```
810
+
811
+ ### Why this matters to bots
812
+
813
+ If your bot logs sender ids, checks participants, stores device metadata, or combines phone-number and LID records, identity mismatches will show up quickly unless the JID layer is handled carefully.
814
+
815
+ That is exactly why:
816
+
817
+ - the local `jid-utils` was extended
818
+ - history sync now collects LID-to-PN mapping data
819
+ - session migration helpers now exist in the signal repository
820
+
821
+ ## Deep-dive: history sync behavior
822
+
823
+ The current local package now handles history sync more consistently with the existing socket expectations.
824
+
825
+ ### What is processed
826
+
827
+ - conversations
828
+ - contacts
829
+ - messages
830
+ - `phoneNumberToLidMappings`
831
+ - inline bootstrap payloads when present
832
+
833
+ ### What gets emitted
834
+
835
+ The important event remains:
836
+
837
+ ```js
838
+ sock.ev.on('messaging-history.set', (data) => {
839
+ console.log(data)
840
+ })
841
+ ```
842
+
843
+ ### Example: inspect incoming history batches
844
+
845
+ ```js
846
+ sock.ev.on('messaging-history.set', ({ chats, contacts, messages, lidPnMappings, isLatest }) => {
847
+ console.log({
848
+ chats: chats.length,
849
+ contacts: contacts.length,
850
+ messages: messages.length,
851
+ lidPnMappings: lidPnMappings?.length || 0,
852
+ isLatest
853
+ })
854
+ })
855
+ ```
856
+
857
+ ### Why the mapping part matters
858
+
859
+ If you maintain your own sender normalization or account mapping layer, the `lidPnMappings` portion can help reconcile:
860
+
861
+ - phone-number identity space
862
+ - LID identity space
863
+ - device-level migration paths
864
+
865
+ ## Cookbook: common tasks
866
+
867
+ ### Send text
868
+
869
+ ```js
870
+ await sock.sendMessage(jid, { text: 'hello' })
871
+ ```
872
+
873
+ ### Send image with caption
874
+
875
+ ```js
876
+ await sock.sendMessage(jid, {
877
+ image: { url: './image.jpg' },
878
+ caption: 'caption'
879
+ })
880
+ ```
881
+
882
+ ### Send video
883
+
884
+ ```js
885
+ await sock.sendMessage(jid, {
886
+ video: { url: './video.mp4' },
887
+ caption: 'video'
888
+ })
889
+ ```
890
+
891
+ ### Send document
892
+
893
+ ```js
894
+ await sock.sendMessage(jid, {
895
+ document: { url: './report.pdf' },
896
+ mimetype: 'application/pdf',
897
+ fileName: 'report.pdf'
898
+ })
899
+ ```
900
+
901
+ ### Send sticker
902
+
903
+ ```js
904
+ await sock.sendMessage(jid, {
905
+ sticker: { url: './sticker.webp' }
906
+ })
907
+ ```
908
+
909
+ ### Send location
910
+
911
+ ```js
912
+ await sock.sendMessage(jid, {
913
+ location: {
914
+ degreesLatitude: 52.52,
915
+ degreesLongitude: 13.405
916
+ }
917
+ })
918
+ ```
919
+
920
+ ### Send contact
921
+
922
+ ```js
923
+ const vcard = [
924
+ 'BEGIN:VCARD',
925
+ 'VERSION:3.0',
926
+ 'FN:Example Contact',
927
+ 'TEL;type=CELL;type=VOICE;waid=491234567890:+49 123 4567890',
928
+ 'END:VCARD'
929
+ ].join('\n')
930
+
931
+ await sock.sendMessage(jid, {
932
+ contacts: {
933
+ displayName: 'Example Contact',
934
+ contacts: [{ vcard }]
935
+ }
936
+ })
937
+ ```
938
+
939
+ ### Send reaction
940
+
941
+ ```js
942
+ await sock.sendMessage(jid, {
943
+ react: {
944
+ text: '❤',
945
+ key: message.key
946
+ }
947
+ })
948
+ ```
949
+
950
+ ### Remove reaction
951
+
952
+ ```js
953
+ await sock.sendMessage(jid, {
954
+ react: {
955
+ text: '',
956
+ key: message.key
957
+ }
958
+ })
959
+ ```
960
+
961
+ ### Edit a message
962
+
963
+ ```js
964
+ const sent = await sock.sendMessage(jid, { text: 'draft' })
965
+
966
+ await sock.sendMessage(jid, {
967
+ text: 'final text',
968
+ edit: sent.key
969
+ })
970
+ ```
971
+
972
+ ### Delete for everyone
973
+
974
+ ```js
975
+ await sock.sendMessage(jid, {
976
+ delete: message.key
977
+ })
978
+ ```
979
+
980
+ ### Mention a user
981
+
982
+ ```js
983
+ await sock.sendMessage(jid, {
984
+ text: '@491234567890 hello',
985
+ mentions: ['491234567890@s.whatsapp.net']
986
+ })
987
+ ```
988
+
989
+ ### Forward a message
990
+
991
+ ```js
992
+ await sock.sendMessage(jid, {
993
+ forward: originalMessage
994
+ })
995
+ ```
996
+
997
+ ### Send poll
998
+
999
+ ```js
1000
+ await sock.sendMessage(jid, {
1001
+ poll: {
1002
+ name: 'Choose one',
1003
+ values: ['A', 'B', 'C'],
1004
+ selectableCount: 1
1005
+ }
1006
+ })
1007
+ ```
1008
+
1009
+ ## Group and community notes
1010
+
1011
+ The current fork still exposes the usual group-oriented socket methods, and the event layer keeps its extended handling for participant and community metadata.
1012
+
1013
+ ### Example: create a group
1014
+
1015
+ ```js
1016
+ const group = await sock.groupCreate('Example Group', [
1017
+ '491111111111@s.whatsapp.net',
1018
+ '492222222222@s.whatsapp.net'
1019
+ ])
1020
+
1021
+ console.log(group.id)
1022
+ ```
1023
+
1024
+ ### Example: add participants
1025
+
1026
+ ```js
1027
+ await sock.groupParticipantsUpdate(
1028
+ group.id,
1029
+ ['493333333333@s.whatsapp.net'],
1030
+ 'add'
1031
+ )
1032
+ ```
1033
+
1034
+ ### Example: change subject
1035
+
1036
+ ```js
1037
+ await sock.groupUpdateSubject(group.id, 'New Subject')
1038
+ ```
1039
+
1040
+ ### Example: change description
1041
+
1042
+ ```js
1043
+ await sock.groupUpdateDescription(group.id, 'New Description')
1044
+ ```
1045
+
1046
+ ### Example: fetch metadata
1047
+
1048
+ ```js
1049
+ const metadata = await sock.groupMetadata(group.id)
1050
+ console.log(metadata.subject)
1051
+ ```
1052
+
1053
+ ### Event surfaces that matter here
1054
+
1055
+ - `groups.update`
1056
+ - `group-participants.update`
1057
+ - `group.join-request`
1058
+ - `group.member-tag.update`
1059
+ - `communities.update`
1060
+
1061
+ ### Why the fork keeps custom group handling
1062
+
1063
+ The local project already has richer handling around:
1064
+
1065
+ - group author info
1066
+ - participant alternatives
1067
+ - community-specific stubs
1068
+ - label changes
1069
+
1070
+ That is why those paths were preserved instead of normalized down to a simpler generic structure.
1071
+
1072
+ ## Event reference
1073
+
1074
+ The package uses the event-emitter style surface exposed through `sock.ev`.
1075
+
1076
+ ### High-value events
1077
+
1078
+ | Event | Typical use |
1079
+ |---|---|
1080
+ | `connection.update` | login, reconnect, QR lifecycle |
1081
+ | `creds.update` | persist auth state |
1082
+ | `messages.upsert` | incoming messages |
1083
+ | `messages.update` | edits, receipts, state changes |
1084
+ | `messages.reaction` | reaction handling |
1085
+ | `messaging-history.set` | first sync and history batches |
1086
+ | `contacts.update` | contact refresh |
1087
+ | `chats.update` | chat state changes |
1088
+ | `groups.update` | group metadata changes |
1089
+ | `group-participants.update` | participant changes |
1090
+
1091
+ ### Example: connection update
1092
+
1093
+ ```js
1094
+ sock.ev.on('connection.update', (update) => {
1095
+ const { connection, qr, isNewLogin, lastDisconnect } = update
1096
+
1097
+ if (qr) {
1098
+ console.log('qr available')
1099
+ }
1100
+
1101
+ if (isNewLogin) {
1102
+ console.log('new login established')
1103
+ }
1104
+
1105
+ if (connection === 'close') {
1106
+ console.log(lastDisconnect?.error)
1107
+ }
1108
+ })
1109
+ ```
1110
+
1111
+ ### Example: messages upsert
1112
+
1113
+ ```js
1114
+ sock.ev.on('messages.upsert', ({ messages, type }) => {
1115
+ console.log(type, messages.length)
1116
+ })
1117
+ ```
1118
+
1119
+ ### Example: group participants update
1120
+
1121
+ ```js
1122
+ sock.ev.on('group-participants.update', (event) => {
1123
+ console.log({
1124
+ id: event.id,
1125
+ author: event.author,
1126
+ action: event.action,
1127
+ participants: event.participants
1128
+ })
1129
+ })
1130
+ ```
1131
+
1132
+ ### Example: group join requests
1133
+
1134
+ ```js
1135
+ sock.ev.on('group.join-request', (event) => {
1136
+ console.log(event)
1137
+ })
1138
+ ```
1139
+
1140
+ ### Example: reactions
1141
+
1142
+ ```js
1143
+ sock.ev.on('messages.reaction', (items) => {
1144
+ for (const item of items) {
1145
+ console.log(item.reaction)
1146
+ }
1147
+ })
1148
+ ```
1149
+
1150
+ ## Logging notes
1151
+
1152
+ The package continues to work with a `pino`-style logger object. In practice:
1153
+
1154
+ - quiet logs are appropriate for production wrappers
1155
+ - `debug` is helpful when exploring socket flow
1156
+ - `trace` is useful when inspecting binary-node behavior and protocol details
1157
+
1158
+ ### Example
1159
+
1160
+ ```js
1161
+ const pino = require('pino')
1162
+
1163
+ const sock = makeWASocket({
1164
+ version,
1165
+ auth: state,
1166
+ logger: pino({ level: 'info' }),
1167
+ browser: Browsers.ubuntu('Neelegirl'),
1168
+ printQRInTerminal: true
1169
+ })
1170
+ ```
1171
+
1172
+ ### Why logs were preserved
1173
+
1174
+ Neelegirl-specific logging output and watch behavior were explicitly treated as protected. The goal was not to "prettify" logs at the cost of losing operational context.
1175
+
1176
+ ## Update notice
1177
+
1178
+ This package already contains a runtime npm-version check in the current Neelegirl fork.
1179
+
1180
+ ### What it really does
1181
+
1182
+ - it checks the npm registry
1183
+ - it does not self-update
1184
+ - it prints a hint only
1185
+ - it is intentionally lightweight
1186
+
1187
+ ### When it appears
1188
+
1189
+ In the current local fork, the update notice is tied to the existing connection and QR-related flow, and it is designed to run once per process.
1190
+
1191
+ ### Realistic expectation
1192
+
1193
+ If a newer version exists, you still update manually:
1194
+
1195
+ ```bash
1196
+ npm install @neelegirl/baileys@latest
1197
+ ```
1198
+
1199
+ This is the realistic behavior. The package does not automatically replace files in your project.
1200
+
1201
+ ## Troubleshooting
1202
+
1203
+ ### QR is not appearing
1204
+
1205
+ Check:
1206
+
1207
+ - `printQRInTerminal: true`
1208
+ - your auth folder is not already fully logged in
1209
+ - the socket is actually being started
1210
+ - your terminal is not swallowing QR output
1211
+
1212
+ ### Pairing code does not return
1213
+
1214
+ Check:
1215
+
1216
+ - `printQRInTerminal` is disabled for pairing flow
1217
+ - the phone number is passed without `+`
1218
+ - the session is not already registered
1219
+
1220
+ ### Messages are not sending after reconnect
1221
+
1222
+ Check:
1223
+
1224
+ - auth state persistence
1225
+ - key-store persistence
1226
+ - `creds.update` listener
1227
+ - whether your custom store is actually writing signal keys back
1228
+
1229
+ ### Sender ids look inconsistent
1230
+
1231
+ Check whether you are mixing:
1232
+
1233
+ - PN ids
1234
+ - LID ids
1235
+ - hosted PN ids
1236
+ - hosted LID ids
1237
+
1238
+ Normalize before storing or comparing.
1239
+
1240
+ ### History sync looks incomplete
1241
+
1242
+ Check:
1243
+
1244
+ - `syncFullHistory`
1245
+ - browser profile choice
1246
+ - first-login behavior versus reconnect behavior
1247
+ - whether you are handling `messaging-history.set`
1248
+
1249
+ ## FAQ
1250
+
1251
+ ### Is this the official Baileys package?
1252
+
1253
+ No. It is a Neelegirl-maintained fork.
1254
+
1255
+ ### Is it based on public WhiskeySockets/Baileys?
1256
+
1257
+ Yes, but selectively and conservatively.
1258
+
1259
+ ### Does it preserve the custom QR flow?
1260
+
1261
+ Yes.
1262
+
1263
+ ### Does it preserve `NEELE` message IDs?
1264
+
1265
+ Yes.
1266
+
1267
+ ### Does it mirror every upstream internal file?
1268
+
1269
+ No.
1270
+
1271
+ ### Does it include a CLI?
1272
+
1273
+ No.
1274
+
1275
+ ### Does it auto-update itself?
1276
+
1277
+ No. It can show an update hint, but updating remains manual.
1278
+
1279
+ ### Should I use this instead of upstream for Neelegirl projects?
1280
+
1281
+ If your project depends on the current Neelegirl-specific runtime behavior, yes.
1282
+
1283
+ ### Can I still access lower-level helpers?
1284
+
1285
+ Yes. The package exports a broad set of utilities and socket-related helpers.
1286
+
1287
+ ### Why not just overwrite everything with upstream?
1288
+
1289
+ Because that would risk breaking project-specific runtime behavior that already exists locally.
1290
+
1291
+ ### Why are LID helpers emphasized so much?
1292
+
1293
+ Because identity handling is one of the areas most likely to cause subtle regressions in message processing, logging, and sender tracking.
1294
+
1295
+ ## Configuration patterns
1296
+
1297
+ This section is intentionally verbose because configuration details are where many WhatsApp Web client issues begin.
1298
+
1299
+ ### Minimal practical config
1300
+
1301
+ ```js
1302
+ const sock = makeWASocket({
1303
+ version,
1304
+ auth: state,
1305
+ browser: Browsers.ubuntu('Neelegirl'),
1306
+ printQRInTerminal: true
1307
+ })
1308
+ ```
1309
+
1310
+ ### Quiet production-oriented config
1311
+
1312
+ ```js
1313
+ const pino = require('pino')
1314
+
1315
+ const sock = makeWASocket({
1316
+ version,
1317
+ auth: state,
1318
+ browser: Browsers.windows('Neelegirl Bot'),
1319
+ printQRInTerminal: false,
1320
+ logger: pino({ level: 'silent' }),
1321
+ markOnlineOnConnect: false,
1322
+ syncFullHistory: false
1323
+ })
1324
+ ```
1325
+
1326
+ ### Store-aware config
1327
+
1328
+ ```js
1329
+ const sock = makeWASocket({
1330
+ version,
1331
+ auth: state,
1332
+ browser: Browsers.macOS('Desktop'),
1333
+ printQRInTerminal: true,
1334
+ getMessage: async (key) => {
1335
+ return store.loadMessage(key.remoteJid, key.id)
1336
+ },
1337
+ cachedGroupMetadata: async (jid) => {
1338
+ return groupCache.get(jid)
1339
+ }
1340
+ })
1341
+ ```
1342
+
1343
+ ### Config checklist
1344
+
1345
+ | Question | Why to check it |
1346
+ |---|---|
1347
+ | did you pass `auth` | required for login state |
1348
+ | did you persist `creds.update` | prevents key drift |
1349
+ | did you choose an appropriate `browser` | affects presentation and sometimes sync behavior |
1350
+ | did you define `getMessage` if needed | helps retry and recovery flows |
1351
+ | did you define `cachedGroupMetadata` if group-heavy | reduces repeated metadata fetches |
1352
+
1353
+ ## Auth and persistence patterns
1354
+
1355
+ ### Multi-file auth state
1356
+
1357
+ This is usually the easiest place to start:
1358
+
1359
+ ```js
1360
+ const { state, saveCreds } = await useMultiFileAuthState('./auth_info')
1361
+
1362
+ const sock = makeWASocket({
1363
+ version,
1364
+ auth: state,
1365
+ browser: Browsers.ubuntu('Neelegirl'),
1366
+ printQRInTerminal: true
1367
+ })
1368
+
1369
+ sock.ev.on('creds.update', saveCreds)
1370
+ ```
1371
+
1372
+ ### Single-file auth state
1373
+
1374
+ ```js
1375
+ const { state, saveCreds } = await useSingleFileAuthState('./auth.json')
1376
+
1377
+ const sock = makeWASocket({
1378
+ version,
1379
+ auth: state,
1380
+ browser: Browsers.ubuntu('Neelegirl'),
1381
+ printQRInTerminal: true
1382
+ })
1383
+
1384
+ sock.ev.on('creds.update', saveCreds)
1385
+ ```
1386
+
1387
+ ### Mongo-style helper
1388
+
1389
+ If your project uses the local helper for mongo-backed auth state:
1390
+
1391
+ ```js
1392
+ const { state, saveCreds } = await useMongoFileAuthState(mongoCollection)
1393
+ ```
1394
+
1395
+ ### Custom persistence rules
1396
+
1397
+ If you write your own auth store:
1398
+
1399
+ - persist credentials
1400
+ - persist signal keys
1401
+ - persist updates promptly
1402
+ - do not drop `creds.update`
1403
+ - do not ignore key mutations
1404
+
1405
+ ## Store usage
1406
+
1407
+ The package still exports `makeInMemoryStore` for simple local state handling.
1408
+
1409
+ ### Example
1410
+
1411
+ ```js
1412
+ const pino = require('pino')
1413
+ const { makeInMemoryStore } = require('@neelegirl/baileys')
1414
+
1415
+ const store = makeInMemoryStore({
1416
+ logger: pino({ level: 'silent' })
1417
+ })
1418
+
1419
+ store.bind(sock.ev)
1420
+ ```
1421
+
1422
+ ### Typical uses
1423
+
1424
+ - quick development persistence
1425
+ - message lookup for retry helpers
1426
+ - chat cache
1427
+ - contact cache
1428
+
1429
+ ### Caveat
1430
+
1431
+ For serious production systems, build a proper persistent store instead of keeping too much history only in memory.
1432
+
1433
+ ## More cookbook examples
1434
+
1435
+ ### Mark messages as read
1436
+
1437
+ ```js
1438
+ await sock.readMessages([message.key])
1439
+ ```
1440
+
1441
+ ### Update presence
1442
+
1443
+ ```js
1444
+ await sock.sendPresenceUpdate('available', jid)
1445
+ await sock.sendPresenceUpdate('unavailable', jid)
1446
+ ```
1447
+
1448
+ ### Subscribe to another user's presence
1449
+
1450
+ ```js
1451
+ await sock.presenceSubscribe(jid)
1452
+ ```
1453
+
1454
+ ### Fetch profile picture
1455
+
1456
+ ```js
1457
+ const url = await sock.profilePictureUrl(jid, 'image')
1458
+ console.log(url)
1459
+ ```
1460
+
1461
+ ### Fetch status
1462
+
1463
+ ```js
1464
+ const status = await sock.fetchStatus(jid)
1465
+ console.log(status)
1466
+ ```
1467
+
1468
+ ### Check if a number is on WhatsApp
1469
+
1470
+ ```js
1471
+ const [result] = await sock.onWhatsApp('491234567890@s.whatsapp.net')
1472
+ console.log(result)
1473
+ ```
1474
+
1475
+ ### Run a USync query
1476
+
1477
+ ```js
1478
+ const {
1479
+ USyncQuery,
1480
+ USyncUser
1481
+ } = require('@neelegirl/baileys')
1482
+
1483
+ const query = new USyncQuery()
1484
+ .withContactProtocol()
1485
+ .withUser(new USyncUser().withPhone('+491234567890'))
1486
+
1487
+ const result = await sock.executeUSyncQuery(query)
1488
+ console.log(result)
1489
+ ```
1490
+
1491
+ ### Fetch group invite code
1492
+
1493
+ ```js
1494
+ const code = await sock.groupInviteCode(groupId)
1495
+ console.log(code)
1496
+ ```
1497
+
1498
+ ### Accept invite
1499
+
1500
+ ```js
1501
+ const joined = await sock.groupAcceptInvite(code)
1502
+ console.log(joined)
1503
+ ```
1504
+
1505
+ ### Update profile status
1506
+
1507
+ ```js
1508
+ await sock.updateProfileStatus('hello from neelegirl')
1509
+ ```
1510
+
1511
+ ### Update profile name
1512
+
1513
+ ```js
1514
+ await sock.updateProfileName('Neelegirl Bot')
1515
+ ```
1516
+
1517
+ ## Architecture notes
1518
+
1519
+ This local package can be thought of in layers:
1520
+
1521
+ | Layer | Responsibility |
1522
+ |---|---|
1523
+ | socket layer | connection, noise, login, QR, pairing |
1524
+ | utils layer | message building, media handling, parsing, helpers |
1525
+ | binary layer | JID parsing and node encoding/decoding |
1526
+ | signal layer | session crypto, sender keys, LID mapping |
1527
+ | store layer | optional in-memory cache and helpers |
1528
+
1529
+ ### Why the signal layer mattered in this maintenance pass
1530
+
1531
+ The socket already expected LID-aware signal helpers, but the older local `libsignal.js` did not fully provide them. That mismatch was one of the most important actual runtime corrections in the recent update.
1532
+
1533
+ ## Automatic update note
1534
+
1535
+ This package can show an update hint, but it does not auto-patch your installation.
1536
+
1537
+ ### Realistic behavior summary
1538
+
1539
+ | Behavior | Status |
1540
+ |---|---|
1541
+ | check registry | yes |
1542
+ | run once per process | yes |
1543
+ | self-update code | no |
1544
+ | replace files automatically | no |
1545
+ | tell you what to run | yes |
1546
+
1547
+ ### Manual update commands
1548
+
1549
+ ```bash
1550
+ npm install @neelegirl/baileys@latest
1551
+ ```
1552
+
1553
+ ```bash
1554
+ yarn add @neelegirl/baileys@latest
1555
+ ```
1556
+
1557
+ ### Why not self-update
1558
+
1559
+ Auto-replacing package files inside an active bot environment would be risky and surprising. A hint is realistic. Silent mutation of dependencies is not.
1560
+
1561
+ ## Glossary
1562
+
1563
+ ### PN
1564
+
1565
+ Phone-number identity space, typically `@s.whatsapp.net`.
1566
+
1567
+ ### LID
1568
+
1569
+ Linked identity space, typically `@lid`.
1570
+
1571
+ ### hosted PN
1572
+
1573
+ Hosted phone-number identity space, often seen with device-specific hosted forms.
1574
+
1575
+ ### hosted LID
1576
+
1577
+ Hosted LID identity space, often seen when identity and hosted-device concerns intersect.
1578
+
1579
+ ### `participantAlt`
1580
+
1581
+ Project-specific alternate participant metadata preserved in the local fork.
1582
+
1583
+ ### `remoteJidAlt`
1584
+
1585
+ Project-specific alternate remote jid metadata preserved in the local fork.
1586
+
1587
+ ### `senderNormalized`
1588
+
1589
+ A generic phrase used in many bot projects to refer to the stable sender representation after identity reconciliation.
1590
+
1591
+ ## Project policy
1592
+
1593
+ This fork intentionally prioritizes:
1594
+
1595
+ - stable behavior for existing Neelegirl consumers
1596
+ - conservative compatibility updates
1597
+ - readable maintenance over flashy churn
1598
+ - truthful documentation over exaggerated claims
1599
+
1600
+ It intentionally avoids:
1601
+
1602
+ - blind upstream overwrite
1603
+ - destructive export-map tightening
1604
+ - rewriting protected project logic just to look more "modern"
1605
+
1606
+ ## Documentation philosophy
1607
+
1608
+ This README is intentionally longer than a minimal package page because users of this fork usually need:
1609
+
1610
+ - a clear explanation of why the fork exists
1611
+ - reassurance about what custom logic is protected
1612
+ - a practical guide for auth, QR, pairing, and message handling
1613
+ - a realistic statement of what is and is not updated automatically
1614
+
1615
+ ## Release notes
1616
+
1617
+ ### 2.1.7
1618
+
1619
+ - documentation expansion release
1620
+ - Baileys README now includes deep operational guidance and realistic update behavior notes
1621
+ - dependency range aligned to `@neelegirl/libsignal@^1.0.11`
1622
+
1623
+ ### 2.1.6
1624
+
1625
+ - restored runtime consistency between socket logic and Signal repository behavior
1626
+ - added local LID mapping store support
1627
+ - improved history sync processing for LID and PN mapping capture
1628
+ - added current JID helper compatibility exports
1629
+ - refreshed typings and README without touching protected QR and `NEELE` logic
1630
+
1631
+ ### 2.1.5
1632
+
1633
+ - previous local package baseline before the current conservative maintenance pass
212
1634
 
213
- ## Legal
1635
+ ## Disclaimer
214
1636
 
215
- Dieses Projekt ist nicht mit WhatsApp verbunden. Nutzung nur in Uebereinstimmung mit geltendem Recht und Plattformregeln.
1637
+ This project is not affiliated with WhatsApp. Use it responsibly. Do not use it for spam, stalking, or abusive automation.