@neelegirl/baileys 2.1.9 → 2.2.0

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