@neelegirl/baileys 2.1.6 → 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.
Files changed (2) hide show
  1. package/README.md +1102 -1
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -19,7 +19,7 @@
19
19
 
20
20
  | Package | Version | Main goal |
21
21
  |---|---:|---|
22
- | `@neelegirl/baileys` | `2.1.6` | Stable Neelegirl fork with preserved project-specific runtime behavior |
22
+ | `@neelegirl/baileys` | `2.1.7` | Stable Neelegirl fork with preserved project-specific runtime behavior |
23
23
 
24
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
25
 
@@ -517,8 +517,1109 @@ The following items were verified in the currently prepared package before publi
517
517
  - no restrictive `exports` map was added because that would risk breaking existing CommonJS consumers
518
518
  - some upstream files remain intentionally absent because the local Neelegirl fork structure differs by design
519
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
+
520
1615
  ## Release notes
521
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
+
522
1623
  ### 2.1.6
523
1624
 
524
1625
  - restored runtime consistency between socket logic and Signal repository behavior
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neelegirl/baileys",
3
- "version": "2.1.6",
3
+ "version": "2.1.7",
4
4
  "description": "CommonJS Neelegirl Baileys fork with preserved QR/NEELE logic and selective WhiskeySockets/Baileys compatibility updates",
5
5
  "keywords": [
6
6
  "whatsapp",
@@ -44,7 +44,7 @@
44
44
  "@adiwajshing/keyed-db": "^0.2.4",
45
45
  "@cacheable/node-cache": "^1.5.4",
46
46
  "@hapi/boom": "^9.1.3",
47
- "@neelegirl/libsignal": "^1.0.9",
47
+ "@neelegirl/libsignal": "^1.0.11",
48
48
  "async-mutex": "^0.5.0",
49
49
  "audio-decode": "^2.1.3",
50
50
  "axios": "^1.3.3",