@baileys-md/baileys 10.1.0 → 11.0.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.
Files changed (122) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1303 -2
  3. package/WAProto/GenerateStatics.sh +3 -0
  4. package/WAProto/WAProto.proto +4633 -0
  5. package/WAProto/fix-imports.js +29 -0
  6. package/WAProto/index.js +13516 -4182
  7. package/lib/Defaults/baileys-version.js +1 -0
  8. package/lib/Defaults/index.js +51 -72
  9. package/lib/Signal/Group/ciphertext-message.js +12 -0
  10. package/lib/Signal/Group/group-session-builder.js +30 -0
  11. package/lib/Signal/Group/group_cipher.js +94 -0
  12. package/lib/Signal/Group/index.js +12 -0
  13. package/lib/Signal/Group/keyhelper.js +19 -0
  14. package/lib/Signal/Group/queue-job.js +54 -0
  15. package/lib/Signal/Group/sender-chain-key.js +32 -0
  16. package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
  17. package/lib/Signal/Group/sender-key-message.js +67 -0
  18. package/lib/Signal/Group/sender-key-name.js +48 -0
  19. package/lib/Signal/Group/sender-key-record.js +50 -0
  20. package/lib/Signal/Group/sender-key-state.js +96 -0
  21. package/{WASignalGroup/sender_message_key.js → lib/Signal/Group/sender-message-key.js} +4 -16
  22. package/lib/Signal/libsignal.js +41 -61
  23. package/lib/Socket/Client/index.js +3 -19
  24. package/lib/Socket/Client/types.js +11 -0
  25. package/lib/Socket/Client/websocket.js +50 -0
  26. package/lib/Socket/business.js +37 -42
  27. package/lib/Socket/chats.js +194 -187
  28. package/lib/Socket/communities.js +351 -0
  29. package/lib/Socket/groups.js +87 -90
  30. package/lib/Socket/index.js +7 -8
  31. package/lib/Socket/messages-recv.js +360 -335
  32. package/lib/Socket/messages-send.js +156 -279
  33. package/lib/Socket/mex.js +42 -0
  34. package/lib/Socket/newsletter.js +144 -213
  35. package/lib/Socket/socket.js +128 -161
  36. package/lib/Socket/usync.js +19 -26
  37. package/lib/Types/Auth.js +2 -2
  38. package/lib/Types/Call.js +2 -2
  39. package/lib/Types/Chat.js +8 -4
  40. package/lib/Types/Contact.js +2 -2
  41. package/lib/Types/Events.js +2 -2
  42. package/lib/Types/GroupMetadata.js +2 -2
  43. package/lib/Types/Label.js +3 -5
  44. package/lib/Types/LabelAssociation.js +3 -5
  45. package/lib/Types/Message.js +7 -7
  46. package/lib/Types/Newsletter.js +30 -17
  47. package/lib/Types/Product.js +2 -2
  48. package/lib/Types/Signal.js +2 -2
  49. package/lib/Types/Socket.js +3 -2
  50. package/lib/Types/State.js +2 -2
  51. package/lib/Types/USync.js +2 -2
  52. package/lib/Types/index.js +15 -31
  53. package/lib/Utils/auth-utils.js +31 -47
  54. package/lib/Utils/baileys-event-stream.js +15 -22
  55. package/lib/Utils/business.js +66 -69
  56. package/lib/Utils/chat-utils.js +200 -195
  57. package/lib/Utils/crypto.js +70 -85
  58. package/lib/Utils/decode-wa-message.js +47 -51
  59. package/lib/Utils/event-buffer.js +36 -46
  60. package/lib/Utils/generics.js +116 -188
  61. package/lib/Utils/history.js +37 -46
  62. package/lib/Utils/index.js +19 -33
  63. package/lib/Utils/link-preview.js +14 -55
  64. package/lib/Utils/logger.js +3 -7
  65. package/lib/Utils/lt-hash.js +23 -26
  66. package/lib/{Store → Utils}/make-in-memory-store.js +19 -27
  67. package/lib/Utils/make-mutex.js +7 -10
  68. package/lib/{Store → Utils}/make-ordered-dictionary.js +1 -3
  69. package/lib/Utils/messages-media.js +236 -368
  70. package/lib/Utils/messages.js +278 -510
  71. package/lib/Utils/noise-handler.js +22 -31
  72. package/lib/{Store → Utils}/object-repository.js +1 -4
  73. package/lib/Utils/process-message.js +144 -148
  74. package/lib/Utils/signal.js +71 -64
  75. package/lib/Utils/use-multi-file-auth-state.js +112 -84
  76. package/lib/Utils/validate-connection.js +72 -115
  77. package/lib/WABinary/constants.js +1281 -20
  78. package/lib/WABinary/decode.js +15 -52
  79. package/lib/WABinary/encode.js +14 -48
  80. package/lib/WABinary/generic-utils.js +31 -39
  81. package/lib/WABinary/index.js +6 -21
  82. package/lib/WABinary/jid-utils.js +23 -40
  83. package/lib/WABinary/types.js +2 -2
  84. package/lib/WAM/BinaryInfo.js +2 -5
  85. package/lib/WAM/constants.js +2257 -2366
  86. package/lib/WAM/encode.js +17 -21
  87. package/lib/WAM/index.js +4 -19
  88. package/lib/WAUSync/Protocols/USyncContactProtocol.js +8 -11
  89. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +11 -14
  90. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +9 -12
  91. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +9 -13
  92. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +20 -22
  93. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +3 -6
  94. package/lib/WAUSync/Protocols/index.js +5 -20
  95. package/lib/WAUSync/USyncQuery.js +34 -32
  96. package/lib/WAUSync/USyncUser.js +2 -5
  97. package/lib/WAUSync/index.js +4 -19
  98. package/lib/index.js +11 -33
  99. package/package.json +25 -54
  100. package/WASignalGroup/GroupProtocol.js +0 -1697
  101. package/WASignalGroup/ciphertext_message.js +0 -16
  102. package/WASignalGroup/group_cipher.js +0 -120
  103. package/WASignalGroup/group_session_builder.js +0 -46
  104. package/WASignalGroup/index.js +0 -5
  105. package/WASignalGroup/keyhelper.js +0 -21
  106. package/WASignalGroup/protobufs.js +0 -3
  107. package/WASignalGroup/queue_job.js +0 -69
  108. package/WASignalGroup/sender_chain_key.js +0 -50
  109. package/WASignalGroup/sender_key_distribution_message.js +0 -78
  110. package/WASignalGroup/sender_key_message.js +0 -92
  111. package/WASignalGroup/sender_key_name.js +0 -70
  112. package/WASignalGroup/sender_key_record.js +0 -56
  113. package/WASignalGroup/sender_key_state.js +0 -129
  114. package/lib/Defaults/baileys-version.json +0 -3
  115. package/lib/Defaults/phonenumber-mcc.json +0 -223
  116. package/lib/Socket/Client/abstract-socket-client.js +0 -13
  117. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  118. package/lib/Socket/Client/web-socket-client.js +0 -62
  119. package/lib/Socket/registration.js +0 -166
  120. package/lib/Store/index.js +0 -8
  121. package/lib/Store/make-cache-manager-store.js +0 -83
  122. package/lib/Store/make-mongo-store.js +0 -567
@@ -1,38 +1,36 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.makeMessagesRecvSocket = void 0;
7
- const boom_1 = require("@hapi/boom");
8
- const crypto_1 = require("crypto");
9
- const node_cache_1 = __importDefault(require("@cacheable/node-cache"));
10
- const WAProto_1 = require("../../WAProto");
11
- const Defaults_1 = require("../Defaults");
12
- const Types_1 = require("../Types");
13
- const Utils_1 = require("../Utils");
14
- const make_mutex_1 = require("../Utils/make-mutex");
15
- const WABinary_1 = require("../WABinary");
16
- const groups_1 = require("./groups");
17
- const messages_send_1 = require("./messages-send");
18
- const makeMessagesRecvSocket = (config) => {
1
+ import NodeCache from '@cacheable/node-cache';
2
+ import { Boom } from '@hapi/boom';
3
+ import { randomBytes } from 'crypto';
4
+ import Long from 'long';
5
+ import { proto } from '../../WAProto/index.js';
6
+ import { DEFAULT_CACHE_TTLS, KEY_BUNDLE_TYPE, MIN_PREKEY_COUNT } from '../Defaults/index.js';
7
+ import { WAMessageStatus, WAMessageStubType } from '../Types/index.js';
8
+ import { aesDecryptCTR, aesEncryptGCM, cleanMessage, Curve, decodeMediaRetryNode, decodeMessageNode, decryptMessageNode, delay, derivePairingCodeKey, encodeBigEndian, encodeSignedDeviceIdentity, getCallStatusFromNode, getHistoryMsg, getNextPreKeys, getStatusFromReceiptType, hkdf, MISSING_KEYS_ERROR_TEXT, NACK_REASONS, NO_MESSAGE_FOUND_ERROR_TEXT, unixTimestampSeconds, xmppPreKey, xmppSignedPreKey } from '../Utils/index.js';
9
+ import { makeMutex } from '../Utils/make-mutex.js';
10
+ import { areJidsSameUser, getAllBinaryNodeChildren, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildren, getBinaryNodeChildString, isJidGroup, isJidStatusBroadcast, isJidUser, jidDecode, jidNormalizedUser, S_WHATSAPP_NET } from '../WABinary/index.js';
11
+ import { extractGroupMetadata } from './groups.js';
12
+ import { makeMessagesSocket } from './messages-send.js';
13
+ export const makeMessagesRecvSocket = (config) => {
19
14
  const { logger, retryRequestDelayMs, maxMsgRetryCount, getMessage, shouldIgnoreJid } = config;
20
- const sock = (0, messages_send_1.makeMessagesSocket)(config);
21
- const { ev, authState, ws, processingMutex, signalRepository, query, upsertMessage, resyncAppState, onUnexpectedError, assertSessions, sendNode, relayMessage, sendReceipt, uploadPreKeys, createParticipantNodes, getUSyncDevices, sendPeerDataOperationMessage, } = sock;
15
+ const sock = makeMessagesSocket(config);
16
+ const { ev, authState, ws, processingMutex, signalRepository, query, upsertMessage, resyncAppState, onUnexpectedError, assertSessions, sendNode, relayMessage, sendReceipt, uploadPreKeys, sendPeerDataOperationMessage } = sock;
22
17
  /** this mutex ensures that each retryRequest will wait for the previous one to finish */
23
- const retryMutex = (0, make_mutex_1.makeMutex)();
24
- const msgRetryCache = config.msgRetryCounterCache || new node_cache_1.default({
25
- stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
26
- useClones: false
27
- });
28
- const callOfferCache = config.callOfferCache || new node_cache_1.default({
29
- stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.CALL_OFFER, // 5 mins
30
- useClones: false
31
- });
32
- const placeholderResendCache = config.placeholderResendCache || new node_cache_1.default({
33
- stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
34
- useClones: false
35
- });
18
+ const retryMutex = makeMutex();
19
+ const msgRetryCache = config.msgRetryCounterCache ||
20
+ new NodeCache({
21
+ stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
22
+ useClones: false
23
+ });
24
+ const callOfferCache = config.callOfferCache ||
25
+ new NodeCache({
26
+ stdTTL: DEFAULT_CACHE_TTLS.CALL_OFFER, // 5 mins
27
+ useClones: false
28
+ });
29
+ const placeholderResendCache = config.placeholderResendCache ||
30
+ new NodeCache({
31
+ stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
32
+ useClones: false
33
+ });
36
34
  let sendActiveReceipts = false;
37
35
  const sendMessageAck = async ({ tag, attrs, content }, errorCode) => {
38
36
  const stanza = {
@@ -52,97 +50,42 @@ const makeMessagesRecvSocket = (config) => {
52
50
  if (!!attrs.recipient) {
53
51
  stanza.attrs.recipient = attrs.recipient;
54
52
  }
55
- if (!!attrs.type && (tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
53
+ if (!!attrs.type &&
54
+ (tag !== 'message' || getBinaryNodeChild({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
56
55
  stanza.attrs.type = attrs.type;
57
56
  }
58
- if (tag === 'message' && (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable')) {
57
+ if (tag === 'message' && getBinaryNodeChild({ tag, attrs, content }, 'unavailable')) {
59
58
  stanza.attrs.from = authState.creds.me.id;
60
59
  }
61
60
  logger.debug({ recv: { tag, attrs }, sent: stanza.attrs }, 'sent ack');
62
61
  await sendNode(stanza);
63
62
  };
64
- const offerCall = async (toJid, isVideo = false) => {
65
- const callId = (0, crypto_1.randomBytes)(16).toString('hex').toUpperCase().substring(0, 64);
66
- const offerContent = [];
67
- offerContent.push({ tag: 'audio', attrs: { enc: 'opus', rate: '16000' }, content: undefined });
68
- offerContent.push({ tag: 'audio', attrs: { enc: 'opus', rate: '8000' }, content: undefined });
69
- if (isVideo) {
70
- offerContent.push({
71
- tag: 'video',
72
- attrs: {
73
- orientation: '0',
74
- 'screen_width': '1920',
75
- 'screen_height': '1080',
76
- 'device_orientation': '0',
77
- enc: 'vp8',
78
- dec: 'vp8',
79
- }
80
- });
81
- }
82
- offerContent.push({ tag: 'net', attrs: { medium: '3' }, content: undefined });
83
- offerContent.push({ tag: 'capability', attrs: { ver: '1' }, content: new Uint8Array([1, 4, 255, 131, 207, 4]) });
84
- offerContent.push({ tag: 'encopt', attrs: { keygen: '2' }, content: undefined });
85
- const encKey = (0, crypto_1.randomBytes)(32);
86
- const devices = (await getUSyncDevices([toJid], true, false)).map(({ user, device }) => (0, WABinary_1.jidEncode)(user, 's.whatsapp.net', device));
87
- await assertSessions(devices, true);
88
- const { nodes: destinations, shouldIncludeDeviceIdentity } = await createParticipantNodes(devices, {
89
- call: {
90
- callKey: encKey
91
- }
92
- });
93
- offerContent.push({ tag: 'destination', attrs: {}, content: destinations });
94
- if (shouldIncludeDeviceIdentity) {
95
- offerContent.push({
96
- tag: 'device-identity',
97
- attrs: {},
98
- content: (0, Utils_1.encodeSignedDeviceIdentity)(authState.creds.account, true)
99
- });
100
- }
101
- const stanza = ({
102
- tag: 'call',
103
- attrs: {
104
- to: toJid,
105
- },
106
- content: [{
107
- tag: 'offer',
108
- attrs: {
109
- 'call-id': callId,
110
- 'call-creator': authState.creds.me.id,
111
- },
112
- content: offerContent,
113
- }],
114
- });
115
- await query(stanza);
116
- return {
117
- callId,
118
- toJid,
119
- isVideo,
120
- };
121
- };
122
63
  const rejectCall = async (callId, callFrom) => {
123
- const stanza = ({
64
+ const stanza = {
124
65
  tag: 'call',
125
66
  attrs: {
126
67
  from: authState.creds.me.id,
127
- to: callFrom,
68
+ to: callFrom
128
69
  },
129
- content: [{
70
+ content: [
71
+ {
130
72
  tag: 'reject',
131
73
  attrs: {
132
74
  'call-id': callId,
133
75
  'call-creator': callFrom,
134
- count: '0',
76
+ count: '0'
135
77
  },
136
- content: undefined,
137
- }],
138
- });
78
+ content: undefined
79
+ }
80
+ ]
81
+ };
139
82
  await query(stanza);
140
83
  };
141
84
  const sendRetryRequest = async (node, forceIncludeKeys = false) => {
142
- const { fullMessage } = (0, Utils_1.decodeMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '');
85
+ const { fullMessage } = decodeMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '');
143
86
  const { key: msgKey } = fullMessage;
144
87
  const msgId = msgKey.id;
145
- const key = `${msgId}:${msgKey === null || msgKey === void 0 ? void 0 : msgKey.participant}`;
88
+ const key = `${msgId}:${msgKey?.participant}`;
146
89
  let retryCount = msgRetryCache.get(key) || 0;
147
90
  if (retryCount >= maxMsgRetryCount) {
148
91
  logger.debug({ retryCount, msgId }, 'reached retry limit, clearing');
@@ -157,7 +100,7 @@ const makeMessagesRecvSocket = (config) => {
157
100
  const msgId = await requestPlaceholderResend(msgKey);
158
101
  logger.debug(`sendRetryRequest: requested placeholder resend for message ${msgId}`);
159
102
  }
160
- const deviceIdentity = (0, Utils_1.encodeSignedDeviceIdentity)(account, true);
103
+ const deviceIdentity = encodeSignedDeviceIdentity(account, true);
161
104
  await authState.keys.transaction(async () => {
162
105
  const receipt = {
163
106
  tag: 'receipt',
@@ -179,7 +122,7 @@ const makeMessagesRecvSocket = (config) => {
179
122
  {
180
123
  tag: 'registration',
181
124
  attrs: {},
182
- content: (0, Utils_1.encodeBigEndian)(authState.creds.registrationId)
125
+ content: encodeBigEndian(authState.creds.registrationId)
183
126
  }
184
127
  ]
185
128
  };
@@ -190,7 +133,7 @@ const makeMessagesRecvSocket = (config) => {
190
133
  receipt.attrs.participant = node.attrs.participant;
191
134
  }
192
135
  if (retryCount > 1 || forceIncludeKeys) {
193
- const { update, preKeys } = await (0, Utils_1.getNextPreKeys)(authState, 1);
136
+ const { update, preKeys } = await getNextPreKeys(authState, 1);
194
137
  const [keyId] = Object.keys(preKeys);
195
138
  const key = preKeys[+keyId];
196
139
  const content = receipt.content;
@@ -198,10 +141,10 @@ const makeMessagesRecvSocket = (config) => {
198
141
  tag: 'keys',
199
142
  attrs: {},
200
143
  content: [
201
- { tag: 'type', attrs: {}, content: Buffer.from(Defaults_1.KEY_BUNDLE_TYPE) },
144
+ { tag: 'type', attrs: {}, content: Buffer.from(KEY_BUNDLE_TYPE) },
202
145
  { tag: 'identity', attrs: {}, content: identityKey.public },
203
- (0, Utils_1.xmppPreKey)(key, +keyId),
204
- (0, Utils_1.xmppSignedPreKey)(signedPreKey),
146
+ xmppPreKey(key, +keyId),
147
+ xmppSignedPreKey(signedPreKey),
205
148
  { tag: 'device-identity', attrs: {}, content: deviceIdentity }
206
149
  ]
207
150
  });
@@ -213,17 +156,17 @@ const makeMessagesRecvSocket = (config) => {
213
156
  };
214
157
  const handleEncryptNotification = async (node) => {
215
158
  const from = node.attrs.from;
216
- if (from === WABinary_1.S_WHATSAPP_NET) {
217
- const countChild = (0, WABinary_1.getBinaryNodeChild)(node, 'count');
159
+ if (from === S_WHATSAPP_NET) {
160
+ const countChild = getBinaryNodeChild(node, 'count');
218
161
  const count = +countChild.attrs.value;
219
- const shouldUploadMorePreKeys = count < Defaults_1.MIN_PREKEY_COUNT;
162
+ const shouldUploadMorePreKeys = count < MIN_PREKEY_COUNT;
220
163
  logger.debug({ count, shouldUploadMorePreKeys }, 'recv pre-key count');
221
164
  if (shouldUploadMorePreKeys) {
222
165
  await uploadPreKeys();
223
166
  }
224
167
  }
225
168
  else {
226
- const identityNode = (0, WABinary_1.getBinaryNodeChild)(node, 'identity');
169
+ const identityNode = getBinaryNodeChild(node, 'identity');
227
170
  if (identityNode) {
228
171
  logger.info({ jid: from }, 'identity changed');
229
172
  // not handling right now
@@ -235,37 +178,40 @@ const makeMessagesRecvSocket = (config) => {
235
178
  }
236
179
  };
237
180
  const handleGroupNotification = (participant, child, msg) => {
238
- var _a, _b, _c, _d;
239
- const participantJid = ((_b = (_a = (0, WABinary_1.getBinaryNodeChild)(child, 'participant')) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.jid) || participant;
240
- switch (child === null || child === void 0 ? void 0 : child.tag) {
181
+ const participantJid = getBinaryNodeChild(child, 'participant')?.attrs?.jid || participant;
182
+ switch (child?.tag) {
241
183
  case 'create':
242
- const metadata = (0, groups_1.extractGroupMetadata)(child);
243
- msg.messageStubType = Types_1.WAMessageStubType.GROUP_CREATE;
184
+ const metadata = extractGroupMetadata(child);
185
+ msg.messageStubType = WAMessageStubType.GROUP_CREATE;
244
186
  msg.messageStubParameters = [metadata.subject];
245
187
  msg.key = { participant: metadata.owner };
246
- ev.emit('chats.upsert', [{
188
+ ev.emit('chats.upsert', [
189
+ {
247
190
  id: metadata.id,
248
191
  name: metadata.subject,
249
- conversationTimestamp: metadata.creation,
250
- }]);
251
- ev.emit('groups.upsert', [{
192
+ conversationTimestamp: metadata.creation
193
+ }
194
+ ]);
195
+ ev.emit('groups.upsert', [
196
+ {
252
197
  ...metadata,
253
198
  author: participant
254
- }]);
199
+ }
200
+ ]);
255
201
  break;
256
202
  case 'ephemeral':
257
203
  case 'not_ephemeral':
258
204
  msg.message = {
259
205
  protocolMessage: {
260
- type: WAProto_1.proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
206
+ type: proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
261
207
  ephemeralExpiration: +(child.attrs.expiration || 0)
262
208
  }
263
209
  };
264
210
  break;
265
211
  case 'modify':
266
- const oldNumber = (0, WABinary_1.getBinaryNodeChildren)(child, 'participant').map(p => p.attrs.jid);
212
+ const oldNumber = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid);
267
213
  msg.messageStubParameters = oldNumber || [];
268
- msg.messageStubType = Types_1.WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER;
214
+ msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER;
269
215
  break;
270
216
  case 'promote':
271
217
  case 'demote':
@@ -273,121 +219,73 @@ const makeMessagesRecvSocket = (config) => {
273
219
  case 'add':
274
220
  case 'leave':
275
221
  const stubType = `GROUP_PARTICIPANT_${child.tag.toUpperCase()}`;
276
- msg.messageStubType = Types_1.WAMessageStubType[stubType];
277
- const participants = (0, WABinary_1.getBinaryNodeChildren)(child, 'participant').map(p => p.attrs.jid);
222
+ msg.messageStubType = WAMessageStubType[stubType];
223
+ const participants = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid);
278
224
  if (participants.length === 1 &&
279
225
  // if recv. "remove" message and sender removed themselves
280
226
  // mark as left
281
- (0, WABinary_1.areJidsSameUser)(participants[0], participant) &&
227
+ areJidsSameUser(participants[0], participant) &&
282
228
  child.tag === 'remove') {
283
- msg.messageStubType = Types_1.WAMessageStubType.GROUP_PARTICIPANT_LEAVE;
229
+ msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_LEAVE;
284
230
  }
285
231
  msg.messageStubParameters = participants;
286
232
  break;
287
233
  case 'subject':
288
- msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_SUBJECT;
234
+ msg.messageStubType = WAMessageStubType.GROUP_CHANGE_SUBJECT;
289
235
  msg.messageStubParameters = [child.attrs.subject];
290
236
  break;
291
237
  case 'description':
292
- const description = (_d = (_c = (0, WABinary_1.getBinaryNodeChild)(child, 'body')) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d.toString();
293
- msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_DESCRIPTION;
238
+ const description = getBinaryNodeChild(child, 'body')?.content?.toString();
239
+ msg.messageStubType = WAMessageStubType.GROUP_CHANGE_DESCRIPTION;
294
240
  msg.messageStubParameters = description ? [description] : undefined;
295
241
  break;
296
242
  case 'announcement':
297
243
  case 'not_announcement':
298
- msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_ANNOUNCE;
299
- msg.messageStubParameters = [(child.tag === 'announcement') ? 'on' : 'off'];
244
+ msg.messageStubType = WAMessageStubType.GROUP_CHANGE_ANNOUNCE;
245
+ msg.messageStubParameters = [child.tag === 'announcement' ? 'on' : 'off'];
300
246
  break;
301
247
  case 'locked':
302
248
  case 'unlocked':
303
- msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_RESTRICT;
304
- msg.messageStubParameters = [(child.tag === 'locked') ? 'on' : 'off'];
249
+ msg.messageStubType = WAMessageStubType.GROUP_CHANGE_RESTRICT;
250
+ msg.messageStubParameters = [child.tag === 'locked' ? 'on' : 'off'];
305
251
  break;
306
252
  case 'invite':
307
- msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_INVITE_LINK;
253
+ msg.messageStubType = WAMessageStubType.GROUP_CHANGE_INVITE_LINK;
308
254
  msg.messageStubParameters = [child.attrs.code];
309
255
  break;
310
256
  case 'member_add_mode':
311
257
  const addMode = child.content;
312
258
  if (addMode) {
313
- msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBER_ADD_MODE;
259
+ msg.messageStubType = WAMessageStubType.GROUP_MEMBER_ADD_MODE;
314
260
  msg.messageStubParameters = [addMode.toString()];
315
261
  }
316
262
  break;
317
263
  case 'membership_approval_mode':
318
- const approvalMode = (0, WABinary_1.getBinaryNodeChild)(child, 'group_join');
264
+ const approvalMode = getBinaryNodeChild(child, 'group_join');
319
265
  if (approvalMode) {
320
- msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE;
266
+ msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE;
321
267
  msg.messageStubParameters = [approvalMode.attrs.state];
322
268
  }
323
269
  break;
324
270
  case 'created_membership_requests':
325
- msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
271
+ msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
326
272
  msg.messageStubParameters = [participantJid, 'created', child.attrs.request_method];
327
273
  break;
328
274
  case 'revoked_membership_requests':
329
- const isDenied = (0, WABinary_1.areJidsSameUser)(participantJid, participant);
330
- msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
275
+ const isDenied = areJidsSameUser(participantJid, participant);
276
+ msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
331
277
  msg.messageStubParameters = [participantJid, isDenied ? 'revoked' : 'rejected'];
332
278
  break;
333
- break;
334
- default:
335
- // console.log("BAILEYS-DEBUG:", JSON.stringify({ ...child, content: Buffer.isBuffer(child.content) ? child.content.toString() : child.content, participant }, null, 2))
336
- }
337
- };
338
- const handleNewsletterNotification = (id, node) => {
339
- const messages = (0, WABinary_1.getBinaryNodeChild)(node, 'messages');
340
- const message = (0, WABinary_1.getBinaryNodeChild)(messages, 'message');
341
- const server_id = message.attrs.server_id;
342
- const reactionsList = (0, WABinary_1.getBinaryNodeChild)(message, 'reactions');
343
- const viewsList = (0, WABinary_1.getBinaryNodeChildren)(message, 'views_count');
344
- if (reactionsList) {
345
- const reactions = (0, WABinary_1.getBinaryNodeChildren)(reactionsList, 'reaction');
346
- if (reactions.length === 0) {
347
- ev.emit('newsletter.reaction', { id, server_id, reaction: { removed: true } });
348
- }
349
- reactions.forEach(item => {
350
- var _a, _b;
351
- ev.emit('newsletter.reaction', { id, server_id, reaction: { code: (_a = item.attrs) === null || _a === void 0 ? void 0 : _a.code, count: +((_b = item.attrs) === null || _b === void 0 ? void 0 : _b.count) } });
352
- });
353
- }
354
- if (viewsList.length) {
355
- viewsList.forEach(item => {
356
- ev.emit('newsletter.view', { id, server_id, count: +item.attrs.count });
357
- });
358
- }
359
- };
360
- const handleMexNewsletterNotification = (id, node) => {
361
- var _a;
362
- const operation = node === null || node === void 0 ? void 0 : node.attrs.op_name;
363
- const content = JSON.parse((_a = node === null || node === void 0 ? void 0 : node.content) === null || _a === void 0 ? void 0 : _a.toString());
364
- let contentPath;
365
- if (operation === Types_1.MexOperations.PROMOTE || operation === Types_1.MexOperations.DEMOTE) {
366
- let action;
367
- if (operation === Types_1.MexOperations.PROMOTE) {
368
- action = 'promote';
369
- contentPath = content.data[Types_1.XWAPaths.PROMOTE];
370
- }
371
- if (operation === Types_1.MexOperations.DEMOTE) {
372
- action = 'demote';
373
- contentPath = content.data[Types_1.XWAPaths.DEMOTE];
374
- }
375
- ev.emit('newsletter-participants.update', { id, author: contentPath.actor.pn, user: contentPath.user.pn, new_role: contentPath.user_new_role, action });
376
- }
377
- if (operation === Types_1.MexOperations.UPDATE) {
378
- contentPath = content.data[Types_1.XWAPaths.METADATA_UPDATE];
379
- ev.emit('newsletter-settings.update', { id, update: contentPath.thread_metadata.settings });
380
279
  }
381
280
  };
382
281
  const processNotification = async (node) => {
383
- var _a, _b;
384
282
  const result = {};
385
- const [child] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
283
+ const [child] = getAllBinaryNodeChildren(node);
386
284
  const nodeType = node.attrs.type;
387
- const from = (0, WABinary_1.jidNormalizedUser)(node.attrs.from);
285
+ const from = jidNormalizedUser(node.attrs.from);
388
286
  switch (nodeType) {
389
287
  case 'privacy_token':
390
- const tokenList = (0, WABinary_1.getBinaryNodeChildren)(child, 'token');
288
+ const tokenList = getBinaryNodeChildren(child, 'token');
391
289
  for (const { attrs, content } of tokenList) {
392
290
  const jid = attrs.jid;
393
291
  ev.emit('chats.update', [
@@ -400,52 +298,54 @@ const makeMessagesRecvSocket = (config) => {
400
298
  }
401
299
  break;
402
300
  case 'newsletter':
403
- handleNewsletterNotification(node.attrs.from, child);
301
+ await handleNewsletterNotification(node);
404
302
  break;
405
303
  case 'mex':
406
- handleMexNewsletterNotification(node.attrs.from, child);
304
+ await handleMexNewsletterNotification(node);
407
305
  break;
408
306
  case 'w:gp2':
409
307
  handleGroupNotification(node.attrs.participant, child, result);
410
308
  break;
411
309
  case 'mediaretry':
412
- const event = (0, Utils_1.decodeMediaRetryNode)(node);
310
+ const event = decodeMediaRetryNode(node);
413
311
  ev.emit('messages.media-update', [event]);
414
312
  break;
415
313
  case 'encrypt':
416
314
  await handleEncryptNotification(node);
417
315
  break;
418
316
  case 'devices':
419
- const devices = (0, WABinary_1.getBinaryNodeChildren)(child, 'device');
420
- if ((0, WABinary_1.areJidsSameUser)(child.attrs.jid, authState.creds.me.id)) {
317
+ const devices = getBinaryNodeChildren(child, 'device');
318
+ if (areJidsSameUser(child.attrs.jid, authState.creds.me.id)) {
421
319
  const deviceJids = devices.map(d => d.attrs.jid);
422
320
  logger.info({ deviceJids }, 'got my own devices');
423
321
  }
424
322
  break;
425
323
  case 'server_sync':
426
- const update = (0, WABinary_1.getBinaryNodeChild)(node, 'collection');
324
+ const update = getBinaryNodeChild(node, 'collection');
427
325
  if (update) {
428
326
  const name = update.attrs.name;
429
327
  await resyncAppState([name], false);
430
328
  }
431
329
  break;
432
330
  case 'picture':
433
- const setPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'set');
434
- const delPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'delete');
435
- ev.emit('contacts.update', [{
436
- id: from || ((_b = (_a = (setPicture || delPicture)) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.hash) || '',
331
+ const setPicture = getBinaryNodeChild(node, 'set');
332
+ const delPicture = getBinaryNodeChild(node, 'delete');
333
+ ev.emit('contacts.update', [
334
+ {
335
+ id: jidNormalizedUser(node?.attrs?.from) || (setPicture || delPicture)?.attrs?.hash || '',
437
336
  imgUrl: setPicture ? 'changed' : 'removed'
438
- }]);
439
- if ((0, WABinary_1.isJidGroup)(from)) {
337
+ }
338
+ ]);
339
+ if (isJidGroup(from)) {
440
340
  const node = setPicture || delPicture;
441
- result.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_ICON;
341
+ result.messageStubType = WAMessageStubType.GROUP_CHANGE_ICON;
442
342
  if (setPicture) {
443
343
  result.messageStubParameters = [setPicture.attrs.id];
444
344
  }
445
- result.participant = node === null || node === void 0 ? void 0 : node.attrs.author;
345
+ result.participant = node?.attrs.author;
446
346
  result.key = {
447
- ...result.key || {},
448
- participant: setPicture === null || setPicture === void 0 ? void 0 : setPicture.attrs.author
347
+ ...(result.key || {}),
348
+ participant: setPicture?.attrs.author
449
349
  };
450
350
  }
451
351
  break;
@@ -459,44 +359,48 @@ const makeMessagesRecvSocket = (config) => {
459
359
  ...authState.creds.accountSettings,
460
360
  defaultDisappearingMode: {
461
361
  ephemeralExpiration: newDuration,
462
- ephemeralSettingTimestamp: timestamp,
463
- },
362
+ ephemeralSettingTimestamp: timestamp
363
+ }
464
364
  }
465
365
  });
466
366
  }
467
367
  else if (child.tag === 'blocklist') {
468
- const blocklists = (0, WABinary_1.getBinaryNodeChildren)(child, 'item');
368
+ const blocklists = getBinaryNodeChildren(child, 'item');
469
369
  for (const { attrs } of blocklists) {
470
370
  const blocklist = [attrs.jid];
471
- const type = (attrs.action === 'block') ? 'add' : 'remove';
371
+ const type = attrs.action === 'block' ? 'add' : 'remove';
472
372
  ev.emit('blocklist.update', { blocklist, type });
473
373
  }
474
374
  }
475
375
  break;
476
376
  case 'link_code_companion_reg':
477
- const linkCodeCompanionReg = (0, WABinary_1.getBinaryNodeChild)(node, 'link_code_companion_reg');
478
- const ref = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'link_code_pairing_ref'));
479
- const primaryIdentityPublicKey = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'primary_identity_pub'));
480
- const primaryEphemeralPublicKeyWrapped = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'link_code_pairing_wrapped_primary_ephemeral_pub'));
377
+ const linkCodeCompanionReg = getBinaryNodeChild(node, 'link_code_companion_reg');
378
+ const ref = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'link_code_pairing_ref'));
379
+ const primaryIdentityPublicKey = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'primary_identity_pub'));
380
+ const primaryEphemeralPublicKeyWrapped = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'link_code_pairing_wrapped_primary_ephemeral_pub'));
481
381
  const codePairingPublicKey = await decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped);
482
- const companionSharedKey = Utils_1.Curve.sharedKey(authState.creds.pairingEphemeralKeyPair.private, codePairingPublicKey);
483
- const random = (0, crypto_1.randomBytes)(32);
484
- const linkCodeSalt = (0, crypto_1.randomBytes)(32);
485
- const linkCodePairingExpanded = await (0, Utils_1.hkdf)(companionSharedKey, 32, {
382
+ const companionSharedKey = Curve.sharedKey(authState.creds.pairingEphemeralKeyPair.private, codePairingPublicKey);
383
+ const random = randomBytes(32);
384
+ const linkCodeSalt = randomBytes(32);
385
+ const linkCodePairingExpanded = await hkdf(companionSharedKey, 32, {
486
386
  salt: linkCodeSalt,
487
387
  info: 'link_code_pairing_key_bundle_encryption_key'
488
388
  });
489
- const encryptPayload = Buffer.concat([Buffer.from(authState.creds.signedIdentityKey.public), primaryIdentityPublicKey, random]);
490
- const encryptIv = (0, crypto_1.randomBytes)(12);
491
- const encrypted = (0, Utils_1.aesEncryptGCM)(encryptPayload, linkCodePairingExpanded, encryptIv, Buffer.alloc(0));
389
+ const encryptPayload = Buffer.concat([
390
+ Buffer.from(authState.creds.signedIdentityKey.public),
391
+ primaryIdentityPublicKey,
392
+ random
393
+ ]);
394
+ const encryptIv = randomBytes(12);
395
+ const encrypted = aesEncryptGCM(encryptPayload, linkCodePairingExpanded, encryptIv, Buffer.alloc(0));
492
396
  const encryptedPayload = Buffer.concat([linkCodeSalt, encryptIv, encrypted]);
493
- const identitySharedKey = Utils_1.Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey);
397
+ const identitySharedKey = Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey);
494
398
  const identityPayload = Buffer.concat([companionSharedKey, identitySharedKey, random]);
495
- authState.creds.advSecretKey = (await (0, Utils_1.hkdf)(identityPayload, 32, { info: 'adv_secret' })).toString('base64');
399
+ authState.creds.advSecretKey = (await hkdf(identityPayload, 32, { info: 'adv_secret' })).toString('base64');
496
400
  await query({
497
401
  tag: 'iq',
498
402
  attrs: {
499
- to: WABinary_1.S_WHATSAPP_NET,
403
+ to: S_WHATSAPP_NET,
500
404
  type: 'set',
501
405
  id: sock.generateMessageTag(),
502
406
  xmlns: 'md'
@@ -506,7 +410,7 @@ const makeMessagesRecvSocket = (config) => {
506
410
  tag: 'link_code_companion_reg',
507
411
  attrs: {
508
412
  jid: authState.creds.me.id,
509
- stage: 'companion_finish',
413
+ stage: 'companion_finish'
510
414
  },
511
415
  content: [
512
416
  {
@@ -538,14 +442,14 @@ const makeMessagesRecvSocket = (config) => {
538
442
  async function decipherLinkPublicKey(data) {
539
443
  const buffer = toRequiredBuffer(data);
540
444
  const salt = buffer.slice(0, 32);
541
- const secretKey = await (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
445
+ const secretKey = await derivePairingCodeKey(authState.creds.pairingCode, salt);
542
446
  const iv = buffer.slice(32, 48);
543
447
  const payload = buffer.slice(48, 80);
544
- return (0, Utils_1.aesDecryptCTR)(payload, secretKey, iv);
448
+ return aesDecryptCTR(payload, secretKey, iv);
545
449
  }
546
450
  function toRequiredBuffer(data) {
547
451
  if (data === undefined) {
548
- throw new boom_1.Boom('Invalid buffer', { statusCode: 400 });
452
+ throw new Boom('Invalid buffer', { statusCode: 400 });
549
453
  }
550
454
  return data instanceof Buffer ? data : Buffer.from(data);
551
455
  }
@@ -560,7 +464,6 @@ const makeMessagesRecvSocket = (config) => {
560
464
  msgRetryCache.set(key, newValue);
561
465
  };
562
466
  const sendMessagesAgain = async (key, ids, retryNode) => {
563
- var _a;
564
467
  // todo: implement a cache to store the last 256 sent messages (copy whatsmeow)
565
468
  const msgs = await Promise.all(ids.map(id => getMessage({ ...key, id })));
566
469
  const remoteJid = key.remoteJid;
@@ -568,14 +471,13 @@ const makeMessagesRecvSocket = (config) => {
568
471
  // if it's the primary jid sending the request
569
472
  // just re-send the message to everyone
570
473
  // prevents the first message decryption failure
571
- const sendToAll = !((_a = (0, WABinary_1.jidDecode)(participant)) === null || _a === void 0 ? void 0 : _a.device);
474
+ const sendToAll = !jidDecode(participant)?.device;
572
475
  await assertSessions([participant], true);
573
- if ((0, WABinary_1.isJidGroup)(remoteJid)) {
476
+ if (isJidGroup(remoteJid)) {
574
477
  await authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } });
575
478
  }
576
479
  logger.debug({ participant, sendToAll }, 'forced new session for retry recp');
577
- for (let i = 0; i < msgs.length; i++) {
578
- const msg = msgs[i];
480
+ for (const [i, msg] of msgs.entries()) {
579
481
  if (msg) {
580
482
  updateSendMessageAgainCount(ids[i], participant);
581
483
  const msgRelayOpts = { messageId: ids[i] };
@@ -596,12 +498,11 @@ const makeMessagesRecvSocket = (config) => {
596
498
  }
597
499
  };
598
500
  const handleReceipt = async (node) => {
599
- var _a, _b;
600
501
  const { attrs, content } = node;
601
502
  const isLid = attrs.from.includes('lid');
602
- const isNodeFromMe = (0, WABinary_1.areJidsSameUser)(attrs.participant || attrs.from, isLid ? (_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.lid : (_b = authState.creds.me) === null || _b === void 0 ? void 0 : _b.id);
603
- const remoteJid = !isNodeFromMe || (0, WABinary_1.isJidGroup)(attrs.from) ? attrs.from : attrs.recipient;
604
- const fromMe = !attrs.recipient || (attrs.type === 'retry' && isNodeFromMe);
503
+ const isNodeFromMe = areJidsSameUser(attrs.participant || attrs.from, isLid ? authState.creds.me?.lid : authState.creds.me?.id);
504
+ const remoteJid = !isNodeFromMe || isJidGroup(attrs.from) ? attrs.from : attrs.recipient;
505
+ const fromMe = !attrs.recipient || ((attrs.type === 'retry' || attrs.type === 'sender') && isNodeFromMe);
605
506
  const key = {
606
507
  remoteJid,
607
508
  id: '',
@@ -615,26 +516,24 @@ const makeMessagesRecvSocket = (config) => {
615
516
  }
616
517
  const ids = [attrs.id];
617
518
  if (Array.isArray(content)) {
618
- const items = (0, WABinary_1.getBinaryNodeChildren)(content[0], 'item');
519
+ const items = getBinaryNodeChildren(content[0], 'item');
619
520
  ids.push(...items.map(i => i.attrs.id));
620
521
  }
621
522
  try {
622
523
  await Promise.all([
623
524
  processingMutex.mutex(async () => {
624
- const status = (0, Utils_1.getStatusFromReceiptType)(attrs.type);
525
+ const status = getStatusFromReceiptType(attrs.type);
625
526
  if (typeof status !== 'undefined' &&
626
- (
627
527
  // basically, we only want to know when a message from us has been delivered to/read by the other person
628
528
  // or another device of ours has read some messages
629
- status >= WAProto_1.proto.WebMessageInfo.Status.SERVER_ACK ||
630
- !isNodeFromMe)) {
631
- if ((0, WABinary_1.isJidGroup)(remoteJid) || (0, WABinary_1.isJidStatusBroadcast)(remoteJid)) {
529
+ (status >= proto.WebMessageInfo.Status.SERVER_ACK || !isNodeFromMe)) {
530
+ if (isJidGroup(remoteJid) || isJidStatusBroadcast(remoteJid)) {
632
531
  if (attrs.participant) {
633
- const updateKey = status === WAProto_1.proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
532
+ const updateKey = status === proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
634
533
  ev.emit('message-receipt.update', ids.map(id => ({
635
534
  key: { ...key, id },
636
535
  receipt: {
637
- userJid: (0, WABinary_1.jidNormalizedUser)(attrs.participant),
536
+ userJid: jidNormalizedUser(attrs.participant),
638
537
  [updateKey]: +attrs.t
639
538
  }
640
539
  })));
@@ -650,7 +549,7 @@ const makeMessagesRecvSocket = (config) => {
650
549
  if (attrs.type === 'retry') {
651
550
  // correctly set who is asking for the retry
652
551
  key.participant = key.participant || attrs.from;
653
- const retryNode = (0, WABinary_1.getBinaryNodeChild)(node, 'retry');
552
+ const retryNode = getBinaryNodeChild(node, 'retry');
654
553
  if (willSendMessageAgain(ids[0], key.participant)) {
655
554
  if (key.fromMe) {
656
555
  try {
@@ -686,10 +585,9 @@ const makeMessagesRecvSocket = (config) => {
686
585
  try {
687
586
  await Promise.all([
688
587
  processingMutex.mutex(async () => {
689
- var _a;
690
588
  const msg = await processNotification(node);
691
589
  if (msg) {
692
- const fromMe = (0, WABinary_1.areJidsSameUser)(node.attrs.participant || remoteJid, authState.creds.me.id);
590
+ const fromMe = areJidsSameUser(node.attrs.participant || remoteJid, authState.creds.me.id);
693
591
  msg.key = {
694
592
  remoteJid,
695
593
  fromMe,
@@ -697,9 +595,9 @@ const makeMessagesRecvSocket = (config) => {
697
595
  id: node.attrs.id,
698
596
  ...(msg.key || {})
699
597
  };
700
- (_a = msg.participant) !== null && _a !== void 0 ? _a : (msg.participant = node.attrs.participant);
598
+ msg.participant ?? (msg.participant = node.attrs.participant);
701
599
  msg.messageTimestamp = +node.attrs.t;
702
- const fullMsg = WAProto_1.proto.WebMessageInfo.fromObject(msg);
600
+ const fullMsg = proto.WebMessageInfo.fromObject(msg);
703
601
  await upsertMessage(fullMsg, 'append');
704
602
  }
705
603
  })
@@ -710,13 +608,12 @@ const makeMessagesRecvSocket = (config) => {
710
608
  }
711
609
  };
712
610
  const handleMessage = async (node) => {
713
- var _a, _b, _c;
714
611
  if (shouldIgnoreJid(node.attrs.from) && node.attrs.from !== '@s.whatsapp.net') {
715
612
  logger.debug({ key: node.attrs.key }, 'ignored message');
716
613
  await sendMessageAck(node);
717
614
  return;
718
615
  }
719
- const encNode = (0, WABinary_1.getBinaryNodeChild)(node, 'enc');
616
+ const encNode = getBinaryNodeChild(node, 'enc');
720
617
  // TODO: temporary fix for crashes and issues resulting of failed msmsg decryption
721
618
  if (encNode && encNode.attrs.type === 'msmsg') {
722
619
  logger.debug({ key: node.attrs.key }, 'ignored msmsg');
@@ -724,9 +621,9 @@ const makeMessagesRecvSocket = (config) => {
724
621
  return;
725
622
  }
726
623
  let response;
727
- if ((0, WABinary_1.getBinaryNodeChild)(node, 'unavailable') && !encNode) {
624
+ if (getBinaryNodeChild(node, 'unavailable') && !encNode) {
728
625
  await sendMessageAck(node);
729
- const { key } = (0, Utils_1.decodeMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '').fullMessage;
626
+ const { key } = decodeMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '').fullMessage;
730
627
  response = await requestPlaceholderResend(key);
731
628
  if (response === 'RESOLVED') {
732
629
  return;
@@ -738,34 +635,32 @@ const makeMessagesRecvSocket = (config) => {
738
635
  placeholderResendCache.del(node.attrs.id);
739
636
  }
740
637
  }
741
- const { fullMessage: msg, category, author, decrypt } = (0, Utils_1.decryptMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger);
742
- if (response && ((_a = msg === null || msg === void 0 ? void 0 : msg.messageStubParameters) === null || _a === void 0 ? void 0 : _a[0]) === Utils_1.NO_MESSAGE_FOUND_ERROR_TEXT) {
743
- msg.messageStubParameters = [Utils_1.NO_MESSAGE_FOUND_ERROR_TEXT, response];
638
+ const { fullMessage: msg, category, author, decrypt } = decryptMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger);
639
+ if (response && msg?.messageStubParameters?.[0] === NO_MESSAGE_FOUND_ERROR_TEXT) {
640
+ msg.messageStubParameters = [NO_MESSAGE_FOUND_ERROR_TEXT, response];
744
641
  }
745
- if (((_c = (_b = msg.message) === null || _b === void 0 ? void 0 : _b.protocolMessage) === null || _c === void 0 ? void 0 : _c.type) === WAProto_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER) {
746
- if (node.attrs.sender_pn) {
747
- ev.emit('chats.phoneNumberShare', { lid: node.attrs.from, jid: node.attrs.sender_pn });
748
- }
642
+ if (msg.message?.protocolMessage?.type === proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER &&
643
+ node.attrs.sender_pn) {
644
+ ev.emit('chats.phoneNumberShare', { lid: node.attrs.from, jid: node.attrs.sender_pn });
749
645
  }
750
646
  try {
751
647
  await Promise.all([
752
648
  processingMutex.mutex(async () => {
753
- var _a;
754
649
  await decrypt();
755
650
  // message failed to decrypt
756
- if (msg.messageStubType === WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT) {
757
- if (((_a = msg === null || msg === void 0 ? void 0 : msg.messageStubParameters) === null || _a === void 0 ? void 0 : _a[0]) === Utils_1.MISSING_KEYS_ERROR_TEXT) {
758
- return sendMessageAck(node, Utils_1.NACK_REASONS.ParsingError);
651
+ if (msg.messageStubType === proto.WebMessageInfo.StubType.CIPHERTEXT) {
652
+ if (msg?.messageStubParameters?.[0] === MISSING_KEYS_ERROR_TEXT) {
653
+ return sendMessageAck(node, NACK_REASONS.ParsingError);
759
654
  }
760
655
  retryMutex.mutex(async () => {
761
656
  if (ws.isOpen) {
762
- if ((0, WABinary_1.getBinaryNodeChild)(node, 'unavailable')) {
657
+ if (getBinaryNodeChild(node, 'unavailable')) {
763
658
  return;
764
659
  }
765
- const encNode = (0, WABinary_1.getBinaryNodeChild)(node, 'enc');
660
+ const encNode = getBinaryNodeChild(node, 'enc');
766
661
  await sendRetryRequest(node, !encNode);
767
662
  if (retryRequestDelayMs) {
768
- await (0, Utils_1.delay)(retryRequestDelayMs);
663
+ await delay(retryRequestDelayMs);
769
664
  }
770
665
  }
771
666
  else {
@@ -777,13 +672,15 @@ const makeMessagesRecvSocket = (config) => {
777
672
  // no type in the receipt => message delivered
778
673
  let type = undefined;
779
674
  let participant = msg.key.participant;
780
- if (category === 'peer') { // special peer message
675
+ if (category === 'peer') {
676
+ // special peer message
781
677
  type = 'peer_msg';
782
678
  }
783
- else if (msg.key.fromMe) { // message was sent by us from a different device
679
+ else if (msg.key.fromMe) {
680
+ // message was sent by us from a different device
784
681
  type = 'sender';
785
682
  // need to specially handle this case
786
- if ((0, WABinary_1.isJidUser)(msg.key.remoteJid)) {
683
+ if (isJidUser(msg.key.remoteJid)) {
787
684
  participant = author;
788
685
  }
789
686
  }
@@ -792,13 +689,13 @@ const makeMessagesRecvSocket = (config) => {
792
689
  }
793
690
  await sendReceipt(msg.key.remoteJid, participant, [msg.key.id], type);
794
691
  // send ack for history message
795
- const isAnyHistoryMsg = (0, Utils_1.getHistoryMsg)(msg.message);
692
+ const isAnyHistoryMsg = getHistoryMsg(msg.message);
796
693
  if (isAnyHistoryMsg) {
797
- const jid = (0, WABinary_1.jidNormalizedUser)(msg.key.remoteJid);
694
+ const jid = jidNormalizedUser(msg.key.remoteJid);
798
695
  await sendReceipt(jid, undefined, [msg.key.id], 'hist_sync');
799
696
  }
800
697
  }
801
- (0, Utils_1.cleanMessage)(msg, authState.creds.me.id);
698
+ cleanMessage(msg, authState.creds.me.id);
802
699
  await sendMessageAck(node);
803
700
  await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify');
804
701
  })
@@ -809,9 +706,8 @@ const makeMessagesRecvSocket = (config) => {
809
706
  }
810
707
  };
811
708
  const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
812
- var _a;
813
- if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
814
- throw new boom_1.Boom('Not authenticated');
709
+ if (!authState.creds.me?.id) {
710
+ throw new Boom('Not authenticated');
815
711
  }
816
712
  const pdoMessage = {
817
713
  historySyncOnDemandRequest: {
@@ -821,57 +717,61 @@ const makeMessagesRecvSocket = (config) => {
821
717
  oldestMsgTimestampMs: oldestMsgTimestamp,
822
718
  onDemandMsgCount: count
823
719
  },
824
- peerDataOperationRequestType: WAProto_1.proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
720
+ peerDataOperationRequestType: proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
825
721
  };
826
722
  return sendPeerDataOperationMessage(pdoMessage);
827
723
  };
828
724
  const requestPlaceholderResend = async (messageKey) => {
829
- var _a;
830
- if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
831
- throw new boom_1.Boom('Not authenticated');
725
+ if (!authState.creds.me?.id) {
726
+ throw new Boom('Not authenticated');
832
727
  }
833
- if (placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
728
+ if (placeholderResendCache.get(messageKey?.id)) {
834
729
  logger.debug({ messageKey }, 'already requested resend');
835
730
  return;
836
731
  }
837
732
  else {
838
- placeholderResendCache.set(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id, true);
733
+ placeholderResendCache.set(messageKey?.id, true);
839
734
  }
840
- await (0, Utils_1.delay)(5000);
841
- if (!placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
735
+ await delay(5000);
736
+ if (!placeholderResendCache.get(messageKey?.id)) {
842
737
  logger.debug({ messageKey }, 'message received while resend requested');
843
738
  return 'RESOLVED';
844
739
  }
845
740
  const pdoMessage = {
846
- placeholderMessageResendRequest: [{
741
+ placeholderMessageResendRequest: [
742
+ {
847
743
  messageKey
848
- }],
849
- peerDataOperationRequestType: WAProto_1.proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
744
+ }
745
+ ],
746
+ peerDataOperationRequestType: proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
850
747
  };
851
748
  setTimeout(() => {
852
- if (placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
749
+ if (placeholderResendCache.get(messageKey?.id)) {
853
750
  logger.debug({ messageKey }, 'PDO message without response after 15 seconds. Phone possibly offline');
854
- placeholderResendCache.del(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id);
751
+ placeholderResendCache.del(messageKey?.id);
855
752
  }
856
753
  }, 15000);
857
754
  return sendPeerDataOperationMessage(pdoMessage);
858
755
  };
859
756
  const handleCall = async (node) => {
860
757
  const { attrs } = node;
861
- const [infoChild] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
758
+ const [infoChild] = getAllBinaryNodeChildren(node);
759
+ if (!infoChild) {
760
+ throw new Boom('Missing call info in call node');
761
+ }
862
762
  const callId = infoChild.attrs['call-id'];
863
763
  const from = infoChild.attrs.from || infoChild.attrs['call-creator'];
864
- const status = (0, Utils_1.getCallStatusFromNode)(infoChild);
764
+ const status = getCallStatusFromNode(infoChild);
865
765
  const call = {
866
766
  chatId: attrs.from,
867
767
  from,
868
768
  id: callId,
869
769
  date: new Date(+attrs.t * 1000),
870
770
  offline: !!attrs.offline,
871
- status,
771
+ status
872
772
  };
873
773
  if (status === 'offer') {
874
- call.isVideo = !!(0, WABinary_1.getBinaryNodeChild)(infoChild, 'video');
774
+ call.isVideo = !!getBinaryNodeChild(infoChild, 'video');
875
775
  call.isGroup = infoChild.attrs.type === 'group' || !!infoChild.attrs['group-jid'];
876
776
  call.groupJid = infoChild.attrs['group-jid'];
877
777
  callOfferCache.set(call.id, call);
@@ -890,28 +790,20 @@ const makeMessagesRecvSocket = (config) => {
890
790
  await sendMessageAck(node);
891
791
  };
892
792
  const handleBadAck = async ({ attrs }) => {
893
- const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id, server_id: attrs === null || attrs === void 0 ? void 0 : attrs.server_id };
894
- // current hypothesis is that if pash is sent in the ack
895
- // it means -- the message hasn't reached all devices yet
896
- // we'll retry sending the message here
897
- if (attrs.phash) {
898
- logger.info({ attrs }, 'received phash in ack, resending message...');
899
- const cacheKey = `${key.remoteJid}:${key.id}`;
900
- if ((msgRetryCache.get(cacheKey) || 0) >= maxMsgRetryCount) {
901
- logger.warn({ attrs }, 'reached max retry count, not sending message again');
902
- msgRetryCache.del(cacheKey);
903
- return;
904
- }
905
- const retryCount = msgRetryCache.get(cacheKey) || 0;
906
- const msg = await getMessage(key);
907
- if (msg) {
908
- await relayMessage(key.remoteJid, msg, { messageId: key.id, useUserDevicesCache: false });
909
- msgRetryCache.set(cacheKey, retryCount + 1);
910
- }
911
- else {
912
- logger.warn({ attrs }, 'could not send message again, as it was not found');
913
- }
914
- }
793
+ const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id };
794
+ // WARNING: REFRAIN FROM ENABLING THIS FOR NOW. IT WILL CAUSE A LOOP
795
+ // // current hypothesis is that if pash is sent in the ack
796
+ // // it means -- the message hasn't reached all devices yet
797
+ // // we'll retry sending the message here
798
+ // if(attrs.phash) {
799
+ // logger.info({ attrs }, 'received phash in ack, resending message...')
800
+ // const msg = await getMessage(key)
801
+ // if(msg) {
802
+ // await relayMessage(key.remoteJid!, msg, { messageId: key.id!, useUserDevicesCache: false })
803
+ // } else {
804
+ // logger.warn({ attrs }, 'could not send message again, as it was not found')
805
+ // }
806
+ // }
915
807
  // error in acknowledgement,
916
808
  // device could not display the message
917
809
  if (attrs.error) {
@@ -920,10 +812,8 @@ const makeMessagesRecvSocket = (config) => {
920
812
  {
921
813
  key,
922
814
  update: {
923
- status: Types_1.WAMessageStatus.ERROR,
924
- messageStubParameters: [
925
- attrs.error
926
- ]
815
+ status: WAMessageStatus.ERROR,
816
+ messageStubParameters: [attrs.error]
927
817
  }
928
818
  }
929
819
  ]);
@@ -936,8 +826,7 @@ const makeMessagesRecvSocket = (config) => {
936
826
  await execTask();
937
827
  ev.flush();
938
828
  function execTask() {
939
- return exec(node, false)
940
- .catch(err => onUnexpectedError(err, identifier));
829
+ return exec(node, false).catch(err => onUnexpectedError(err, identifier));
941
830
  }
942
831
  };
943
832
  const makeOfflineNodeProcessor = () => {
@@ -981,6 +870,139 @@ const makeMessagesRecvSocket = (config) => {
981
870
  processNodeWithBuffer(node, identifier, exec);
982
871
  }
983
872
  };
873
+ // Handles newsletter notifications
874
+ async function handleNewsletterNotification(node) {
875
+ const from = node.attrs.from;
876
+ const child = getAllBinaryNodeChildren(node)[0];
877
+ const author = node.attrs.participant;
878
+ logger.info({ from, child }, 'got newsletter notification');
879
+ switch (child.tag) {
880
+ case 'reaction':
881
+ const reactionUpdate = {
882
+ id: from,
883
+ server_id: child.attrs.message_id,
884
+ reaction: {
885
+ code: getBinaryNodeChildString(child, 'reaction'),
886
+ count: 1
887
+ }
888
+ };
889
+ ev.emit('newsletter.reaction', reactionUpdate);
890
+ break;
891
+ case 'view':
892
+ const viewUpdate = {
893
+ id: from,
894
+ server_id: child.attrs.message_id,
895
+ count: parseInt(child.content?.toString() || '0', 10)
896
+ };
897
+ ev.emit('newsletter.view', viewUpdate);
898
+ break;
899
+ case 'participant':
900
+ const participantUpdate = {
901
+ id: from,
902
+ author,
903
+ user: child.attrs.jid,
904
+ action: child.attrs.action,
905
+ new_role: child.attrs.role
906
+ };
907
+ ev.emit('newsletter-participants.update', participantUpdate);
908
+ break;
909
+ case 'update':
910
+ const settingsNode = getBinaryNodeChild(child, 'settings');
911
+ if (settingsNode) {
912
+ const update = {};
913
+ const nameNode = getBinaryNodeChild(settingsNode, 'name');
914
+ if (nameNode?.content)
915
+ update.name = nameNode.content.toString();
916
+ const descriptionNode = getBinaryNodeChild(settingsNode, 'description');
917
+ if (descriptionNode?.content)
918
+ update.description = descriptionNode.content.toString();
919
+ ev.emit('newsletter-settings.update', {
920
+ id: from,
921
+ update
922
+ });
923
+ }
924
+ break;
925
+ case 'message':
926
+ const plaintextNode = getBinaryNodeChild(child, 'plaintext');
927
+ if (plaintextNode?.content) {
928
+ try {
929
+ const contentBuf = typeof plaintextNode.content === 'string'
930
+ ? Buffer.from(plaintextNode.content, 'binary')
931
+ : Buffer.from(plaintextNode.content);
932
+ const messageProto = proto.Message.decode(contentBuf);
933
+ const fullMessage = proto.WebMessageInfo.fromObject({
934
+ key: {
935
+ remoteJid: from,
936
+ id: child.attrs.message_id || child.attrs.server_id,
937
+ fromMe: false
938
+ },
939
+ message: messageProto,
940
+ messageTimestamp: +child.attrs.t
941
+ });
942
+ await upsertMessage(fullMessage, 'append');
943
+ logger.info('Processed plaintext newsletter message');
944
+ }
945
+ catch (error) {
946
+ logger.error({ error }, 'Failed to decode plaintext newsletter message');
947
+ }
948
+ }
949
+ break;
950
+ default:
951
+ logger.warn({ node }, 'Unknown newsletter notification');
952
+ break;
953
+ }
954
+ }
955
+ // Handles mex newsletter notifications
956
+ async function handleMexNewsletterNotification(node) {
957
+ const mexNode = getBinaryNodeChild(node, 'mex');
958
+ if (!mexNode?.content) {
959
+ logger.warn({ node }, 'Invalid mex newsletter notification');
960
+ return;
961
+ }
962
+ let data;
963
+ try {
964
+ data = JSON.parse(mexNode.content.toString());
965
+ }
966
+ catch (error) {
967
+ logger.error({ err: error, node }, 'Failed to parse mex newsletter notification');
968
+ return;
969
+ }
970
+ const operation = data?.operation;
971
+ const updates = data?.updates;
972
+ if (!updates || !operation) {
973
+ logger.warn({ data }, 'Invalid mex newsletter notification content');
974
+ return;
975
+ }
976
+ logger.info({ operation, updates }, 'got mex newsletter notification');
977
+ switch (operation) {
978
+ case 'NotificationNewsletterUpdate':
979
+ for (const update of updates) {
980
+ if (update.jid && update.settings && Object.keys(update.settings).length > 0) {
981
+ ev.emit('newsletter-settings.update', {
982
+ id: update.jid,
983
+ update: update.settings
984
+ });
985
+ }
986
+ }
987
+ break;
988
+ case 'NotificationNewsletterAdminPromote':
989
+ for (const update of updates) {
990
+ if (update.jid && update.user) {
991
+ ev.emit('newsletter-participants.update', {
992
+ id: update.jid,
993
+ author: node.attrs.from,
994
+ user: update.user,
995
+ new_role: 'ADMIN',
996
+ action: 'promote'
997
+ });
998
+ }
999
+ }
1000
+ break;
1001
+ default:
1002
+ logger.info({ operation, data }, 'Unhandled mex newsletter notification');
1003
+ break;
1004
+ }
1005
+ }
984
1006
  // recv a message
985
1007
  ws.on('CB:message', (node) => {
986
1008
  processNode('message', node, 'processing message', handleMessage);
@@ -995,10 +1017,12 @@ const makeMessagesRecvSocket = (config) => {
995
1017
  processNode('notification', node, 'handling notification', handleNotification);
996
1018
  });
997
1019
  ws.on('CB:ack,class:message', (node) => {
998
- handleBadAck(node)
999
- .catch(error => onUnexpectedError(error, 'handling bad ack'));
1020
+ handleBadAck(node).catch(error => onUnexpectedError(error, 'handling bad ack'));
1000
1021
  });
1001
1022
  ev.on('call', ([call]) => {
1023
+ if (!call) {
1024
+ return;
1025
+ }
1002
1026
  // missed call + group call notification message generation
1003
1027
  if (call.status === 'timeout' || (call.status === 'offer' && call.isGroup)) {
1004
1028
  const msg = {
@@ -1007,20 +1031,22 @@ const makeMessagesRecvSocket = (config) => {
1007
1031
  id: call.id,
1008
1032
  fromMe: false
1009
1033
  },
1010
- messageTimestamp: (0, Utils_1.unixTimestampSeconds)(call.date),
1034
+ messageTimestamp: unixTimestampSeconds(call.date)
1011
1035
  };
1012
1036
  if (call.status === 'timeout') {
1013
1037
  if (call.isGroup) {
1014
- msg.messageStubType = call.isVideo ? Types_1.WAMessageStubType.CALL_MISSED_GROUP_VIDEO : Types_1.WAMessageStubType.CALL_MISSED_GROUP_VOICE;
1038
+ msg.messageStubType = call.isVideo
1039
+ ? WAMessageStubType.CALL_MISSED_GROUP_VIDEO
1040
+ : WAMessageStubType.CALL_MISSED_GROUP_VOICE;
1015
1041
  }
1016
1042
  else {
1017
- msg.messageStubType = call.isVideo ? Types_1.WAMessageStubType.CALL_MISSED_VIDEO : Types_1.WAMessageStubType.CALL_MISSED_VOICE;
1043
+ msg.messageStubType = call.isVideo ? WAMessageStubType.CALL_MISSED_VIDEO : WAMessageStubType.CALL_MISSED_VOICE;
1018
1044
  }
1019
1045
  }
1020
1046
  else {
1021
1047
  msg.message = { call: { callKey: Buffer.from(call.id) } };
1022
1048
  }
1023
- const protoMsg = WAProto_1.proto.WebMessageInfo.fromObject(msg);
1049
+ const protoMsg = proto.WebMessageInfo.fromObject(msg);
1024
1050
  upsertMessage(protoMsg, call.offline ? 'append' : 'notify');
1025
1051
  }
1026
1052
  });
@@ -1035,9 +1061,8 @@ const makeMessagesRecvSocket = (config) => {
1035
1061
  sendMessageAck,
1036
1062
  sendRetryRequest,
1037
1063
  rejectCall,
1038
- offerCall,
1039
1064
  fetchMessageHistory,
1040
- requestPlaceholderResend,
1065
+ requestPlaceholderResend
1041
1066
  };
1042
1067
  };
1043
- exports.makeMessagesRecvSocket = makeMessagesRecvSocket;
1068
+ //# sourceMappingURL=messages-recv.js.map