@hansaka02/baileys 1.0.0 → 7.3.2

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 (44) hide show
  1. package/README.md +172 -172
  2. package/WAProto/AICommon/AICommon.d.ts +7102 -5380
  3. package/WAProto/AICommon/AICommon.js +13991 -9169
  4. package/WAProto/AICommon/AICommon.proto +110 -3
  5. package/WAProto/CompanionReg/CompanionReg.d.ts +27 -0
  6. package/WAProto/CompanionReg/CompanionReg.js +114 -0
  7. package/WAProto/CompanionReg/CompanionReg.proto +3 -0
  8. package/WAProto/DeviceCapabilities/DeviceCapabilities.d.ts +244 -0
  9. package/WAProto/DeviceCapabilities/DeviceCapabilities.js +652 -0
  10. package/WAProto/DeviceCapabilities/DeviceCapabilities.proto +19 -0
  11. package/WAProto/E2E/E2E.d.ts +7234 -1003
  12. package/WAProto/E2E/E2E.js +77193 -51248
  13. package/WAProto/E2E/E2E.proto +68 -12
  14. package/WAProto/HistorySync/HistorySync.d.ts +1195 -75
  15. package/WAProto/HistorySync/HistorySync.js +3375 -178
  16. package/WAProto/HistorySync/HistorySync.proto +3 -3
  17. package/WAProto/LidMigrationSyncPayload/LidMigrationSyncPayload.d.ts +18 -6
  18. package/WAProto/LidMigrationSyncPayload/LidMigrationSyncPayload.js +98 -49
  19. package/WAProto/LidMigrationSyncPayload/LidMigrationSyncPayload.proto +2 -2
  20. package/WAProto/MdStorageMsgRowOpaqueData/MdStorageMsgRowOpaqueData.d.ts +7468 -1051
  21. package/WAProto/MdStorageMsgRowOpaqueData/MdStorageMsgRowOpaqueData.js +75226 -48422
  22. package/WAProto/MdStorageMsgRowOpaqueData/MdStorageMsgRowOpaqueData.proto +6 -0
  23. package/WAProto/StatusAttributions/StatusAttributions.d.ts +5 -2
  24. package/WAProto/StatusAttributions/StatusAttributions.js +21 -0
  25. package/WAProto/StatusAttributions/StatusAttributions.proto +3 -0
  26. package/WAProto/SyncAction/SyncAction.d.ts +2271 -280
  27. package/WAProto/SyncAction/SyncAction.js +9423 -2023
  28. package/WAProto/SyncAction/SyncAction.proto +208 -15
  29. package/WAProto/Wa6/Wa6.d.ts +20 -1
  30. package/WAProto/Wa6/Wa6.js +83 -0
  31. package/WAProto/Wa6/Wa6.proto +3 -0
  32. package/WAProto/Web/Web.d.ts +8207 -1194
  33. package/WAProto/Web/Web.js +92664 -63403
  34. package/WAProto/Web/Web.proto +31 -13
  35. package/lib/Defaults/baileys-version.json +1 -1
  36. package/lib/Socket/messages-recv.js +9 -1
  37. package/lib/Types/MexUpdates.js +1 -0
  38. package/lib/Utils/crypto.js +1 -1
  39. package/lib/Utils/decode-wa-message.js +14 -16
  40. package/lib/Utils/generics.js +63 -16
  41. package/lib/Utils/messages.js +40 -0
  42. package/lib/Utils/process-message.js +336 -24
  43. package/lib/Utils/validate-connection.js +51 -9
  44. package/package.json +19 -19
@@ -4,25 +4,33 @@ package Web;
4
4
  import "../E2E/E2E.proto";
5
5
  import "../Protocol/Protocol.proto";
6
6
 
7
- message GroupHistoryBundleMessage {
8
- optional E2E.Message.MessageHistoryBundle messageHistoryBundle = 1;
7
+ message QuarantinedMessage {
8
+ optional bytes originalData = 1;
9
+ optional string extractedText = 2;
10
+ }
11
+
12
+ message GroupHistoryBundleInfo {
13
+ optional E2E.Message.MessageHistoryBundle deprecatedMessageHistoryBundle = 1;
9
14
  optional ProcessState processState = 2;
10
15
  enum ProcessState {
11
- NOT_DOWNLOADED = 0;
12
- DOWNLOADED = 1;
13
- DOWNLOAD_FAILED = 2;
16
+ NOT_INJECTED = 0;
17
+ INJECTED = 1;
18
+ INJECTED_PARTIAL = 2;
19
+ INJECTION_FAILED = 3;
20
+ INJECTION_FAILED_NO_RETRY = 4;
14
21
  }
15
22
  }
16
23
 
17
24
  message GroupHistoryIndividualMessageInfo {
18
25
  optional Protocol.MessageKey bundleMessageKey = 1;
26
+ optional bool editedAfterReceivedAsHistory = 2;
19
27
  }
20
28
 
21
29
  message Citation {
22
- required string title = 1;
23
- required string subtitle = 2;
24
- required string cmsId = 3;
25
- required string imageUrl = 4;
30
+ optional string title = 1;
31
+ optional string subtitle = 2;
32
+ optional string cmsId = 3;
33
+ optional string imageUrl = 4;
26
34
  }
27
35
 
28
36
  message StatusMentionMessage {
@@ -94,6 +102,10 @@ message EventAdditionalMetadata {
94
102
  optional bool isStale = 1;
95
103
  }
96
104
 
105
+ message InteractiveMessageAdditionalMetadata {
106
+ optional bool isGalaxyFlowCompleted = 1;
107
+ }
108
+
97
109
  message PollAdditionalMetadata {
98
110
  optional bool pollInvalidated = 1;
99
111
  }
@@ -115,7 +127,7 @@ message Reaction {
115
127
  }
116
128
 
117
129
  message UserReceipt {
118
- required string userJid = 1;
130
+ optional string userJid = 1;
119
131
  optional int64 receiptTimestamp = 2;
120
132
  optional int64 readTimestamp = 3;
121
133
  optional int64 playedTimestamp = 4;
@@ -124,7 +136,7 @@ message UserReceipt {
124
136
  }
125
137
 
126
138
  message StatusPSA {
127
- required uint64 campaignId = 44;
139
+ optional uint64 campaignId = 44;
128
140
  optional uint64 campaignExpirationTimestamp = 45;
129
141
  }
130
142
 
@@ -284,7 +296,7 @@ message CommentMetadata {
284
296
  }
285
297
 
286
298
  message WebMessageInfo {
287
- required Protocol.MessageKey key = 1;
299
+ optional Protocol.MessageKey key = 1;
288
300
  optional E2E.Message message = 2;
289
301
  optional uint64 messageTimestamp = 3;
290
302
  optional Status status = 4;
@@ -347,7 +359,9 @@ message WebMessageInfo {
347
359
  repeated Citation supportAiCitations = 72;
348
360
  optional string botTargetId = 73;
349
361
  optional GroupHistoryIndividualMessageInfo groupHistoryIndividualMessageInfo = 74;
350
- optional GroupHistoryBundleMessage groupHistoryBundleMessage = 75;
362
+ optional GroupHistoryBundleInfo groupHistoryBundleInfo = 75;
363
+ optional InteractiveMessageAdditionalMetadata interactiveMessageAdditionalMetadata = 76;
364
+ optional QuarantinedMessage quarantinedMessage = 77;
351
365
  enum BizPrivacyStatus {
352
366
  E2EE = 0;
353
367
  FB = 2;
@@ -583,5 +597,9 @@ message WebMessageInfo {
583
597
  GROUP_MEMBER_LINK_MODE = 217;
584
598
  BIZ_AUTOMATICALLY_LABELED_CHAT_SYSTEM_MESSAGE = 218;
585
599
  PHONE_NUMBER_HIDING_CHAT_DEPRECATED_MESSAGE = 219;
600
+ QUARANTINED_MESSAGE = 220;
601
+ GROUP_MEMBER_SHARE_GROUP_HISTORY_MODE = 221;
602
+ GROUP_OPEN_BOT_ADDED = 222;
603
+ GROUP_TEE_BOT_ADDED = 223;
586
604
  }
587
605
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": [2, 3000, 1026924051]
2
+ "version": [2, 3000, 1030003753]
3
3
  }
@@ -535,6 +535,14 @@ const makeMessagesRecvSocket = (config) => {
535
535
  id,
536
536
  update: contentPath.thread_metadata.settings
537
537
  })
538
+ } else if (operation === Types_1.MexUpdatesOperations.GROUP_MEMBER_LINK) {
539
+ contentPath = content.data[Types_1.XWAPathsMexUpdates.GROUP_SHARING_CHANGE]
540
+
541
+ ev.emit('groups.update', [{
542
+ id,
543
+ author: contentPath.updated_by.id,
544
+ member_link_mode: contentPath.properties.member_link_mode
545
+ }])
538
546
  } else if (operation === Types_1.MexUpdatesOperations.GROUP_LIMIT_SHARING) {
539
547
  contentPath = content.data[Types_1.XWAPathsMexUpdates.GROUP_SHARING_CHANGE]
540
548
 
@@ -603,7 +611,7 @@ const makeMessagesRecvSocket = (config) => {
603
611
  handleNewsletterNotification(node.attrs.from, child)
604
612
  break
605
613
  case 'mex':
606
- handleMexNotification(node.attrs.from, child)
614
+ handleMexNotification(node.attrs.from, child, result)
607
615
  break
608
616
  case 'mediaretry':
609
617
  const event = Utils_1.decodeMediaRetryNode(node)
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true })
4
4
 
5
5
  const MexUpdatesOperations = {
6
6
  OWNER_COMMUNITY: "NotificationCommunityOwnerUpdate",
7
+ GROUP_MEMBER_LINK: "NotificationGroupMemberLinkPropertyUpdate",
7
8
  GROUP_LIMIT_SHARING: "NotificationGroupLimitSharingPropertyUpdate"
8
9
  }
9
10
 
@@ -78,7 +78,7 @@ function aesDecryptGCM(ciphertext, key, iv, additionalData) {
78
78
  const decipher = crypto_1.createDecipheriv('aes-256-gcm', key, iv)
79
79
  const enc = ciphertext.slice(0, ciphertext.length - GCM_TAG_LENGTH)
80
80
  const tag = ciphertext.slice(ciphertext.length - GCM_TAG_LENGTH)
81
- decipher.setAAD(additionalData)
81
+ if (additionalData) decipher.setAAD(additionalData)
82
82
  decipher.setAuthTag(tag)
83
83
  return Buffer.concat([decipher.update(enc), decipher.final()])
84
84
  }
@@ -97,6 +97,7 @@ function decodeMessageNode(stanza, meId, meLid) {
97
97
  let msgType
98
98
  let chatId
99
99
  let author
100
+ let fromMe = false
100
101
  const msgId = stanza.attrs.id
101
102
  const from = stanza.attrs.from
102
103
  const participant = stanza.attrs.participant
@@ -104,23 +105,13 @@ function decodeMessageNode(stanza, meId, meLid) {
104
105
  const addressingContext = extractAddressingContext(stanza)
105
106
  const isMe = (jid) => WABinary_1.areJidsSameUser(jid, meId)
106
107
  const isMeLid = (jid) => WABinary_1.areJidsSameUser(jid, meLid)
107
- if (WABinary_1.isJidUser(from)) {
108
- if (recipient) {
109
- if (!isMe(from)) {
108
+ if (WABinary_1.isJidUser(from) || WABinary_1.isLidUser(from)) {
109
+ if (recipient && !WABinary_1.isJidMetaAI(recipient)) {
110
+ if (!isMe(from) && !isMeLid(from)) {
110
111
  throw new boom_1.Boom('receipient present, but msg not from me', { data: stanza })
111
112
  }
112
- chatId = recipient
113
- }
114
- else {
115
- chatId = from
116
- }
117
- msgType = 'chat'
118
- author = from
119
- }
120
- else if (WABinary_1.isLidUser(from)) {
121
- if (recipient) {
122
- if (!isMeLid(from)) {
123
- throw new boom_1.Boom('receipient present, but msg not from me', { data: stanza })
113
+ if (isMe(from) || isMeLid(from)) {
114
+ fromMe = true
124
115
  }
125
116
  chatId = recipient
126
117
  }
@@ -134,6 +125,9 @@ function decodeMessageNode(stanza, meId, meLid) {
134
125
  if (!participant) {
135
126
  throw new boom_1.Boom('No participant in group message')
136
127
  }
128
+ if (isMe(participant) || isMeLid(participant)) {
129
+ fromMe = true;
130
+ }
137
131
  msgType = 'group'
138
132
  author = participant
139
133
  chatId = from
@@ -149,6 +143,7 @@ function decodeMessageNode(stanza, meId, meLid) {
149
143
  else {
150
144
  msgType = isParticipantMe ? 'peer_broadcast' : 'other_broadcast'
151
145
  }
146
+ fromMe = isParticipantMe
152
147
  chatId = from
153
148
  author = participant
154
149
  }
@@ -156,11 +151,14 @@ function decodeMessageNode(stanza, meId, meLid) {
156
151
  msgType = 'newsletter'
157
152
  chatId = from
158
153
  author = from
154
+ if (isMe(from) || isMeLid(from)) {
155
+ fromMe = true;
156
+ }
159
157
  }
160
158
  else {
161
159
  throw new boom_1.Boom('Unknown message type', { data: stanza })
162
160
  }
163
- const fromMe = WABinary_1.isJidNewsletter(from) ? !!stanza.attrs?.is_sender : WABinary_1.isLidUser(from) ? isMeLid(stanza.attrs.participant || stanza.attrs.from) : isMe(stanza.attrs.participant || stanza.attrs.from)
161
+
164
162
  const pushname = stanza?.attrs?.notify
165
163
  const key = {
166
164
  remoteJid: chatId,
@@ -298,23 +298,17 @@ async function promiseTimeout(ms, promise) {
298
298
  }
299
299
 
300
300
  const generateMessageID = (userId) => {
301
- const data = Buffer.alloc(8 + 20 + 16)
302
- data.writeBigUInt64BE(BigInt(Math.floor(Date.now() / 1000)))
303
- if (userId) {
304
- const id = WABinary_1.jidDecode(userId)
305
- if (id?.user) {
306
- data.write(id.user, 8)
307
- data.write('@c.us', 8 + id.user.length)
308
- }
309
- }
310
- const random = crypto_1.randomBytes(20)
311
- random.copy(data, 28)
312
- const sha = asciiDecode([ 83, 85, 75, 73 ])
313
- const hash = crypto_1.createHash('sha256').update(data).digest()
314
- return sha + hash.toString('hex').toUpperCase().substring(0, 16)
315
- }
301
+ const timestamp = Date.now().toString();
302
+ const user = userId || 'unknown';
303
+ const random = crypto_1.randomBytes(16).toString('hex');
304
+
305
+ const hash = crypto_1.createHash('sha256')
306
+ .update(timestamp + user + random)
307
+ .digest('hex')
308
+ .toUpperCase();
316
309
 
317
- // code is inspired by whatsmeow
310
+ return 'A' + hash.substring(0, 31);
311
+ }
318
312
  const generateParticipantHashV2 = (participants) => {
319
313
  participants.sort()
320
314
  const sha256Hash = crypto_2.sha256(Buffer.from(participants.join(''))).toString('base64')
@@ -387,6 +381,58 @@ const fetchLatestBaileysVersion = async (options = {}) => {
387
381
  }
388
382
  }
389
383
 
384
+ /**
385
+ * A utility that fetches the latest web version of whatsapp.
386
+ * Use to ensure your WA connection is always on the latest version
387
+ */
388
+ const fetchLatestWaWebVersion = async (options = {}) => {
389
+ try {
390
+ // Absolute minimal headers required to bypass anti-bot detection
391
+ const defaultHeaders = {
392
+ 'sec-fetch-site': 'none',
393
+ 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
394
+ }
395
+
396
+ const headers = { ...defaultHeaders, ...options.headers }
397
+ const response = await fetch('https://web.whatsapp.com/sw.js', {
398
+ ...options,
399
+ method: 'GET',
400
+ headers
401
+ })
402
+
403
+ if (!response.ok) {
404
+ throw new boom_1.Boom(`Failed to fetch sw.js: ${response.statusText}`, { statusCode: response.status })
405
+ }
406
+
407
+ const data = await response.text()
408
+ const regex = /\\?"client_revision\\?":\s*(\d+)/
409
+ const match = data.match(regex)
410
+
411
+ if (!match?.[1]) {
412
+ return {
413
+ version: baileys_version_json_1,
414
+ isLatest: false,
415
+ error: {
416
+ message: 'Could not find client revision in the fetched content'
417
+ }
418
+ }
419
+ }
420
+
421
+ const clientRevision = match[1]
422
+ return {
423
+ version: [2, 3000, +clientRevision],
424
+ isLatest: true
425
+ }
426
+ }
427
+ catch (error) {
428
+ return {
429
+ version: baileys_version_json_1,
430
+ isLatest: false,
431
+ error
432
+ }
433
+ }
434
+ }
435
+
390
436
  /** unique message tag prefix for MD clients */
391
437
  const generateMdTagPrefix = () => {
392
438
  const bytes = crypto_1.randomBytes(4)
@@ -554,6 +600,7 @@ module.exports = {
554
600
  bindWaitForConnectionUpdate,
555
601
  printQRIfNecessaryListener,
556
602
  fetchLatestBaileysVersion,
603
+ fetchLatestWaWebVersion,
557
604
  generateMdTagPrefix,
558
605
  getStatusFromReceiptType,
559
606
  getErrorCodeFromStreamError,
@@ -1539,6 +1539,16 @@ const updateMessageWithPollUpdate = (msg, update) => {
1539
1539
  msg.pollUpdates = votes
1540
1540
  }
1541
1541
 
1542
+ /** Update the message with a new event response*/
1543
+ const updateMessageWithEventResponse = (msg, update) => {
1544
+ const authorID = generics_1.getKeyAuthor(update.eventResponseMessageKey)
1545
+ const responses = (msg.eventResponses || [])
1546
+ .filter(r => generics_1.getKeyAuthor(r.eventResponseMessageKey) !== authorID)
1547
+
1548
+ responses.push(update)
1549
+ msg.eventResponses = responses
1550
+ }
1551
+
1542
1552
  /**
1543
1553
  * Aggregates all poll updates in a poll.
1544
1554
  * @param msg the poll creation message
@@ -1587,6 +1597,34 @@ function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
1587
1597
  return Object.values(voteHashMap)
1588
1598
  }
1589
1599
 
1600
+ /**
1601
+ * Aggregates all event responses in an event message.
1602
+ * @param msg the event creation message
1603
+ * @param meLid your lid
1604
+ * @returns A list of response types & their responders
1605
+ */
1606
+ function getAggregateResponsesInEventMessage({ eventResponses }, meLid) {
1607
+ const responseTypes = ['GOING', 'NOT_GOING', 'MAYBE']
1608
+ const responseMap = {}
1609
+
1610
+ for (const type of responseTypes) {
1611
+ responseMap[type] = {
1612
+ response: type,
1613
+ responders: []
1614
+ }
1615
+ }
1616
+
1617
+ for (const update of eventResponses) {
1618
+ const { response } = update.response || 0
1619
+ const responseType = WAProto_1.proto.Message.EventResponseMessage.EventResponseType[response]
1620
+ if (responseType !== 'UNKNOWN' && responseMap[responseType]) {
1621
+ responseMap[responseType].responders.push(generics_1.getKeyAuthor(update.eventResponseMessageKey, meLid))
1622
+ }
1623
+ }
1624
+
1625
+ return Object.values(responseMap)
1626
+ }
1627
+
1590
1628
  /** Given a list of message keys, aggregates them by chat & sender. Useful for sending read receipts in bulk */
1591
1629
  const aggregateMessageKeysNotFromMe = (keys) => {
1592
1630
  const keyMap = {}
@@ -1737,7 +1775,9 @@ module.exports = {
1737
1775
  updateMessageWithReceipt,
1738
1776
  updateMessageWithReaction,
1739
1777
  updateMessageWithPollUpdate,
1778
+ updateMessageWithEventResponse,
1740
1779
  getAggregateVotesInPollMessage,
1780
+ getAggregateResponsesInEventMessage,
1741
1781
  aggregateMessageKeysNotFromMe,
1742
1782
  downloadMediaMessage,
1743
1783
  assertMediaContent,