@alannxd/baileys 5.0.6 → 6.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 (111) hide show
  1. package/WAProto/fix-import.js +29 -0
  2. package/WAProto/index.js +65432 -137443
  3. package/lib/Defaults/baileys-version.json +1 -1
  4. package/lib/Defaults/index.d.ts +53 -0
  5. package/lib/Defaults/index.js +6 -6
  6. package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
  7. package/lib/Signal/Group/group-session-builder.d.ts +14 -0
  8. package/lib/Signal/Group/group_cipher.d.ts +17 -0
  9. package/lib/Signal/Group/index.d.ts +11 -0
  10. package/lib/Signal/Group/keyhelper.d.ts +10 -0
  11. package/lib/Signal/Group/queue-job.d.ts +1 -0
  12. package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
  13. package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
  14. package/lib/Signal/Group/sender-key-message.d.ts +18 -0
  15. package/lib/Signal/Group/sender-key-name.d.ts +17 -0
  16. package/lib/Signal/Group/sender-key-record.d.ts +30 -0
  17. package/lib/Signal/Group/sender-key-state.d.ts +38 -0
  18. package/lib/Signal/Group/sender-message-key.d.ts +11 -0
  19. package/lib/Signal/libsignal.d.ts +3 -0
  20. package/lib/Socket/Client/abstract-socket-client.d.ts +17 -0
  21. package/lib/Socket/Client/index.d.ts +3 -0
  22. package/lib/Socket/Client/mobile-socket-client.d.ts +13 -0
  23. package/lib/Socket/Client/web-socket-client.d.ts +12 -0
  24. package/lib/Socket/business.d.ts +171 -0
  25. package/lib/Socket/chats.d.ts +267 -0
  26. package/lib/Socket/chats.js +39 -48
  27. package/lib/Socket/communities.d.ts +180 -0
  28. package/lib/Socket/communities.js +421 -0
  29. package/lib/Socket/groups.d.ts +115 -0
  30. package/lib/Socket/groups.js +64 -0
  31. package/lib/Socket/index.d.ts +173 -0
  32. package/lib/Socket/luxu.d.ts +266 -0
  33. package/lib/Socket/luxu.js +541 -0
  34. package/lib/Socket/messages-recv.d.ts +161 -0
  35. package/lib/Socket/messages-send.d.ts +183 -0
  36. package/lib/Socket/messages-send.js +410 -157
  37. package/lib/Socket/newsletter.d.ts +134 -0
  38. package/lib/Socket/newsletter.js +14 -133
  39. package/lib/Socket/registration.d.ts +267 -0
  40. package/lib/Socket/socket.d.ts +44 -0
  41. package/lib/Socket/socket.js +73 -2
  42. package/lib/Socket/usync.d.ts +36 -0
  43. package/lib/Store/index.d.ts +3 -0
  44. package/lib/Store/make-cache-manager-store.d.ts +13 -0
  45. package/lib/Store/make-in-memory-store.d.ts +118 -0
  46. package/lib/Store/make-ordered-dictionary.d.ts +13 -0
  47. package/lib/Store/object-repository.d.ts +10 -0
  48. package/lib/Types/Auth.d.ts +110 -0
  49. package/lib/Types/Call.d.ts +13 -0
  50. package/lib/Types/Chat.d.ts +102 -0
  51. package/lib/Types/Contact.d.ts +19 -0
  52. package/lib/Types/Events.d.ts +157 -0
  53. package/lib/Types/GroupMetadata.d.ts +55 -0
  54. package/lib/Types/Label.d.ts +35 -0
  55. package/lib/Types/LabelAssociation.d.ts +29 -0
  56. package/lib/Types/Message.d.ts +273 -0
  57. package/lib/Types/Newsletter.d.ts +103 -0
  58. package/lib/Types/Product.d.ts +78 -0
  59. package/lib/Types/Signal.d.ts +57 -0
  60. package/lib/Types/Socket.d.ts +111 -0
  61. package/lib/Types/State.d.ts +27 -0
  62. package/lib/Types/USync.d.ts +25 -0
  63. package/lib/Types/index.d.ts +57 -0
  64. package/lib/Utils/auth-utils.d.ts +18 -0
  65. package/lib/Utils/baileys-event-stream.d.ts +16 -0
  66. package/lib/Utils/business.d.ts +22 -0
  67. package/lib/Utils/chat-utils.d.ts +71 -0
  68. package/lib/Utils/crypto.d.ts +41 -0
  69. package/lib/Utils/decode-wa-message.d.ts +19 -0
  70. package/lib/Utils/event-buffer.d.ts +35 -0
  71. package/lib/Utils/generics.d.ts +92 -0
  72. package/lib/Utils/generics.js +5 -80
  73. package/lib/Utils/history.d.ts +15 -0
  74. package/lib/Utils/index.d.ts +17 -0
  75. package/lib/Utils/link-preview.d.ts +21 -0
  76. package/lib/Utils/logger.d.ts +4 -0
  77. package/lib/Utils/lt-hash.d.ts +12 -0
  78. package/lib/Utils/make-mutex.d.ts +7 -0
  79. package/lib/Utils/messages-media.d.ts +116 -0
  80. package/lib/Utils/messages.d.ts +77 -0
  81. package/lib/Utils/messages.js +45 -5
  82. package/lib/Utils/noise-handler.d.ts +21 -0
  83. package/lib/Utils/process-message.d.ts +41 -0
  84. package/lib/Utils/signal.d.ts +32 -0
  85. package/lib/Utils/use-multi-file-auth-state.d.ts +13 -0
  86. package/lib/Utils/validate-connection.d.ts +11 -0
  87. package/lib/Utils/validate-connection.js +2 -2
  88. package/lib/WABinary/constants.d.ts +30 -0
  89. package/lib/WABinary/decode.d.ts +7 -0
  90. package/lib/WABinary/encode.d.ts +3 -0
  91. package/lib/WABinary/generic-utils.d.ts +17 -0
  92. package/lib/WABinary/index.d.ts +5 -0
  93. package/lib/WABinary/jid-utils.d.ts +31 -0
  94. package/lib/WABinary/types.d.ts +18 -0
  95. package/lib/WAM/BinaryInfo.d.ts +17 -0
  96. package/lib/WAM/constants.d.ts +38 -0
  97. package/lib/WAM/encode.d.ts +3 -0
  98. package/lib/WAM/index.d.ts +3 -0
  99. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -0
  100. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
  101. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  102. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  103. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +25 -0
  104. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +8 -0
  105. package/lib/WAUSync/Protocols/index.d.ts +4 -0
  106. package/lib/WAUSync/USyncQuery.d.ts +28 -0
  107. package/lib/WAUSync/USyncUser.d.ts +12 -0
  108. package/lib/index.d.ts +12 -0
  109. package/lib/index.js +7 -3
  110. package/package.json +104 -105
  111. package/lib/Socket/dugong.js +0 -637
@@ -8,13 +8,16 @@ const boom_1 = require("@hapi/boom");
8
8
  const node_cache_1 = __importDefault(require("node-cache"));
9
9
  const WAProto_1 = require("../../WAProto");
10
10
  const Defaults_1 = require("../Defaults");
11
- const Types_1 = require("../Types");
11
+ const axios_1 = require("axios")
12
+ const Types_1 = require("../Types")
12
13
  const Utils_1 = require("../Utils");
13
14
  const link_preview_1 = require("../Utils/link-preview");
14
15
  const WABinary_1 = require("../WABinary");
15
- const newsletter_1 = require("./newsletter");
16
+ const communities_1 = require("./communities");
16
17
  const WAUSync_1 = require("../WAUSync");
17
- const kikyy = require('./dugong');
18
+ const crypto = require("crypto");
19
+ const imup = require('./luxu');
20
+ var ListType = WAProto_1.proto.Message.ListMessage.ListType;
18
21
  const makeMessagesSocket = (config) => {
19
22
  const {
20
23
  logger,
@@ -23,7 +26,7 @@ const makeMessagesSocket = (config) => {
23
26
  options: axiosOptions,
24
27
  patchMessageBeforeSending
25
28
  } = config;
26
- const sock = (0, newsletter_1.makeNewsletterSocket)(config);
29
+ const sock = (0, communities_1.makeCommunitiesSocket)(config);
27
30
  const {
28
31
  ev,
29
32
  authState,
@@ -32,6 +35,7 @@ const makeMessagesSocket = (config) => {
32
35
  upsertMessage,
33
36
  query,
34
37
  fetchPrivacySettings,
38
+ generateMessageTag,
35
39
  sendNode,
36
40
  groupMetadata,
37
41
  groupToggleEphemeral,
@@ -71,6 +75,10 @@ const makeMessagesSocket = (config) => {
71
75
  }
72
76
  return mediaConn;
73
77
  };
78
+ /**
79
+ * generic send receipt function
80
+ * used for receipts of phone call, read, delivery etc.
81
+ * */
74
82
  const sendReceipt = async (jid, participant, messageIds, type) => {
75
83
  const node = {
76
84
  tag: 'receipt',
@@ -111,63 +119,84 @@ const makeMessagesSocket = (config) => {
111
119
  logger.debug({ attrs: node.attrs, messageIds }, 'sending receipt for messages');
112
120
  await sendNode(node);
113
121
  };
122
+ /** Correctly bulk send receipts to multiple chats, participants */
114
123
  const sendReceipts = async (keys, type) => {
115
124
  const recps = (0, Utils_1.aggregateMessageKeysNotFromMe)(keys);
116
125
  for (const { jid, participant, messageIds } of recps) {
117
126
  await sendReceipt(jid, participant, messageIds, type);
118
127
  }
119
128
  };
129
+ /** Bulk read messages. Keys can be from different chats & participants */
120
130
  const readMessages = async (keys) => {
121
131
  const privacySettings = await fetchPrivacySettings();
132
+ // based on privacy settings, we have to change the read type
122
133
  const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self';
123
134
  await sendReceipts(keys, readType);
124
135
  };
136
+ /** Fetch all the devices we've to send a message to */
125
137
  const getUSyncDevices = async (jids, useCache, ignoreZeroDevices) => {
126
138
  const deviceResults = []
139
+
127
140
  if (!useCache) {
128
141
  logger.debug('not using cache for devices')
129
142
  }
143
+
130
144
  const toFetch = []
145
+
131
146
  jids = Array.from(new Set(jids))
147
+
132
148
  for (let jid of jids) {
133
149
  const user = WABinary_1.jidDecode(jid)?.user
150
+
134
151
  jid = WABinary_1.jidNormalizedUser(jid)
152
+
135
153
  if (useCache) {
136
154
  const devices = userDevicesCache.get(user)
155
+
137
156
  if (devices) {
138
157
  deviceResults.push(...devices)
139
158
  logger.trace({ user }, 'using cache for devices')
140
159
  }
160
+
141
161
  else {
142
162
  toFetch.push(jid)
143
163
  }
144
164
  }
165
+
145
166
  else {
146
167
  toFetch.push(jid)
147
168
  }
148
169
  }
170
+
149
171
  if (!toFetch.length) {
150
172
  return deviceResults
151
173
  }
174
+
152
175
  const query = new WAUSync_1.USyncQuery()
153
176
  .withContext('message')
154
177
  .withDeviceProtocol()
178
+
155
179
  for (const jid of toFetch) {
156
180
  query.withUser(new WAUSync_1.USyncUser().withId(jid))
157
181
  }
182
+
158
183
  const result = await executeUSyncQuery(query)
184
+
159
185
  if (result) {
160
186
  const extracted = Utils_1.extractDeviceJids(result?.list, authState.creds.me.id, ignoreZeroDevices)
161
187
  const deviceMap = {}
188
+
162
189
  for (const item of extracted) {
163
190
  deviceMap[item.user] = deviceMap[item.user] || []
164
191
  deviceMap[item.user].push(item)
165
192
  deviceResults.push(item)
166
193
  }
194
+
167
195
  for (const key in deviceMap) {
168
196
  userDevicesCache.set(key, deviceMap[key])
169
197
  }
170
198
  }
199
+
171
200
  return deviceResults
172
201
  }
173
202
  const assertSessions = async (jids, force) => {
@@ -213,10 +242,13 @@ const makeMessagesSocket = (config) => {
213
242
  }
214
243
  return didFetchNewSession;
215
244
  };
245
+
246
+
216
247
  const sendPeerDataOperationMessage = async (pdoMessage) => {
217
248
  if (!authState.creds.me?.id) {
218
249
  throw new boom_1.Boom('Not authenticated')
219
250
  }
251
+
220
252
  const protocolMessage = {
221
253
  protocolMessage: {
222
254
  peerDataOperationRequestMessage: pdoMessage,
@@ -227,6 +259,7 @@ const makeMessagesSocket = (config) => {
227
259
  const msgId = await relayMessage(meJid, protocolMessage, {
228
260
  additionalAttributes: {
229
261
  category: 'peer',
262
+ // eslint-disable-next-line camelcase
230
263
  push_priority: 'high_force',
231
264
  },
232
265
  });
@@ -259,6 +292,7 @@ const makeMessagesSocket = (config) => {
259
292
  }));
260
293
  return { nodes, shouldIncludeDeviceIdentity };
261
294
  };
295
+
262
296
  const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, cachedGroupMetadata, useCachedGroupMetadata, statusJidList, AI = true }) => {
263
297
  const meId = authState.creds.me.id;
264
298
  let shouldIncludeDeviceIdentity = false;
@@ -284,9 +318,12 @@ const makeMessagesSocket = (config) => {
284
318
  }
285
319
  };
286
320
  const extraAttrs = {}
287
- const messages = Utils_1.normalizeMessageContent(message);
321
+ const messages = Utils_1.normalizeMessageContent(message)
288
322
  const buttonType = getButtonType(messages);
289
323
  if (participant) {
324
+ // when the retry request is not for a group
325
+ // only send to the specific device that asked for a retry
326
+ // otherwise the message is sent out to every device that should be a recipient
290
327
  if (!isGroup && !isStatus) {
291
328
  additionalAttributes = { ...additionalAttributes, 'device_fanout': 'false' };
292
329
  }
@@ -295,15 +332,19 @@ const makeMessagesSocket = (config) => {
295
332
  }
296
333
  await authState.keys.transaction(async () => {
297
334
  const mediaType = getMediaType(messages);
335
+
298
336
  if (mediaType) {
299
337
  extraAttrs['mediatype'] = mediaType
300
338
  }
339
+
301
340
  if (messages.pinInChatMessage || messages.keepInChatMessage || message.reactionMessage || message.protocolMessage?.editedMessage) {
302
341
  extraAttrs['decrypt-fail'] = 'hide'
303
- }
342
+ }
343
+
304
344
  if (messages.interactiveResponseMessage?.nativeFlowResponseMessage) {
305
345
  extraAttrs['native_flow_name'] = messages.interactiveResponseMessage?.nativeFlowResponseMessage.name
306
346
  }
347
+
307
348
  if (isGroup || isStatus) {
308
349
  const [groupData, senderKeyMap] = await Promise.all([
309
350
  (async () => {
@@ -311,9 +352,11 @@ const makeMessagesSocket = (config) => {
311
352
  if (groupData) {
312
353
  logger.trace({ jid, participants: groupData.participants.length }, 'using cached group metadata');
313
354
  }
355
+
314
356
  else if (!isStatus) {
315
357
  groupData = await groupMetadata(jid)
316
358
  }
359
+
317
360
  return groupData;
318
361
  })(),
319
362
  (async () => {
@@ -321,32 +364,51 @@ const makeMessagesSocket = (config) => {
321
364
  const result = await authState.keys.get('sender-key-memory', [jid])
322
365
  return result[jid] || {}
323
366
  }
367
+
324
368
  return {}
325
- })()
369
+
370
+ })()
326
371
  ]);
327
372
  if (!participant) {
328
373
  const participantsList = (groupData && !isStatus) ? groupData.participants.map(p => p.id) : []
374
+
329
375
  if (isStatus && statusJidList) {
330
376
  participantsList.push(...statusJidList)
331
377
  }
378
+
379
+ // if (!isStatus) {
380
+ // const expiration = await getEphemeralGroup(jid)
381
+ // additionalAttributes = {
382
+ // ...additionalAttributes,
383
+ // addressing_mode: 'pn',
384
+ // ...expiration ? { expiration: expiration.toString() } : null
385
+ // }
386
+ // }
387
+
332
388
  const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false)
333
389
  devices.push(...additionalDevices)
334
390
  }
391
+
335
392
  const patched = await patchMessageBeforeSending(message, devices.map(d => WABinary_1.jidEncode(d.user, isLid ? 'lid' : 's.whatsapp.net', d.device)));
336
393
  const bytes = Utils_1.encodeWAMessage(patched);
394
+
337
395
  const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({
338
396
  group: destinationJid,
339
397
  data: bytes,
340
398
  meId,
341
399
  });
342
400
  const senderKeyJids = [];
401
+
343
402
  for (const { user, device } of devices) {
344
403
  const jid = WABinary_1.jidEncode(user, (groupData === null || groupData === void 0 ? void 0 : groupData.addressingMode) === 'lid' ? 'lid' : 's.whatsapp.net', device);
345
404
  if (!senderKeyMap[jid] || !!participant) {
346
405
  senderKeyJids.push(jid);
406
+ // store that this person has had the sender keys sent to them
347
407
  senderKeyMap[jid] = true;
348
408
  }
349
409
  }
410
+ // if there are some participants with whom the session has not been established
411
+ // if there are, we re-send the senderkey
350
412
  if (senderKeyJids.length) {
351
413
  logger.debug({ senderKeyJids }, 'sending new sender key');
352
414
  const senderKeyMsg = {
@@ -368,16 +430,21 @@ const makeMessagesSocket = (config) => {
368
430
  await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } });
369
431
  }
370
432
  else if (isNewsletter) {
433
+ // Message edit
371
434
  if (message.protocolMessage?.editedMessage) {
372
435
  msgId = message.protocolMessage.key?.id
373
436
  message = message.protocolMessage.editedMessage
374
437
  }
438
+
439
+ // Message delete
375
440
  if (message.protocolMessage?.type === WAProto_1.proto.Message.ProtocolMessage.Type.REVOKE) {
376
441
  msgId = message.protocolMessage.key?.id
377
442
  message = {}
378
443
  }
444
+
379
445
  const patched = await patchMessageBeforeSending(message, [])
380
446
  const bytes = Utils_1.encodeNewsletterMessage(patched)
447
+
381
448
  binaryNodeContent.push({
382
449
  tag: 'plaintext',
383
450
  attrs: extraAttrs ? extraAttrs : {},
@@ -391,8 +458,10 @@ const makeMessagesSocket = (config) => {
391
458
  if (user !== meUser) {
392
459
  devices.push({ user: meUser })
393
460
  }
461
+
394
462
  if (additionalAttributes?.['category'] !== 'peer') {
395
463
  const additionalDevices = await getUSyncDevices([meId, jid], !!useUserDevicesCache, true)
464
+
396
465
  devices.push(...additionalDevices)
397
466
  }
398
467
  }
@@ -402,12 +471,15 @@ const makeMessagesSocket = (config) => {
402
471
  for (const { user, device } of devices) {
403
472
  const isMe = user === meUser
404
473
  const jid = WABinary_1.jidEncode(isMe && isLid ? authState.creds?.me?.lid?.split(':')[0] || user : user, isLid ? 'lid' : 's.whatsapp.net', device)
474
+
405
475
  if (isMe) {
406
476
  meJids.push(jid)
407
477
  }
478
+
408
479
  else {
409
480
  otherJids.push(jid)
410
481
  }
482
+
411
483
  allJids.push(jid)
412
484
  }
413
485
  await assertSessions(allJids, false);
@@ -422,10 +494,12 @@ const makeMessagesSocket = (config) => {
422
494
  if (participants.length) {
423
495
  if (additionalAttributes?.['category'] === 'peer') {
424
496
  const peerNode = participants[0]?.content?.[0]
497
+
425
498
  if (peerNode) {
426
- binaryNodeContent.push(peerNode)
499
+ binaryNodeContent.push(peerNode) // push only enc
427
500
  }
428
501
  }
502
+
429
503
  else {
430
504
  binaryNodeContent.push({
431
505
  tag: 'participants',
@@ -434,15 +508,19 @@ const makeMessagesSocket = (config) => {
434
508
  })
435
509
  }
436
510
  }
511
+
437
512
  const stanza = {
438
513
  tag: 'message',
439
514
  attrs: {
440
515
  id: msgId,
441
- type: getTypeMessage(messages),
516
+ type: getTypeMessage(messages),
442
517
  ...(additionalAttributes || {})
443
518
  },
444
519
  content: binaryNodeContent
445
520
  }
521
+ // if the participant to send to is explicitly specified (generally retry recp)
522
+ // ensure the message is only sent to that person
523
+ // if a retry receipt is sent to everyone -- it'll fail decryption for everyone else who received the msg
446
524
  if (participant) {
447
525
  if (WABinary_1.isJidGroup(destinationJid)) {
448
526
  stanza.attrs.to = destinationJid;
@@ -467,67 +545,112 @@ const makeMessagesSocket = (config) => {
467
545
  });
468
546
  logger.debug({ jid }, 'adding device identity');
469
547
  }
548
+
470
549
  if (AI && isPrivate) {
471
550
  const botNode = {
472
- tag: 'bot',
551
+ tag: 'bot',
473
552
  attrs: {
474
553
  biz_bot: '1'
475
554
  }
476
555
  }
477
- const filteredBizBot = WABinary_1.getBinaryNodeFilter(additionalNodes ? additionalNodes : [])
556
+
557
+ const filteredBizBot = WABinary_1.getBinaryNodeFilter(additionalNodes ? additionalNodes : [])
558
+
478
559
  if (filteredBizBot) {
479
- stanza.content.push(...additionalNodes)
560
+ stanza.content.push(...additionalNodes)
480
561
  didPushAdditional = true
481
562
  }
563
+
482
564
  else {
483
- stanza.content.push(botNode)
565
+ stanza.content.push(botNode)
484
566
  }
485
567
  }
486
- if (!isNewsletter && buttonType && !isStatus) {
568
+
569
+ if(!isNewsletter && buttonType && !isStatus) {
487
570
  const content = WABinary_1.getAdditionalNode(buttonType)
488
571
  const filteredNode = WABinary_1.getBinaryNodeFilter(additionalNodes)
572
+
489
573
  if (filteredNode) {
490
574
  didPushAdditional = true
491
575
  stanza.content.push(...additionalNodes)
492
- }
576
+ }
493
577
  else {
494
578
  stanza.content.push(...content)
495
579
  }
496
580
  logger.debug({ jid }, 'adding business node')
497
- }
581
+ }
582
+
498
583
  if (!didPushAdditional && additionalNodes && additionalNodes.length > 0) {
499
584
  stanza.content.push(...additionalNodes);
500
585
  }
586
+
501
587
  logger.debug({ msgId }, `sending message to ${participants.length} devices`);
502
588
  await sendNode(stanza);
503
589
  });
504
- message = Types_1.WAProto.Message.fromObject(message)
505
- const messageJSON = {
506
- key: {
507
- remoteJid: jid,
508
- fromMe: true,
509
- id: msgId
510
- },
511
- message: message,
512
- messageTimestamp: Utils_1.unixTimestampSeconds(new Date()),
513
- messageStubParameters: [],
514
- participant: WABinary_1.isJidGroup(jid) || WABinary_1.isJidStatusBroadcast(jid) ? meId : undefined,
515
- status: Types_1.WAMessageStatus.PENDING
590
+ return msgId;
591
+ };
592
+
593
+ const sendMessageMembers = async (jid, message, options = {}) => {
594
+ const {
595
+ messageId: idm,
596
+ quoted,
597
+ delayMs = 1500,
598
+ useUserDevicesCache = true,
599
+ cachedGroupMetadata
600
+ } = options;
601
+
602
+ const { server } = WABinary_1.jidDecode(jid);
603
+ if (server !== "g.us") throw new Error("@g.us server required");
604
+
605
+ const meId = authState.creds.me.id;
606
+ const messages = Utils_1.normalizeMessageContent(message);
607
+ const groupData = cachedGroupMetadata? await cachedGroupMetadata(jid) : await groupMetadata(jid);
608
+ const isLid = groupData.addressingMode === "lid";
609
+ const participantJids = groupData.participants.map(p => p.id);
610
+
611
+ logger.info(`Sending message to ${participantJids.length} members from ${jid}`);
612
+
613
+ for (let i = 0; i < participantJids.length; i++) {
614
+ const jid = participantJids[i];
615
+ if (WABinary_1.areJidsSameUser(jid, meId)) continue;
616
+
617
+ try {
618
+ const msgId = `${idm || Utils_1.generateMessageID()}_${i}`;
619
+ const fullMsg = await Utils_1.generateWAMessageFromContent(jid, message, {
620
+ messageId: msgId,
621
+ quoted
622
+ })
623
+ await relayMessage(jid, fullMsg.message, {
624
+ messageId: fullMsg.key.id
625
+ });
626
+
627
+ logger.debug(`Message successfully sent to ${jid}`);
628
+ if (delayMs && i < participantJids.length - 1) {
629
+ await new Promise(z => setTimeout(z, delayMs));
630
+ }
631
+ } catch (e) {
632
+ logger.error({ jid, e }, "Error sending message to");
516
633
  }
517
- return Types_1.WAProto.WebMessageInfo.fromObject(messageJSON);
634
+ }
635
+ return JSON.stringify({
636
+ members_total: participantJids.length,
637
+ message
638
+ }, null, 4);
518
639
  };
640
+
519
641
  const getTypeMessage = (msg) => {
520
- const message = Utils_1.normalizeMessageContent(msg);
642
+ const message = Utils_1.normalizeMessageContent(msg)
521
643
  if (message.reactionMessage) {
522
644
  return 'reaction'
523
- }
645
+ }
524
646
  else if (getMediaType(message)) {
525
647
  return 'media'
526
- }
648
+ }
527
649
  else {
528
650
  return 'text'
529
651
  }
530
652
  }
653
+
531
654
  const getMediaType = (message) => {
532
655
  if (message.imageMessage) {
533
656
  return 'image'
@@ -578,6 +701,7 @@ const makeMessagesSocket = (config) => {
578
701
  return 'productlink'
579
702
  }
580
703
  }
704
+
581
705
  const getButtonType = (message) => {
582
706
  if (message.listMessage) {
583
707
  return 'list'
@@ -593,8 +717,9 @@ const makeMessagesSocket = (config) => {
593
717
  }
594
718
  else if (message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'payment_info') {
595
719
  return 'payment_info'
596
- }
597
- else if (message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'payment_status') {
720
+ } else if (message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'payment_key_info') {
721
+ return 'payment_key_info'
722
+ } else if (message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'payment_status') {
598
723
  return 'payment_status'
599
724
  }
600
725
  else if (message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'payment_method') {
@@ -632,18 +757,142 @@ const makeMessagesSocket = (config) => {
632
757
  ]
633
758
  });
634
759
  return result;
635
- }
760
+ }
636
761
  const waUploadToServer = (0, Utils_1.getWAUploadToServer)(config, refreshMediaConn);
637
- const rahmi = new kikyy(Utils_1, waUploadToServer, relayMessage, config, sock);
762
+ const luki = new imup(Utils_1, waUploadToServer, relayMessage, authState);
638
763
  const waitForMsgMediaUpdate = (0, Utils_1.bindWaitForEvent)(ev, 'messages.media-update');
764
+ const sendMessage = async (jid, content, options = {}) => {
765
+ const userJid = authState.creds.me.id;
766
+ delete options.ephemeralExpiration
767
+ const { ptcp = false, quoted } = options;
768
+ const getParticipantAttr = () => ptcp ? { participant: { jid } } : {};
769
+ const messageType = luki.detectType(content);
770
+ if (typeof content === 'object' && 'disappearingMessagesInChat' in content &&
771
+ typeof content['disappearingMessagesInChat'] !== 'undefined' && WABinary_1.isJidGroup(jid)) {
772
+ const { disappearingMessagesInChat } = content
773
+
774
+ const value = typeof disappearingMessagesInChat === 'boolean' ?
775
+ (disappearingMessagesInChat ? Defaults_1.WA_DEFAULT_EPHEMERAL : 0) :
776
+ disappearingMessagesInChat
777
+
778
+ await groupToggleEphemeral(jid, value)
779
+ }
780
+
781
+ else {
782
+ let mediaHandle
783
+
784
+
785
+ if (messageType) {
786
+ switch(messageType) {
787
+ case 'PAYMENT':
788
+ const paymentContent = await luki.handlePayment(content, quoted);
789
+ return await relayMessage(jid, paymentContent, {
790
+ messageId: Utils_1.generateMessageID(),
791
+ ...getParticipantAttr()
792
+ });
793
+
794
+ case 'PRODUCT':
795
+ const productContent = await luki.handleProduct(content, jid, quoted);
796
+ const productMsg = await Utils_1.generateWAMessageFromContent(jid, productContent, { quoted });
797
+ return await relayMessage(jid, productMsg.message, {
798
+ messageId: productMsg.key.id,
799
+ ...getParticipantAttr()
800
+ });
801
+
802
+ case 'INTERACTIVE':
803
+ const interactiveContent = await luki.handleInteractive(content, jid, quoted);
804
+ const interactiveMsg = await Utils_1.generateWAMessageFromContent(jid, interactiveContent, { quoted });
805
+ return await relayMessage(jid, interactiveMsg.message, {
806
+ messageId: interactiveMsg.key.id,
807
+ ...getParticipantAttr()
808
+ });
809
+
810
+ case 'ALBUM':
811
+ return await luki.handleAlbum(content, jid, quoted)
812
+ case 'EVENT':
813
+ return await luki.handleEvent(content, jid, quoted)
814
+ case 'POLL_RESULT':
815
+ return await luki.handlePollResult(content, jid, quoted)
816
+ case 'ORDER':
817
+ return await luki.handleOrderMessage(content, jid, quoted)
818
+ case 'GROUP_STATUS':
819
+ return await luki.handleGroupStory(content, jid, quoted)
820
+ case 'GROUP_LABEL':
821
+ return await luki.handleGbLabel(content, jid)
822
+ }
823
+ }
824
+ const fullMsg = await Utils_1.generateWAMessage(jid, content, {
825
+ logger,
826
+ userJid,
827
+ quoted,
828
+ getUrlInfo: text => link_preview_1.getUrlInfo(text, {
829
+ thumbnailWidth: linkPreviewImageThumbnailWidth,
830
+ fetchOpts: {
831
+ timeout: 3000,
832
+ ...axiosOptions || {}
833
+ },
834
+ logger,
835
+ uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
836
+ }),
837
+ upload: async (readStream, opts) => {
838
+ const up = await waUploadToServer(readStream, {
839
+ ...opts,
840
+ newsletter: WABinary_1.isJidNewsLetter(jid)
841
+ });
842
+ return up;
843
+ },
844
+ mediaCache: config.mediaCache,
845
+ options: config.options,
846
+ ...options
847
+ });
848
+
849
+ const isDeleteMsg = 'delete' in content && !!content.delete;
850
+ const isEditMsg = 'edit' in content && !!content.edit;
851
+ const isAiMsg = 'ai' in content && !!content.ai;
852
+
853
+ const additionalAttributes = {};
854
+ const additionalNodes = [];
855
+
856
+ if (isDeleteMsg) {
857
+ const fromMe = content.delete?.fromMe;
858
+ const isGroup = WABinary_1.isJidGroup(content.delete?.remoteJid);
859
+ additionalAttributes.edit = (isGroup && !fromMe) || WABinary_1.isJidNewsLetter(jid) ? '8' : '7';
860
+ } else if (isEditMsg) {
861
+ additionalAttributes.edit = WABinary_1.isJidNewsLetter(jid) ? '3' : '1';
862
+ } else if (isAiMsg) {
863
+ additionalNodes.push({
864
+ attrs: {
865
+ biz_bot: '1'
866
+ }, tag: "bot"
867
+ });
868
+ }
869
+
870
+ await relayMessage(jid, fullMsg.message, {
871
+ messageId: fullMsg.key.id,
872
+ cachedGroupMetadata: options.cachedGroupMetadata,
873
+ additionalNodes: isAiMsg ? additionalNodes : options.additionalNodes,
874
+ additionalAttributes,
875
+ statusJidList: options.statusJidList
876
+ });
877
+
878
+ if (config.emitOwnEvents) {
879
+ process.nextTick(() => {
880
+ processingMutex.mutex(() => upsertMessage(fullMsg, 'append'));
881
+ });
882
+ }
883
+ return fullMsg;
884
+ }
885
+ }
639
886
  return {
640
887
  ...sock,
641
888
  getPrivacyTokens,
642
889
  assertSessions,
643
890
  relayMessage,
891
+ sendMessageMembers,
644
892
  sendReceipt,
645
893
  sendReceipts,
646
- rahmi,
894
+ luki,
895
+ sendMessage,
647
896
  readMessages,
648
897
  refreshMediaConn,
649
898
  getUSyncDevices,
@@ -690,141 +939,145 @@ const makeMessagesSocket = (config) => {
690
939
  ev.emit('messages.update', [
691
940
  {
692
941
  key: message.key,
693
- update: {
942
+ update: {
694
943
  message: message.message
695
944
  }
696
945
  }
697
946
  ]);
698
947
  return message;
699
948
  },
700
- setLabelGroup: async (id, text) => {
701
- await relayMessage(id, {
702
- protocolMessage: {
703
- type: 30,
704
- memberLabel: {
705
- label: text.slice(0, 30)
706
- }
707
- }
708
- }, {
949
+ sendText: async (jid, text, options, quoted = null) => {
950
+ return sendMessage(jid, {
951
+ text,
952
+ ...options
953
+ }, { quoted })
954
+ },
955
+ sendImage: async (jid, image, caption, options, quoted = null) => {
956
+ return sendMessage(jid, {
957
+ image,
958
+ caption,
959
+ ...options
960
+ }, { quoted })
961
+ },
962
+ sendVideo: async (jid, video, caption, options, quoted = null) => {
963
+ return sendMessage(jid, {
964
+ video,
965
+ caption,
966
+ ...options
967
+ }, { quoted })
968
+ },
969
+ sendDocument: async (jid, document, caption, options, quoted = null) => {
970
+ return sendMessage(jid, {
971
+ document,
972
+ caption,
973
+ ...options
974
+ }, { quoted })
975
+ },
976
+ sendAudio: async (jid, audio, options, quoted = null) => {
977
+ return sendMessage(jid, {
978
+ audio,
979
+ ...options
980
+ }, { quoted })
981
+ },
982
+ sendLocation: async (jid, name, degreesLongitude, degreesLatitude, url, address, options, quoted = null) => {
983
+ return sendMessage(jid, {
984
+ location: {
985
+ degreesLongitude,
986
+ degreesLatitude,
987
+ name,
988
+ url,
989
+ address
990
+ },
991
+ ...options
992
+ }, { quoted })
993
+ },
994
+ sendPoll: async (jid, name, pollVote = [], multiSelect = false, options, quoted = null) => {
995
+ const selectableCount = multiSelect ? pollVote.length : 1;
996
+
997
+ return sendMessage(jid, {
998
+ poll: {
999
+ name,
1000
+ values: pollVote,
1001
+ selectableCount
1002
+ },
1003
+ ...options
1004
+ }, { quoted });
1005
+ },
1006
+ sendQuiz: (
1007
+ jid,
1008
+ name,
1009
+ pollVote = [],
1010
+ answer,
1011
+ options,
1012
+ quoted
1013
+ ) => {
1014
+ const poll = {
1015
+ name,
1016
+ values: pollVote,
1017
+ selectableCount: 1,
1018
+ type: "QUIZ",
1019
+ answer: { optionName: answer }
1020
+ }
1021
+ return sendMessage(jid, {
1022
+ poll,
1023
+ ...options
1024
+ }, { quoted })
1025
+ },
1026
+ sendPtv: (jid, ptv, options, quoted = null) => {
1027
+ return sendMessage(jid, {
1028
+ ptv,
1029
+ ...options
1030
+ }, { quoted })
1031
+ },
1032
+ statusMention: async (jid, content) => {
1033
+ const msg = Utils_1.generateWAMessageFromContent("status@broadcast", content, {})
1034
+
1035
+ await relayMessage("status@broadcast", msg.message, {
1036
+ messageId: msg.key.id,
1037
+ statusJidList: [jid, authState.creds.me.id],
709
1038
  additionalNodes: [
710
1039
  {
711
1040
  tag: "meta",
712
- attrs: {
713
- tag_reason: "user_update",
714
- appdata: "member_tag"
715
- },
716
- content: undefined
1041
+ attrs: {},
1042
+ content: [
1043
+ {
1044
+ tag: "mentioned_users",
1045
+ attrs: {},
1046
+ content: [
1047
+ {
1048
+ tag: "to",
1049
+ attrs: { jid },
1050
+ content: undefined
1051
+ }
1052
+ ]
1053
+ }
1054
+ ]
717
1055
  }
718
1056
  ]
719
1057
  })
720
- },
721
- sendStatusMention: async (content, jids = []) => {
722
- return await rahmi.sendStatusWhatsApp(content, jids);
723
- },
724
- sendMessage: async (jid, content, options = {}) => {
725
- const userJid = authState.creds.me.id;
726
- delete options.ephemeralExpiration
727
- const { filter = false, quoted } = options;
728
- const getParticipantAttr = () => filter ? { participant: { jid } } : {};
729
- const messageType = rahmi.detectType(content);
730
- if (typeof content === 'object' && 'disappearingMessagesInChat' in content &&
731
- typeof content['disappearingMessagesInChat'] !== 'undefined' && WABinary_1.isJidGroup(jid)) {
732
- const { disappearingMessagesInChat } = content
733
- const value = typeof disappearingMessagesInChat === 'boolean' ?
734
- (disappearingMessagesInChat ? Defaults_1.WA_DEFAULT_EPHEMERAL : 0) :
735
- disappearingMessagesInChat
736
- await groupToggleEphemeral(jid, value)
737
- }
738
- else {
739
- let mediaHandle
740
- if (messageType) {
741
- switch (messageType) {
742
- case 'PAYMENT':
743
- const paymentContent = await rahmi.handlePayment(content, quoted);
744
- return await relayMessage(jid, paymentContent, {
745
- messageId: Utils_1.generateMessageID(),
746
- ...getParticipantAttr()
747
- });
748
- case 'PRODUCT':
749
- const productContent = await rahmi.handleProduct(content, jid, quoted);
750
- const productMsg = await Utils_1.generateWAMessageFromContent(jid, productContent, { quoted });
751
- return await relayMessage(jid, productMsg.message, {
752
- messageId: productMsg.key.id,
753
- ...getParticipantAttr()
754
- });
755
- case 'INTERACTIVE':
756
- const interactiveContent = await rahmi.handleInteractive(content, jid, quoted);
757
- const interactiveMsg = await Utils_1.generateWAMessageFromContent(jid, interactiveContent, { quoted });
758
- return await relayMessage(jid, interactiveMsg.message, {
759
- messageId: interactiveMsg.key.id,
760
- ...getParticipantAttr()
761
- });
762
- case 'ALBUM':
763
- return await rahmi.handleAlbum(content, jid, quoted)
764
- case 'EVENT':
765
- return await rahmi.handleEvent(content, jid, quoted)
766
- case 'POLL_RESULT':
767
- return await rahmi.handlePollResult(content, jid, quoted)
768
- case 'GROUP_STORY':
769
- return await rahmi.handleGroupStory(content, jid, quoted)
1058
+
1059
+ const mentionMsg = {
1060
+ statusMentionMessage: {
1061
+ message: {
1062
+ protocolMessage: {
1063
+ key: msg.key,
1064
+ type: "STATUS_MENTION_MESSAGE",
1065
+ timestamp: Math.floor(Date.now() / 1000)
1066
+ }
770
1067
  }
771
1068
  }
772
- const fullMsg = await Utils_1.generateWAMessage(jid, content, {
773
- logger,
774
- userJid,
775
- quoted,
776
- getUrlInfo: text => link_preview_1.getUrlInfo(text, {
777
- thumbnailWidth: linkPreviewImageThumbnailWidth,
778
- fetchOpts: {
779
- timeout: 3000,
780
- ...axiosOptions || {}
781
- },
782
- logger,
783
- uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
784
- }),
785
- upload: async (readStream, opts) => {
786
- const up = await waUploadToServer(readStream, {
787
- ...opts,
788
- newsletter: WABinary_1.isJidNewsLetter(jid)
789
- });
790
- return up;
791
- },
792
- mediaCache: config.mediaCache,
793
- options: config.options,
794
- ...options
795
- });
796
- const isDeleteMsg = 'delete' in content && !!content.delete;
797
- const isEditMsg = 'edit' in content && !!content.edit;
798
- const isAiMsg = 'ai' in content && !!content.ai;
799
- const additionalAttributes = {};
800
- const additionalNodes = [];
801
- if (isDeleteMsg) {
802
- const fromMe = content.delete?.fromMe;
803
- const isGroup = WABinary_1.isJidGroup(content.delete?.remoteJid);
804
- additionalAttributes.edit = (isGroup && !fromMe) || WABinary_1.isJidNewsLetter(jid) ? '8' : '7';
805
- } else if (isEditMsg) {
806
- additionalAttributes.edit = WABinary_1.isJidNewsLetter(jid) ? '3' : '1';
807
- } else if (isAiMsg) {
808
- additionalNodes.push({
809
- attrs: {
810
- biz_bot: '1'
811
- }, tag: "bot"
812
- });
813
- }
814
- await relayMessage(jid, fullMsg.message, {
815
- messageId: fullMsg.key.id,
816
- cachedGroupMetadata: options.cachedGroupMetadata,
817
- additionalNodes: isAiMsg ? additionalNodes : options.additionalNodes,
818
- additionalAttributes,
819
- statusJidList: options.statusJidList
820
- });
821
- if (config.emitOwnEvents) {
822
- process.nextTick(() => {
823
- processingMutex.mutex(() => upsertMessage(fullMsg, 'append'));
824
- });
825
- }
826
- return fullMsg;
827
1069
  }
1070
+
1071
+ const x = Utils_1.generateWAMessageFromContent(jid, mentionMsg, {})
1072
+ return relayMessage(jid, x.message, {
1073
+ messageId: x.key.id,
1074
+ additionalNodes: [
1075
+ {
1076
+ tag: "meta",
1077
+ attrs: { is_status_mention: "true" }
1078
+ }
1079
+ ]
1080
+ })
828
1081
  }
829
1082
  }
830
1083
  };