@neelegirly/baileys 2.2.20 → 2.2.22

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
@@ -5,9 +5,9 @@
5
5
  ### *Die WhatsApp Web API mit sauberem Neelegirly-Glow-up*
6
6
  ### *QR Branding · Wrapper-Aware Update Notify · LID · Smart Queue*
7
7
 
8
- [![Version](https://img.shields.io/badge/Version-2.2.20-ff69b4?style=for-the-badge&logo=npm)](https://www.npmjs.com/package/@neelegirly/baileys)
9
- [![wa-api](https://img.shields.io/badge/wa--api-1.8.5-c77dff?style=for-the-badge)](https://www.npmjs.com/package/@neelegirly/wa-api)
10
- [![libsignal](https://img.shields.io/badge/libsignal-1.0.29-f4a261?style=for-the-badge)](https://www.npmjs.com/package/@neelegirly/libsignal)
8
+ [![Version](https://img.shields.io/badge/Version-2.2.22-ff69b4?style=for-the-badge&logo=npm)](https://www.npmjs.com/package/@neelegirly/baileys)
9
+ [![wa-api](https://img.shields.io/badge/wa--api-1.8.6-c77dff?style=for-the-badge)](https://www.npmjs.com/package/@neelegirly/wa-api)
10
+ [![libsignal](https://img.shields.io/badge/libsignal-1.0.31-f4a261?style=for-the-badge)](https://www.npmjs.com/package/@neelegirly/libsignal)
11
11
  [![Node](https://img.shields.io/badge/Node-16+-4caf50?style=for-the-badge&logo=node.js)](https://nodejs.org)
12
12
  [![npm](https://img.shields.io/npm/v/%40neelegirly%2Fbaileys?style=for-the-badge&color=ff69b4&logo=npm)](https://www.npmjs.com/package/@neelegirly/baileys)
13
13
 
@@ -15,9 +15,9 @@
15
15
  <img src="https://files.catbox.moe/5bqumy.jpeg" width="780" alt="@neelegirly/baileys Hero" />
16
16
  </p>
17
17
 
18
- <p align="center"><sub>2026 Glow-Up Edition · frische WA-API-, USync- und libsignal-Patches · Companion-Stack auf <strong>2.2.20 / 1.8.5 / 1.0.29</strong></sub></p>
18
+ <p align="center"><sub>2026 Glow-Up Edition · frische WA-API-, USync- und libsignal-Patches · Companion-Stack auf <strong>2.2.22 / 1.8.6 / 1.0.31</strong></sub></p>
19
19
 
20
- [**Installation**](#-installation) · [**Quickstart**](#-quickstart) · [**Highlights**](#-highlights) · [**QR Branding**](#-qr-branding--update-status) · [**Migration**](#-namespace-migration) · [**Release Notes**](#-release-notes-2220)
20
+ [**Installation**](#-installation) · [**Quickstart**](#-quickstart) · [**Highlights**](#-highlights) · [**QR Branding**](#-qr-branding--update-status) · [**Migration**](#-namespace-migration) · [**Release Notes**](#-release-notes-2222)
21
21
 
22
22
  </div>
23
23
 
@@ -42,14 +42,17 @@ Neelegirlys Variante von Baileys ist die WhatsApp-Web-Basis für stabile Bots, s
42
42
 
43
43
  ---
44
44
 
45
- ## 🆕 Was sich in `v2.2.20` geändert hat
45
+ ## 🆕 Was sich in `v2.2.22` geändert hat
46
46
 
47
47
  - ✅ Aktuelle Baileys-Upstream-Fixes vom 24./25. April 2026 sauber übernommen
48
48
  - ✅ AB-Props-Query nutzt wieder den aktuellen `abt`/Protocol-1-Flow
49
49
  - ✅ Username-Felder in Contacts, Gruppenmetadaten, Message Keys und USync ergänzt
50
50
  - ✅ App-State-Sync robuster bei fehlenden Keys, Snapshot-Retry und Reconnects
51
51
  - ✅ Call-Events, Album-Messages und History/Media-Streaming erweitert
52
- - ✅ libsignal-Dependency auf `1.0.29` mit TypeScript-Definitionen und ProtocolAddress-Typen aktualisiert
52
+ - ✅ Baileys-WA-API mit robusteren Group-/Message-Guards, Reachout-/Message-Cap-Abfragen und Newsletter-Join/Leave-IDs aktualisiert
53
+ - ✅ libsignal-Dependency auf `1.0.31` mit TypeScript-Definitionen und ProtocolAddress-Typen aktualisiert
54
+ - ✅ MEX-LID-Mappings werden in die Signal-Store-Anbindung übernommen
55
+ - ✅ Link-Preview-Redirect-Retry und serverseitige MEX-Notifications fuer Reachout/Message-Capping geprueft
53
56
 
54
57
  ---
55
58
 
@@ -57,9 +60,9 @@ Neelegirlys Variante von Baileys ist die WhatsApp-Web-Basis für stabile Bots, s
57
60
 
58
61
  | Paket | Empfohlene Version |
59
62
  | --- | --- |
60
- | `@neelegirly/baileys` | `2.2.20` |
61
- | `@neelegirly/wa-api` | `1.8.5` |
62
- | `@neelegirly/libsignal` | `1.0.29` |
63
+ | `@neelegirly/baileys` | `2.2.22` |
64
+ | `@neelegirly/wa-api` | `1.8.6` |
65
+ | `@neelegirly/libsignal` | `1.0.31` |
63
66
 
64
67
  ---
65
68
 
@@ -68,22 +71,22 @@ Neelegirlys Variante von Baileys ist die WhatsApp-Web-Basis für stabile Bots, s
68
71
  ### npm
69
72
 
70
73
  ```bash
71
- npm install @neelegirly/baileys@2.2.20 @neelegirly/libsignal@1.0.29 --save-exact
74
+ npm install @neelegirly/baileys@2.2.22 @neelegirly/libsignal@1.0.31 --save-exact
72
75
  ```
73
76
 
74
77
  ### yarn
75
78
 
76
79
  ```bash
77
- yarn add @neelegirly/baileys@2.2.20 @neelegirly/libsignal@1.0.29 --exact
80
+ yarn add @neelegirly/baileys@2.2.22 @neelegirly/libsignal@1.0.31 --exact
78
81
  ```
79
82
 
80
83
  ### pnpm
81
84
 
82
85
  ```bash
83
- pnpm add @neelegirly/baileys@2.2.20 @neelegirly/libsignal@1.0.29 --save-exact
86
+ pnpm add @neelegirly/baileys@2.2.22 @neelegirly/libsignal@1.0.31 --save-exact
84
87
  ```
85
88
 
86
- > Für den kompletten Neelegirly-Stack passt dazu `@neelegirly/wa-api@1.8.5`.
89
+ > Für den kompletten Neelegirly-Stack passt dazu `@neelegirly/wa-api@1.8.6`.
87
90
 
88
91
  ---
89
92
 
@@ -136,9 +139,9 @@ start().catch(console.error)
136
139
 
137
140
  | Paket | Rolle |
138
141
  |------|-------|
139
- | `@neelegirly/baileys 2.2.20` | Socket, Events, Messaging |
140
- | `@neelegirly/libsignal 1.0.29` | Signal-Protokoll-Komponente |
141
- | `@neelegirly/wa-api 1.8.5` | Lifecycle-, Session- und Update-Wrapper |
142
+ | `@neelegirly/baileys 2.2.22` | Socket, Events, Messaging |
143
+ | `@neelegirly/libsignal 1.0.31` | Signal-Protokoll-Komponente |
144
+ | `@neelegirly/wa-api 1.8.6` | Lifecycle-, Session- und Update-Wrapper |
142
145
 
143
146
  ---
144
147
 
@@ -148,8 +151,8 @@ Beim QR-Scan werden automatisch Markenzeilen oberhalb und unterhalb des QR-Codes
148
151
 
149
152
  Typische Anzeige:
150
153
 
151
- - `Baileys Update-Status: up to date (2.2.20)`
152
- - `Wrapper Update-Status: up to date (1.8.5)`
154
+ - `Baileys Update-Status: up to date (2.2.22)`
155
+ - `Wrapper Update-Status: up to date (1.8.6)`
153
156
  - Bei echten Updates werden kompakte Hinweise auf `latest` eingeblendet
154
157
 
155
158
  Wenn kein Wrapper-Kontext vorhanden ist, bleibt die Anzeige sauber bei Baileys. Kein unnötiges Drama, nur QR. ✨
@@ -169,7 +172,7 @@ Wenn du direkt prüfen willst:
169
172
  ```ts
170
173
  import { checkNpmVersion } from '@neelegirly/baileys'
171
174
 
172
- const info = await checkNpmVersion('@neelegirly/baileys', '2.2.20', {
175
+ const info = await checkNpmVersion('@neelegirly/baileys', '2.2.22', {
173
176
  githubRepo: 'neelegirly/baileys'
174
177
  })
175
178
 
@@ -189,11 +192,15 @@ Wenn du vom Upstream kommst, nutze den Neelegirly-Scope:
189
192
 
190
193
  ---
191
194
 
192
- ## 📝 Release Notes `2.2.20`
195
+ ## 📝 Release Notes `2.2.22`
193
196
 
194
197
  - 🔧 Upstream-Änderungen vom 24./25. April 2026 portiert, ohne QR-/Update-Notify- oder Message-ID-Handling umzubauen
195
198
  - 🧩 Username-USync und Inbound-Username-Felder für Kontakte, Gruppen und Message Keys ergänzt
196
199
  - 🛡️ App-State-Sync und libsignal-LID/PN-Typen robuster gemacht
197
200
  - 🖼️ Album-Message-Sending und erweiterte Call-Event-Typen ergänzt
198
- - 🔐 libsignal auf `1.0.29` mit WhiskeySockets-TypeScript-Definitionen und ProtocolAddress-Typen gepinnt
199
- - 🔗 Companion-Stack auf `2.2.20 / 1.8.5 / 1.0.29` aktualisiert
201
+ - 🔐 libsignal auf `1.0.31` mit WhiskeySockets-TypeScript-Definitionen und ProtocolAddress-Typen gepinnt
202
+ - 🔗 Companion-Stack auf `2.2.22 / 1.8.6 / 1.0.31` aktualisiert
203
+ - 🛡️ Null-/Undefined-Pfade in Gruppen-, Nachrichten- und Chat-ID-Verarbeitung gehärtet
204
+ - 🧷 MEX-LID-Mappings werden in den Signal-Store übernommen
205
+ - 🧩 Reachout- und Message-Cap-WA-API-Abfragen plus TypeScript-Definitionen ergänzt
206
+ - 🔁 Link-Preview-Redirect-Retry-Counter repariert und Server-Push-MEX-Updates verarbeitet
@@ -189,4 +189,6 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
189
189
  requestPairingCode: (phoneNumber: string, code?: string) => Promise<string>
190
190
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>
191
191
  sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>
192
+ fetchAccountReachoutTimelock: () => Promise<import("../Types").ReachoutTimelockState>
193
+ fetchNewChatMessageCap: () => Promise<import("../Types").NewChatMessageCapInfo>
192
194
  }
@@ -100,4 +100,6 @@ export declare const makeChatsSocket: (config: SocketConfig) => {
100
100
  * requires the last messages till the last message received required for archive & unread
101
101
  */
102
102
  sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>
103
+ fetchAccountReachoutTimelock: () => Promise<import("../Types").ReachoutTimelockState>
104
+ fetchNewChatMessageCap: () => Promise<import("../Types").NewChatMessageCapInfo>
103
105
  }
@@ -224,5 +224,7 @@ export declare const makeCommunitiesSocket: (config: SocketConfig) => {
224
224
  requestPairingCode: (phoneNumber: string, customPairingCode?: string) => Promise<string>;
225
225
  waitForConnectionUpdate: (check: (u: Partial<import("../index.js").ConnectionState>) => Promise<boolean | undefined>, timeoutMs?: number) => Promise<void>;
226
226
  sendWAMBuffer: (wamBuffer: Buffer) => Promise<any>;
227
+ fetchAccountReachoutTimelock: () => Promise<import("../Types").ReachoutTimelockState>;
228
+ fetchNewChatMessageCap: () => Promise<import("../Types").NewChatMessageCapInfo>;
227
229
  };
228
230
  export declare const extractCommunityMetadata: (result: BinaryNode) => GroupMetadata;
@@ -131,6 +131,8 @@ export declare const makeGroupsSocket: (config: SocketConfig) => {
131
131
  requestPairingCode: (phoneNumber: string, code?: string) => Promise<string>
132
132
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>
133
133
  sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>
134
+ fetchAccountReachoutTimelock: () => Promise<import("../Types").ReachoutTimelockState>
135
+ fetchNewChatMessageCap: () => Promise<import("../Types").NewChatMessageCapInfo>
134
136
  }
135
137
 
136
138
  export declare const extractGroupMetadata: (result: BinaryNode) => GroupMetadata
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true })
3
3
 
4
4
  const WAProto_1 = require("../../WAProto")
5
+ const boom_1 = require("@hapi/boom")
5
6
  const Types_1 = require("../Types")
6
7
  const Utils_1 = require("../Utils")
7
8
  const WABinary_1 = require("../WABinary")
@@ -298,6 +299,21 @@ const makeGroupsSocket = (config) => {
298
299
 
299
300
  const extractGroupMetadata = (result) => {
300
301
  const group = WABinary_1.getBinaryNodeChild(result, 'group')
302
+ if (!group) {
303
+ const errorNode = WABinary_1.getBinaryNodeChild(result, 'error')
304
+ if (errorNode) {
305
+ const code = errorNode.attrs.code ? +errorNode.attrs.code : 500
306
+ const text = errorNode.attrs.text || 'group metadata query failed'
307
+ throw new boom_1.Boom(text, { statusCode: code, data: errorNode })
308
+ }
309
+
310
+ throw new boom_1.Boom('Invalid group metadata response: missing <group> node', { data: result })
311
+ }
312
+
313
+ if (!group.attrs.id) {
314
+ throw new boom_1.Boom('Invalid group metadata response: missing group id', { data: group })
315
+ }
316
+
301
317
  const descChild = WABinary_1.getBinaryNodeChild(group, 'description')
302
318
 
303
319
  let desc
@@ -191,6 +191,8 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
191
191
  requestPairingCode: (phoneNumber: string, code?: string) => Promise<string>
192
192
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>
193
193
  sendWAMBuffer: (wamBuffer: Buffer) => Promise<import("..").BinaryNode>
194
+ fetchAccountReachoutTimelock: () => Promise<import("../Types").ReachoutTimelockState>
195
+ fetchNewChatMessageCap: () => Promise<import("../Types").NewChatMessageCapInfo>
194
196
  }
195
197
 
196
198
  export default makeWASocket
@@ -179,4 +179,6 @@ export declare const makeMessagesRecvSocket: (config: SocketConfig) => {
179
179
  requestPairingCode: (phoneNumber: string, code?: string) => Promise<string>
180
180
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>
181
181
  sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>
182
+ fetchAccountReachoutTimelock: () => Promise<import("../Types").ReachoutTimelockState>
183
+ fetchNewChatMessageCap: () => Promise<import("../Types").NewChatMessageCapInfo>
182
184
  }
@@ -20,6 +20,13 @@ const WABinary_1 = require("../WABinary");
20
20
  const groups_1 = require("./groups");
21
21
  const messages_send_1 = require("./messages-send");
22
22
 
23
+ const ENFORCEMENT_TYPE_VALUES = new Set(
24
+ Object.values(Types_1.ReachoutTimelockEnforcementType)
25
+ );
26
+
27
+ const isValidEnforcementType = (value) =>
28
+ typeof value === "string" && ENFORCEMENT_TYPE_VALUES.has(value);
29
+
23
30
  const makeMessagesRecvSocket = (config) => {
24
31
  const {
25
32
  logger,
@@ -48,6 +55,7 @@ const makeMessagesRecvSocket = (config) => {
48
55
  getUSyncDevices,
49
56
  createParticipantNodes,
50
57
  sendPeerDataOperationMessage,
58
+ fetchAccountReachoutTimelock,
51
59
  } = Neele;
52
60
 
53
61
  /** this mutex ensures that each retryRequest will wait for the previous one to finish */
@@ -677,9 +685,124 @@ const makeMessagesRecvSocket = (config) => {
677
685
  }
678
686
  };
679
687
 
680
- const handleMexNotification = (id, node) => {
681
- const operation = node?.attrs?.op_name;
682
- const content = JSON.parse(node?.content);
688
+ const handleReachoutTimelockNotification = (payload) => {
689
+ if (!payload) {
690
+ logger.warn("reachout timelock notification missing payload");
691
+ return;
692
+ }
693
+
694
+ if (!payload.is_active) {
695
+ logger.info("reachout timelock restriction lifted");
696
+ ev.emit("connection.update", {
697
+ reachoutTimeLock: {
698
+ isActive: false,
699
+ enforcementType: Types_1.ReachoutTimelockEnforcementType.DEFAULT,
700
+ },
701
+ });
702
+ return;
703
+ }
704
+
705
+ const timeEnforcementEnds = payload.time_enforcement_ends
706
+ ? new Date(Number.parseInt(payload.time_enforcement_ends, 10) * 1000)
707
+ : new Date(Date.now() + 60_000);
708
+ const enforcementType = isValidEnforcementType(payload.enforcement_type)
709
+ ? payload.enforcement_type
710
+ : Types_1.ReachoutTimelockEnforcementType.DEFAULT;
711
+
712
+ logger.info(
713
+ { enforcementType, timeEnforcementEnds },
714
+ "reachout timelock restriction set"
715
+ );
716
+ ev.emit("connection.update", {
717
+ reachoutTimeLock: {
718
+ isActive: true,
719
+ timeEnforcementEnds,
720
+ enforcementType,
721
+ },
722
+ });
723
+ };
724
+
725
+ const handleMessageCappingNotification = (payload) => {
726
+ if (!payload) {
727
+ logger.warn("message capping notification missing payload");
728
+ return;
729
+ }
730
+
731
+ logger.info({ payload }, "received message capping update");
732
+ ev.emit("message-capping.update", payload);
733
+ };
734
+
735
+ const handleMexNotification = async (id, node) => {
736
+ const updateNode = !node || node.content ? null : WABinary_1.getBinaryNodeChild(node, "update") || WABinary_1.getAllBinaryNodeChildren(node)[0];
737
+ const payloadNode = node?.content ? node : updateNode;
738
+ if (!payloadNode?.content) {
739
+ logger.warn({ node }, "Invalid mex newsletter notification");
740
+ return;
741
+ }
742
+
743
+ let content;
744
+ try {
745
+ const payloadContent = payloadNode.content;
746
+ if (Array.isArray(payloadContent)) {
747
+ logger.warn({ payloadNode }, "Invalid mex newsletter notification payload format");
748
+ return;
749
+ }
750
+
751
+ const contentBuf = typeof payloadContent === "string"
752
+ ? Buffer.from(payloadContent, "binary")
753
+ : Buffer.from(payloadContent);
754
+ content = JSON.parse(contentBuf.toString());
755
+ } catch (error) {
756
+ logger.error({ err: error, node }, "Failed to parse mex newsletter notification");
757
+ return;
758
+ }
759
+
760
+ const operation = content?.operation || payloadNode?.attrs?.op_name || node?.attrs?.op_name;
761
+ if (Array.isArray(content?.errors) && content.errors.length) {
762
+ logger.warn({ errors: content.errors, operation }, "mex notification has GQL errors");
763
+ return;
764
+ }
765
+
766
+ const data = content?.data || {};
767
+
768
+ if (operation === "NotificationUserReachoutTimelockUpdate") {
769
+ handleReachoutTimelockNotification(data.xwa2_notify_account_reachout_timelock);
770
+ return;
771
+ }
772
+
773
+ if (operation === "MessageCappingInfoNotification") {
774
+ handleMessageCappingNotification(data.xwa2_notify_new_chat_messages_capping_info_update);
775
+ return;
776
+ }
777
+
778
+ const linkedProfiles = content?.data?.[Types_1.XWAPathsMexUpdates.LINKED_PROFILES];
779
+ const updates = content?.updates || (linkedProfiles ? [linkedProfiles] : undefined);
780
+
781
+ if (operation === Types_1.MexUpdatesOperations.LINKED_PROFILES) {
782
+ const mappings = [];
783
+ for (const update of updates || []) {
784
+ const lid = normalizeOptionalJid(update?.jid);
785
+ const addedProfiles = Array.isArray(update?.added_profiles) ? update.added_profiles : [];
786
+ for (const profile of addedProfiles) {
787
+ const pn = normalizeOptionalJid(typeof profile === "string" ? profile : (profile?.pn || profile?.jid || ""));
788
+ if (lid && pn) {
789
+ const mapping = { lid, pn };
790
+ ev.emit("lid-mapping.update", mapping);
791
+ mappings.push(mapping);
792
+ }
793
+ }
794
+ }
795
+
796
+ if (mappings.length && signalRepository?.lidMapping?.storeLIDPNMappings) {
797
+ await signalRepository.lidMapping.storeLIDPNMappings(mappings);
798
+ }
799
+ if (mappings.length && signalRepository?.migrateSession) {
800
+ for (const mapping of mappings) {
801
+ await signalRepository.migrateSession(mapping.pn, mapping.lid);
802
+ }
803
+ }
804
+ return;
805
+ }
683
806
 
684
807
  let contentPath;
685
808
  let action;
@@ -777,7 +900,7 @@ const makeMessagesRecvSocket = (config) => {
777
900
  handleNewsletterNotification(node.attrs.from, child);
778
901
  break;
779
902
  case "mex":
780
- handleMexNotification(node.attrs.from, child);
903
+ await handleMexNotification(node.attrs.from, child);
781
904
  break;
782
905
  case "mediaretry":
783
906
  const event = Utils_1.decodeMediaRetryNode(node);
@@ -1635,13 +1758,19 @@ const makeMessagesRecvSocket = (config) => {
1635
1758
  // error in acknowledgement,
1636
1759
  // device could not display the message
1637
1760
  if (attrs.error) {
1761
+ const isReachoutTimelocked = attrs.error === String(Utils_1.NACK_REASONS.SenderReachoutTimelocked);
1762
+ if (isReachoutTimelocked && fetchAccountReachoutTimelock) {
1763
+ await fetchAccountReachoutTimelock().catch((err) =>
1764
+ logger.warn({ err }, "failed to fetch reachout timelock")
1765
+ );
1766
+ }
1638
1767
  logger.warn({ attrs }, "received error in ack");
1639
1768
  ev.emit("messages.update", [
1640
1769
  {
1641
1770
  key,
1642
1771
  update: {
1643
1772
  status: Types_1.WAMessageStatus.ERROR,
1644
- messageStubParameters: [attrs.error],
1773
+ messageStubParameters: isReachoutTimelocked ? [attrs.error, Utils_1.ACCOUNT_RESTRICTED_TEXT] : [attrs.error],
1645
1774
  },
1646
1775
  },
1647
1776
  ]);
@@ -170,4 +170,6 @@ export declare const makeMessagesSocket: (config: SocketConfig) => {
170
170
  requestPairingCode: (phoneNumber: string, code?: string) => Promise<string>
171
171
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>
172
172
  sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>
173
+ fetchAccountReachoutTimelock: () => Promise<import("../Types").ReachoutTimelockState>
174
+ fetchNewChatMessageCap: () => Promise<import("../Types").NewChatMessageCapInfo>
173
175
  }
@@ -558,7 +558,7 @@ const makeMessagesSocket = (config) => {
558
558
  }
559
559
 
560
560
  const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache, useCachedGroupMetadata, statusJidList, additionalNodes, AI = true }) => {
561
- const meId = authState.creds.me.id
561
+ const meId = Utils_1.assertMeId(authState.creds)
562
562
  const meLid = authState.creds.me?.lid
563
563
 
564
564
  let didPushAdditional = false
@@ -1534,4 +1534,4 @@ const makeMessagesSocket = (config) => {
1534
1534
 
1535
1535
  module.exports = {
1536
1536
  makeMessagesSocket
1537
- }
1537
+ }
@@ -147,6 +147,8 @@ export declare const makeNewsletterSocket: (config: SocketConfig) => {
147
147
  requestPairingCode: (phoneNumber: string, code?: string) => Promise<string>
148
148
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>
149
149
  sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>
150
+ fetchAccountReachoutTimelock: () => Promise<import("../Types").ReachoutTimelockState>
151
+ fetchNewChatMessageCap: () => Promise<import("../Types").NewChatMessageCapInfo>
150
152
  }
151
153
 
152
154
  export declare const extractNewsletterMetadata: (node: BinaryNode, isCreate?: boolean) => NewsletterMetadata
@@ -40,6 +40,8 @@ export declare const makeSocket: (config: SocketConfig) => {
40
40
  /** Waits for the connection to WA to reach a state */
41
41
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>
42
42
  sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>
43
+ fetchAccountReachoutTimelock: () => Promise<import("../Types").ReachoutTimelockState>
44
+ fetchNewChatMessageCap: () => Promise<import("../Types").NewChatMessageCapInfo>
43
45
  }
44
46
 
45
- export type Socket = ReturnType<typeof makeSocket>
47
+ export type Socket = ReturnType<typeof makeSocket>
@@ -15,6 +15,7 @@ const BinaryInfo_1 = require("../WAM/BinaryInfo")
15
15
  const USyncQuery_1 = require("../WAUSync/USyncQuery")
16
16
  const USyncUser_1 = require("../WAUSync/USyncUser")
17
17
  const Client_1 = require("./Client")
18
+ const mex_1 = require("./mex")
18
19
 
19
20
  /**
20
21
  * Connects to WA servers and performs:
@@ -690,6 +691,35 @@ const makeSocket = (config) => {
690
691
  ]
691
692
  })
692
693
  }
694
+
695
+ const fetchAccountReachoutTimelock = async () => {
696
+ const queryResult = await mex_1.executeWMexQuery(
697
+ {},
698
+ Types_1.QueryIds.REACHOUT_TIMELOCK,
699
+ Types_1.XWAPaths.REACHOUT_TIMELOCK,
700
+ query,
701
+ generateMessageTag
702
+ )
703
+ const result = {
704
+ isActive: !!queryResult?.is_active,
705
+ timeEnforcementEnds: queryResult?.time_enforcement_ends && queryResult.time_enforcement_ends !== '0'
706
+ ? new Date(parseInt(queryResult.time_enforcement_ends, 10) * 1000)
707
+ : undefined,
708
+ enforcementType: queryResult?.enforcement_type || Types_1.ReachoutTimelockEnforcementType.DEFAULT
709
+ }
710
+ ev.emit('connection.update', { reachoutTimeLock: result })
711
+ return result
712
+ }
713
+
714
+ const fetchNewChatMessageCap = async () => {
715
+ return mex_1.executeWMexQuery(
716
+ { input: { type: 'INDIVIDUAL_NEW_CHAT_MSG' } },
717
+ Types_1.QueryIds.MESSAGE_CAPPING_INFO,
718
+ Types_1.XWAPaths.MESSAGE_CAPPING_INFO,
719
+ query,
720
+ generateMessageTag
721
+ )
722
+ }
693
723
 
694
724
  ws.on('message', onMessageReceived)
695
725
 
@@ -934,6 +964,8 @@ const makeSocket = (config) => {
934
964
  /** Waits for the connection to WA to reach a state */
935
965
  waitForConnectionUpdate: Utils_1.bindWaitForConnectionUpdate(ev),
936
966
  sendWAMBuffer,
967
+ fetchAccountReachoutTimelock,
968
+ fetchNewChatMessageCap,
937
969
  executeUSyncQuery,
938
970
  onWhatsApp
939
971
  }
@@ -9,7 +9,7 @@ import { Label } from './Label'
9
9
  import { LabelAssociation } from './LabelAssociation'
10
10
  import { MessageUpsertType, MessageUserReceiptUpdate, WAMessage, WAMessageKey, WAMessageUpdate } from './Message'
11
11
  import { NewsletterViewRole, SubscriberAction, NewsletterSettingsUpdate } from './Newsletter'
12
- import { ConnectionState } from './State'
12
+ import { ConnectionState, NewChatMessageCapInfo } from './State'
13
13
 
14
14
  export type BaileysEventMap = {
15
15
  /** connection state has been updated -- WS closed, opened, connecting etc. */
@@ -41,6 +41,10 @@ export type BaileysEventMap = {
41
41
  lid: string
42
42
  jid: string
43
43
  }
44
+ 'lid-mapping.update': {
45
+ lid: string
46
+ pn: string
47
+ }
44
48
  /** delete chats with given ID */
45
49
  'chats.delete': string[]
46
50
  /** presence of contact in a chat updated */
@@ -141,6 +145,7 @@ export type BaileysEventMap = {
141
145
  id: string
142
146
  update: NewsletterSettingsUpdate
143
147
  }
148
+ 'message-capping.update': NewChatMessageCapInfo
144
149
  'limit-sharing.update': {
145
150
  id: string
146
151
  author: string
@@ -1,9 +1,11 @@
1
1
  export declare const enum MexUpdatesOperations {
2
2
  OWNER_COMMUNITY = "NotificationCommunityOwnerUpdate",
3
- GROUP_LIMIT_SHARING = "NotificationGroupLimitSharingPropertyUpdate"
3
+ GROUP_LIMIT_SHARING = "NotificationGroupLimitSharingPropertyUpdate",
4
+ LINKED_PROFILES = "NotificationLinkedProfilesUpdates"
4
5
  }
5
6
 
6
- export declare const enum XWAPathsUpdates {
7
+ export declare const enum XWAPathsMexUpdates {
7
8
  GROUP_SHARING_CHANGE = "xwa2_notify_group_on_prop_change",
8
- COMMUNITY_OWNER_CHANGE = "xwa2_notify_group_on_participants_roles_change"
9
- }
9
+ COMMUNITY_OWNER_CHANGE = "xwa2_notify_group_on_participants_roles_change",
10
+ LINKED_PROFILES = "xwa2_notify_linked_profiles"
11
+ }
@@ -3,16 +3,18 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true })
4
4
 
5
5
  const MexUpdatesOperations = {
6
- OWNER_COMMUNITY: "NotificationCommunityOwnerUpdate",
7
- GROUP_LIMIT_SHARING: "NotificationGroupLimitSharingPropertyUpdate"
6
+ OWNER_COMMUNITY: "NotificationCommunityOwnerUpdate",
7
+ GROUP_LIMIT_SHARING: "NotificationGroupLimitSharingPropertyUpdate",
8
+ LINKED_PROFILES: "NotificationLinkedProfilesUpdates"
8
9
  }
9
10
 
10
11
  const XWAPathsMexUpdates = {
11
- GROUP_SHARING_CHANGE: "xwa2_notify_group_on_prop_change",
12
- COMMUNITY_OWNER_CHANGE: "xwa2_notify_group_on_participants_roles_change"
12
+ GROUP_SHARING_CHANGE: "xwa2_notify_group_on_prop_change",
13
+ COMMUNITY_OWNER_CHANGE: "xwa2_notify_group_on_participants_roles_change",
14
+ LINKED_PROFILES: "xwa2_notify_linked_profiles"
13
15
  }
14
16
 
15
17
  module.exports = {
16
18
  MexUpdatesOperations,
17
19
  XWAPathsMexUpdates
18
- }
20
+ }
@@ -90,14 +90,18 @@ export declare const enum XWAPaths {
90
90
  CREATE = "xwa2_newsletter_create",
91
91
  NEWSLETTER = "xwa2_newsletter",
92
92
  SUBSCRIBED = "xwa2_newsletter_subscribed",
93
- METADATA_UPDATE = "xwa2_notify_newsletter_on_metadata_update"
93
+ METADATA_UPDATE = "xwa2_notify_newsletter_on_metadata_update",
94
+ JOIN_V2 = "xwa2_newsletter_join_v2",
95
+ LEAVE_V2 = "xwa2_newsletter_leave_v2",
96
+ REACHOUT_TIMELOCK = "xwa2_fetch_account_reachout_timelock",
97
+ MESSAGE_CAPPING_INFO = "xwa2_message_capping_info"
94
98
  }
95
99
 
96
100
  export declare const enum QueryIds {
97
101
  JOB_MUTATION = "7150902998257522",
98
102
  METADATA = "6620195908089573",
99
- UNFOLLOW = "7238632346214362",
100
- FOLLOW = "7871414976211147",
103
+ UNFOLLOW = "9767147403369991",
104
+ FOLLOW = "24404358912487870",
101
105
  UNMUTE = "7337137176362961",
102
106
  MUTE = "25151904754424642",
103
107
  CREATE = "6996806640408138",
@@ -105,5 +109,7 @@ export declare const enum QueryIds {
105
109
  CHANGE_OWNER = "7341777602580933",
106
110
  DELETE = "8316537688363079",
107
111
  DEMOTE = "6551828931592903",
108
- SUBSCRIBED = "6388546374527196"
109
- }
112
+ SUBSCRIBED = "6388546374527196",
113
+ REACHOUT_TIMELOCK = "23983697327930364",
114
+ MESSAGE_CAPPING_INFO = "24503548349331633"
115
+ }
@@ -15,14 +15,18 @@ const XWAPaths = {
15
15
  CREATE: "xwa2_newsletter_create",
16
16
  NEWSLETTER: "xwa2_newsletter",
17
17
  SUBSCRIBED: "xwa2_newsletter_subscribed",
18
- METADATA_UPDATE: "xwa2_notify_newsletter_on_metadata_update"
18
+ METADATA_UPDATE: "xwa2_notify_newsletter_on_metadata_update",
19
+ JOIN_V2: "xwa2_newsletter_join_v2",
20
+ LEAVE_V2: "xwa2_newsletter_leave_v2",
21
+ REACHOUT_TIMELOCK: "xwa2_fetch_account_reachout_timelock",
22
+ MESSAGE_CAPPING_INFO: "xwa2_message_capping_info"
19
23
  }
20
24
 
21
25
  const QueryIds = {
22
26
  JOB_MUTATION: "7150902998257522",
23
27
  METADATA: "6620195908089573",
24
- UNFOLLOW: "7238632346214362",
25
- FOLLOW: "7871414976211147",
28
+ UNFOLLOW: "9767147403369991",
29
+ FOLLOW: "24404358912487870",
26
30
  UNMUTE: "7337137176362961",
27
31
  MUTE: "25151904754424642",
28
32
  CREATE: "6996806640408138",
@@ -30,11 +34,13 @@ const QueryIds = {
30
34
  CHANGE_OWNER: "7341777602580933",
31
35
  DELETE: "8316537688363079",
32
36
  DEMOTE: "6551828931592903",
33
- SUBSCRIBED: "6388546374527196"
37
+ SUBSCRIBED: "6388546374527196",
38
+ REACHOUT_TIMELOCK: "23983697327930364",
39
+ MESSAGE_CAPPING_INFO: "24503548349331633"
34
40
  }
35
41
 
36
42
  module.exports = {
37
43
  MexOperations,
38
44
  XWAPaths,
39
45
  QueryIds
40
- }
46
+ }
@@ -38,4 +38,67 @@ export type ConnectionState = {
38
38
  * If this is false, the primary phone and other devices will receive notifs
39
39
  * */
40
40
  isOnline?: boolean
41
- }
41
+ /**
42
+ * When this is active, WhatsApp prevents outgoing messages and calls.
43
+ */
44
+ reachoutTimeLock?: ReachoutTimelockState
45
+ }
46
+
47
+ export type ReachoutTimelockState = {
48
+ isActive?: boolean
49
+ timeEnforcementEnds?: Date
50
+ enforcementType?: ReachoutTimelockEnforcementType
51
+ }
52
+
53
+ export declare const enum ReachoutTimelockEnforcementType {
54
+ BIZ_COMMERCE_VIOLATION_ALCOHOL = "BIZ_COMMERCE_VIOLATION_ALCOHOL",
55
+ BIZ_COMMERCE_VIOLATION_ADULT = "BIZ_COMMERCE_VIOLATION_ADULT",
56
+ BIZ_COMMERCE_VIOLATION_ANIMALS = "BIZ_COMMERCE_VIOLATION_ANIMALS",
57
+ BIZ_COMMERCE_VIOLATION_BODY_PARTS_FLUIDS = "BIZ_COMMERCE_VIOLATION_BODY_PARTS_FLUIDS",
58
+ BIZ_COMMERCE_VIOLATION_DATING = "BIZ_COMMERCE_VIOLATION_DATING",
59
+ BIZ_COMMERCE_VIOLATION_DIGITAL_SERVICES_PRODUCTS = "BIZ_COMMERCE_VIOLATION_DIGITAL_SERVICES_PRODUCTS",
60
+ BIZ_COMMERCE_VIOLATION_DRUGS = "BIZ_COMMERCE_VIOLATION_DRUGS",
61
+ BIZ_COMMERCE_VIOLATION_DRUGS_ONLY_OTC = "BIZ_COMMERCE_VIOLATION_DRUGS_ONLY_OTC",
62
+ BIZ_COMMERCE_VIOLATION_GAMBLING = "BIZ_COMMERCE_VIOLATION_GAMBLING",
63
+ BIZ_COMMERCE_VIOLATION_HEALTHCARE = "BIZ_COMMERCE_VIOLATION_HEALTHCARE",
64
+ BIZ_COMMERCE_VIOLATION_REAL_FAKE_CURRENCY = "BIZ_COMMERCE_VIOLATION_REAL_FAKE_CURRENCY",
65
+ BIZ_COMMERCE_VIOLATION_SUPPLEMENTS = "BIZ_COMMERCE_VIOLATION_SUPPLEMENTS",
66
+ BIZ_COMMERCE_VIOLATION_TOBACCO = "BIZ_COMMERCE_VIOLATION_TOBACCO",
67
+ BIZ_COMMERCE_VIOLATION_VIOLENT_CONTENT = "BIZ_COMMERCE_VIOLATION_VIOLENT_CONTENT",
68
+ BIZ_COMMERCE_VIOLATION_WEAPONS = "BIZ_COMMERCE_VIOLATION_WEAPONS",
69
+ BIZ_QUALITY = "BIZ_QUALITY",
70
+ DEFAULT = "DEFAULT",
71
+ WEB_COMPANION_ONLY = "WEB_COMPANION_ONLY"
72
+ }
73
+
74
+ export declare const enum NewChatMessageCappingStatusType {
75
+ NONE = "NONE",
76
+ FIRST_WARNING = "FIRST_WARNING",
77
+ SECOND_WARNING = "SECOND_WARNING",
78
+ CAPPED = "CAPPED"
79
+ }
80
+
81
+ export declare const enum NewChatMessageCappingMVStatusType {
82
+ NOT_ELIGIBLE = "NOT_ELIGIBLE",
83
+ NOT_ACTIVE = "NOT_ACTIVE",
84
+ ACTIVE = "ACTIVE",
85
+ ACTIVE_UPGRADE_AVAILABLE = "ACTIVE_UPGRADE_AVAILABLE"
86
+ }
87
+
88
+ export declare const enum NewChatMessageCappingOTEStatusType {
89
+ NOT_ELIGIBLE = "NOT_ELIGIBLE",
90
+ ELIGIBLE = "ELIGIBLE",
91
+ ACTIVE_IN_CURRENT_CYCLE = "ACTIVE_IN_CURRENT_CYCLE",
92
+ EXHAUSTED = "EXHAUSTED"
93
+ }
94
+
95
+ export type NewChatMessageCapInfo = {
96
+ total_quota?: number
97
+ used_quota?: number
98
+ cycle_start_timestamp?: string
99
+ cycle_end_timestamp?: string
100
+ server_sent_timestamp?: string
101
+ ote_status?: NewChatMessageCappingOTEStatusType
102
+ mv_status?: NewChatMessageCappingMVStatusType
103
+ capping_status?: NewChatMessageCappingStatusType
104
+ }
@@ -9,6 +9,52 @@ const SyncState = {
9
9
  Online: 3
10
10
  }
11
11
 
12
+ const ReachoutTimelockEnforcementType = {
13
+ BIZ_COMMERCE_VIOLATION_ALCOHOL: "BIZ_COMMERCE_VIOLATION_ALCOHOL",
14
+ BIZ_COMMERCE_VIOLATION_ADULT: "BIZ_COMMERCE_VIOLATION_ADULT",
15
+ BIZ_COMMERCE_VIOLATION_ANIMALS: "BIZ_COMMERCE_VIOLATION_ANIMALS",
16
+ BIZ_COMMERCE_VIOLATION_BODY_PARTS_FLUIDS: "BIZ_COMMERCE_VIOLATION_BODY_PARTS_FLUIDS",
17
+ BIZ_COMMERCE_VIOLATION_DATING: "BIZ_COMMERCE_VIOLATION_DATING",
18
+ BIZ_COMMERCE_VIOLATION_DIGITAL_SERVICES_PRODUCTS: "BIZ_COMMERCE_VIOLATION_DIGITAL_SERVICES_PRODUCTS",
19
+ BIZ_COMMERCE_VIOLATION_DRUGS: "BIZ_COMMERCE_VIOLATION_DRUGS",
20
+ BIZ_COMMERCE_VIOLATION_DRUGS_ONLY_OTC: "BIZ_COMMERCE_VIOLATION_DRUGS_ONLY_OTC",
21
+ BIZ_COMMERCE_VIOLATION_GAMBLING: "BIZ_COMMERCE_VIOLATION_GAMBLING",
22
+ BIZ_COMMERCE_VIOLATION_HEALTHCARE: "BIZ_COMMERCE_VIOLATION_HEALTHCARE",
23
+ BIZ_COMMERCE_VIOLATION_REAL_FAKE_CURRENCY: "BIZ_COMMERCE_VIOLATION_REAL_FAKE_CURRENCY",
24
+ BIZ_COMMERCE_VIOLATION_SUPPLEMENTS: "BIZ_COMMERCE_VIOLATION_SUPPLEMENTS",
25
+ BIZ_COMMERCE_VIOLATION_TOBACCO: "BIZ_COMMERCE_VIOLATION_TOBACCO",
26
+ BIZ_COMMERCE_VIOLATION_VIOLENT_CONTENT: "BIZ_COMMERCE_VIOLATION_VIOLENT_CONTENT",
27
+ BIZ_COMMERCE_VIOLATION_WEAPONS: "BIZ_COMMERCE_VIOLATION_WEAPONS",
28
+ BIZ_QUALITY: "BIZ_QUALITY",
29
+ DEFAULT: "DEFAULT",
30
+ WEB_COMPANION_ONLY: "WEB_COMPANION_ONLY"
31
+ }
32
+
33
+ const NewChatMessageCappingStatusType = {
34
+ NONE: "NONE",
35
+ FIRST_WARNING: "FIRST_WARNING",
36
+ SECOND_WARNING: "SECOND_WARNING",
37
+ CAPPED: "CAPPED"
38
+ }
39
+
40
+ const NewChatMessageCappingMVStatusType = {
41
+ NOT_ELIGIBLE: "NOT_ELIGIBLE",
42
+ NOT_ACTIVE: "NOT_ACTIVE",
43
+ ACTIVE: "ACTIVE",
44
+ ACTIVE_UPGRADE_AVAILABLE: "ACTIVE_UPGRADE_AVAILABLE"
45
+ }
46
+
47
+ const NewChatMessageCappingOTEStatusType = {
48
+ NOT_ELIGIBLE: "NOT_ELIGIBLE",
49
+ ELIGIBLE: "ELIGIBLE",
50
+ ACTIVE_IN_CURRENT_CYCLE: "ACTIVE_IN_CURRENT_CYCLE",
51
+ EXHAUSTED: "EXHAUSTED"
52
+ }
53
+
12
54
  module.exports = {
13
- SyncState
14
- }
55
+ SyncState,
56
+ ReachoutTimelockEnforcementType,
57
+ NewChatMessageCappingStatusType,
58
+ NewChatMessageCappingMVStatusType,
59
+ NewChatMessageCappingOTEStatusType
60
+ }
@@ -18,4 +18,6 @@ export declare function makeCacheableSignalKeyStore(store: SignalKeyStore, logge
18
18
  */
19
19
  export declare const addTransactionCapability: (state: SignalKeyStore, logger?: ILogger, { maxCommitRetries, delayBetweenTriesMs }: TransactionCapabilityOptions) => SignalKeyStoreWithTransaction
20
20
 
21
- export declare const initAuthCreds: () => AuthenticationCreds
21
+ export declare const assertMeId: (creds: AuthenticationCreds) => string
22
+
23
+ export declare const initAuthCreds: () => AuthenticationCreds
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "__esModule", { value: true })
8
8
 
9
9
  const crypto_1 = require("crypto")
10
10
  const node_cache_1 = __importDefault(require("@cacheable/node-cache"))
11
+ const boom_1 = require("@hapi/boom")
11
12
  const Defaults_1 = require("../Defaults")
12
13
  const crypto_2 = require("./crypto")
13
14
  const generics_1 = require("./generics")
@@ -175,6 +176,15 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
175
176
  }
176
177
  }
177
178
 
179
+ const assertMeId = (creds) => {
180
+ const id = creds.me?.id
181
+ if (!id) {
182
+ throw new boom_1.Boom('Cannot proceed: socket is not authenticated yet (creds.me.id is missing)', { statusCode: 401 })
183
+ }
184
+
185
+ return id
186
+ }
187
+
178
188
  const initAuthCreds = () => {
179
189
  const identityKey = crypto_2.Curve.generateKeyPair()
180
190
  return {
@@ -201,5 +211,6 @@ const initAuthCreds = () => {
201
211
  module.exports = {
202
212
  makeCacheableSignalKeyStore,
203
213
  addTransactionCapability,
214
+ assertMeId,
204
215
  initAuthCreds
205
- }
216
+ }
@@ -7,7 +7,10 @@ export declare const NO_MESSAGE_FOUND_ERROR_TEXT = "Message absent from node"
7
7
 
8
8
  export declare const MISSING_KEYS_ERROR_TEXT = "Key used already or never filled"
9
9
 
10
+ export declare const ACCOUNT_RESTRICTED_TEXT = "Your account has been restricted"
11
+
10
12
  export declare const NACK_REASONS: {
13
+ SenderReachoutTimelocked: number
11
14
  ParsingError: number
12
15
  UnrecognizedStanza: number
13
16
  UnrecognizedStanzaClass: number
@@ -38,4 +41,4 @@ export declare const decryptMessageNode: (stanza: BinaryNode, meId: string, meLi
38
41
  category: string
39
42
  author: string
40
43
  decrypt(): Promise<void>
41
- }
44
+ }
@@ -12,7 +12,10 @@ const NO_MESSAGE_FOUND_ERROR_TEXT = 'Message absent from node'
12
12
 
13
13
  const MISSING_KEYS_ERROR_TEXT = 'Key used already or never filled'
14
14
 
15
+ const ACCOUNT_RESTRICTED_TEXT = 'Your account has been restricted'
16
+
15
17
  const NACK_REASONS = {
18
+ SenderReachoutTimelocked: 463,
16
19
  ParsingError: 487,
17
20
  UnrecognizedStanza: 488,
18
21
  UnrecognizedStanzaClass: 489,
@@ -43,6 +46,14 @@ function decodeMessageNode(stanza, meId, meLid) {
43
46
  participant = stanza.attrs.participant_pn;
44
47
  }
45
48
  const recipient = stanza.attrs.recipient
49
+ if (!msgId) {
50
+ throw new boom_1.Boom('Invalid message stanza: missing id attribute', { data: stanza })
51
+ }
52
+
53
+ if (!from) {
54
+ throw new boom_1.Boom('Invalid message stanza: missing from attribute', { data: stanza })
55
+ }
56
+
46
57
  const isMe = (jid) => WABinary_1.areJidsSameUser(jid, meId)
47
58
  const isMeLid = (jid) => WABinary_1.areJidsSameUser(jid, meLid)
48
59
  if (WABinary_1.isJidUser(from)) {
@@ -287,6 +298,10 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
287
298
  }
288
299
 
289
300
  module.exports = {
301
+ NO_MESSAGE_FOUND_ERROR_TEXT,
302
+ MISSING_KEYS_ERROR_TEXT,
303
+ ACCOUNT_RESTRICTED_TEXT,
304
+ NACK_REASONS,
290
305
  decodeMessageNode,
291
306
  decryptMessageNode
292
307
  }
@@ -47,7 +47,7 @@ const getCompressedJpegThumbnail = async (url, { thumbnailWidth, fetchOpts }) =>
47
47
  */
48
48
  const getUrlInfo = async (text, opts = { thumbnailWidth: THUMBNAIL_WIDTH_PX, fetchOpts: { timeout: 3000 }}) => {
49
49
  try {
50
- const retries = 0
50
+ let retries = 0
51
51
  const maxRetry = 5
52
52
  const { getLinkPreview } = await Promise.resolve().then(() => __importStar(require('link-preview-js')))
53
53
  let previewLink = text
@@ -66,7 +66,7 @@ const getUrlInfo = async (text, opts = { thumbnailWidth: THUMBNAIL_WIDTH_PX, fet
66
66
  if (forwardedURLObj.hostname === urlObj.hostname
67
67
  || forwardedURLObj.hostname === 'www.' + urlObj.hostname
68
68
  || 'www.' + forwardedURLObj.hostname === urlObj.hostname) {
69
- retries + 1
69
+ retries += 1
70
70
  return true
71
71
  }
72
72
  else {
@@ -117,4 +117,4 @@ const getUrlInfo = async (text, opts = { thumbnailWidth: THUMBNAIL_WIDTH_PX, fet
117
117
 
118
118
  module.exports = {
119
119
  getUrlInfo
120
- }
120
+ }
@@ -1555,7 +1555,7 @@ const patchMessageForMdIfRequired = (message) => {
1555
1555
  if (message?.buttonsMessage ||
1556
1556
  message?.templateMessage ||
1557
1557
  message?.listMessage ||
1558
- message?.interactiveMessage?.nativeFlowMesaage
1558
+ message?.interactiveMessage
1559
1559
  ) {
1560
1560
  message = {
1561
1561
  viewOnceMessageV2Extension: {
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true })
4
4
 
5
5
  const WAProto_1 = require("../../WAProto")
6
+ const boom_1 = require("@hapi/boom")
6
7
  const Types_1 = require("../Types")
7
8
  const messages_1 = require("../Utils/messages")
8
9
  const WABinary_1 = require("../WABinary")
@@ -80,9 +81,21 @@ const shouldIncrementChatUnread = (message) => !message.key.fromMe && !message.m
80
81
  * Typically -- that'll be the remoteJid, but for broadcasts, it'll be the participant
81
82
  */
82
83
  const getChatId = ({ remoteJid, participant, fromMe }) => {
84
+ if (!remoteJid) {
85
+ throw new boom_1.Boom('Cannot derive chat id: message key is missing remoteJid', {
86
+ data: { remoteJid, participant, fromMe }
87
+ })
88
+ }
89
+
83
90
  if (WABinary_1.isJidBroadcast(remoteJid)
84
91
  && !WABinary_1.isJidStatusBroadcast(remoteJid)
85
92
  && !fromMe) {
93
+ if (!participant) {
94
+ throw new boom_1.Boom('Cannot derive chat id: broadcast message key is missing participant', {
95
+ data: { remoteJid, fromMe }
96
+ })
97
+ }
98
+
86
99
  return participant
87
100
  }
88
101
  return remoteJid
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neelegirly/baileys",
3
- "version": "2.2.20",
3
+ "version": "2.2.22",
4
4
  "description": "Neelegirly fork of Baileys: multi-device WhatsApp Web API for Node.js",
5
5
  "keywords": [
6
6
  "whatsapp",
@@ -27,6 +27,7 @@
27
27
  "files": [
28
28
  "lib/**/*",
29
29
  "WAProto/**/*",
30
+ "tsconfig.json",
30
31
  "README.md",
31
32
  "LICENSE"
32
33
  ],
@@ -43,7 +44,7 @@
43
44
  "@adiwajshing/keyed-db": "^0.2.4",
44
45
  "@cacheable/node-cache": "^1.5.4",
45
46
  "@hapi/boom": "^9.1.3",
46
- "@neelegirly/libsignal": "1.0.29",
47
+ "@neelegirly/libsignal": "1.0.31",
47
48
  "async-mutex": "^0.5.0",
48
49
  "audio-decode": "^2.1.3",
49
50
  "axios": "^1.3.3",
@@ -58,7 +59,7 @@
58
59
  "ws": "^8.13.0"
59
60
  },
60
61
  "overrides": {
61
- "@neelegirly/libsignal": "1.0.29"
62
+ "@neelegirly/libsignal": "1.0.31"
62
63
  },
63
64
  "devDependencies": {
64
65
  "@adiwajshing/eslint-config": "github:adiwajshing/eslint-config",
@@ -115,6 +116,7 @@
115
116
  "scripts": {
116
117
  "build:all": "tsc && typedoc",
117
118
  "build:docs": "typedoc",
118
- "build:tsc": "tsc"
119
+ "build:tsc": "tsc",
120
+ "test": "node --check lib/Socket/groups.js && node --check lib/Socket/messages-recv.js && node --check lib/Socket/messages-send.js && node --check lib/Socket/socket.js && node --check lib/Utils/auth-utils.js && node --check lib/Utils/decode-wa-message.js && node --check lib/Utils/process-message.js && node --check lib/Utils/link-preview.js && node -e \"const b=require('./'); if(typeof b.makeWASocket !== 'function' || b.NACK_REASONS.SenderReachoutTimelocked !== 463 || b.QueryIds.FOLLOW !== '24404358912487870') process.exit(1)\""
119
121
  }
120
122
  }
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "allowJs": true,
4
+ "checkJs": false,
5
+ "esModuleInterop": true,
6
+ "module": "commonjs",
7
+ "moduleResolution": "node",
8
+ "noEmit": true,
9
+ "skipLibCheck": true,
10
+ "target": "es2020",
11
+ "types": ["node"]
12
+ },
13
+ "include": ["lib/**/*.js", "lib/**/*.d.ts", "WAProto/**/*.js", "WAProto/**/*.d.ts"],
14
+ "exclude": ["node_modules"]
15
+ }