@d0v3riz/baileys 6.7.4 → 6.7.6

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 (43) hide show
  1. package/README.md +5 -4
  2. package/lib/Defaults/index.js +3 -1
  3. package/lib/Socket/business.d.ts +8 -5
  4. package/lib/Socket/chats.d.ts +3 -8
  5. package/lib/Socket/chats.js +15 -1
  6. package/lib/Socket/groups.d.ts +9 -1
  7. package/lib/Socket/groups.js +12 -1
  8. package/lib/Socket/index.d.ts +8 -5
  9. package/lib/Socket/messages-recv.d.ts +8 -6
  10. package/lib/Socket/messages-recv.js +105 -12
  11. package/lib/Socket/messages-send.d.ts +5 -3
  12. package/lib/Socket/messages-send.js +83 -71
  13. package/lib/Socket/registration.d.ts +8 -5
  14. package/lib/Socket/socket.js +2 -2
  15. package/lib/Store/make-in-memory-store.js +5 -1
  16. package/lib/Types/Chat.d.ts +2 -0
  17. package/lib/Types/Events.d.ts +5 -1
  18. package/lib/Types/GroupMetadata.d.ts +1 -1
  19. package/lib/Types/Message.d.ts +27 -24
  20. package/lib/Types/Socket.d.ts +5 -0
  21. package/lib/Types/index.d.ts +7 -0
  22. package/lib/Utils/crypto.d.ts +1 -1
  23. package/lib/Utils/crypto.js +4 -2
  24. package/lib/Utils/decode-wa-message.d.ts +1 -0
  25. package/lib/Utils/decode-wa-message.js +16 -7
  26. package/lib/Utils/generics.d.ts +4 -9
  27. package/lib/Utils/generics.js +34 -8
  28. package/lib/Utils/history.d.ts +4 -0
  29. package/lib/Utils/history.js +3 -0
  30. package/lib/Utils/messages-media.js +8 -14
  31. package/lib/Utils/messages.js +48 -58
  32. package/lib/Utils/noise-handler.d.ts +1 -1
  33. package/lib/Utils/noise-handler.js +2 -2
  34. package/lib/Utils/process-message.d.ts +3 -2
  35. package/lib/Utils/process-message.js +47 -24
  36. package/lib/Utils/signal.js +26 -16
  37. package/lib/WABinary/decode.d.ts +2 -2
  38. package/lib/WABinary/decode.js +6 -4
  39. package/lib/WABinary/encode.d.ts +1 -1
  40. package/lib/WABinary/encode.js +8 -4
  41. package/lib/WABinary/jid-utils.d.ts +2 -0
  42. package/lib/WABinary/jid-utils.js +4 -1
  43. package/package.json +6 -5
@@ -12,11 +12,10 @@ const Utils_1 = require("../Utils");
12
12
  const link_preview_1 = require("../Utils/link-preview");
13
13
  const WABinary_1 = require("../WABinary");
14
14
  const groups_1 = require("./groups");
15
- var ListType = WAProto_1.proto.Message.ListMessage.ListType;
16
15
  const makeMessagesSocket = (config) => {
17
- const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: axiosOptions, patchMessageBeforeSending, } = config;
16
+ const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: axiosOptions, patchMessageBeforeSending, cachedGroupMetadata, } = config;
18
17
  const sock = (0, groups_1.makeGroupsSocket)(config);
19
- const { ev, authState, processingMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, generateMessageTag, sendNode, groupMetadata, groupToggleEphemeral } = sock;
18
+ const { ev, authState, processingMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, generateMessageTag, sendNode, groupMetadata, groupToggleEphemeral, } = sock;
20
19
  const userDevicesCache = config.userDevicesCache || new node_cache_1.default({
21
20
  stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.USER_DEVICES,
22
21
  useClones: false
@@ -130,6 +129,9 @@ const makeMessagesSocket = (config) => {
130
129
  users.push({ tag: 'user', attrs: { jid } });
131
130
  }
132
131
  }
132
+ if (!users.length) {
133
+ return deviceResults;
134
+ }
133
135
  const iq = {
134
136
  tag: 'iq',
135
137
  attrs: {
@@ -219,6 +221,28 @@ const makeMessagesSocket = (config) => {
219
221
  }
220
222
  return didFetchNewSession;
221
223
  };
224
+ const sendPeerDataOperationMessage = async (pdoMessage) => {
225
+ var _a;
226
+ //TODO: for later, abstract the logic to send a Peer Message instead of just PDO - useful for App State Key Resync with phone
227
+ if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
228
+ throw new boom_1.Boom('Not authenticated');
229
+ }
230
+ const protocolMessage = {
231
+ protocolMessage: {
232
+ peerDataOperationRequestMessage: pdoMessage,
233
+ type: WAProto_1.proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_MESSAGE
234
+ }
235
+ };
236
+ const meJid = (0, WABinary_1.jidNormalizedUser)(authState.creds.me.id);
237
+ const msgId = await relayMessage(meJid, protocolMessage, {
238
+ additionalAttributes: {
239
+ category: 'peer',
240
+ // eslint-disable-next-line camelcase
241
+ push_priority: 'high_force',
242
+ },
243
+ });
244
+ return msgId;
245
+ };
222
246
  const createParticipantNodes = async (jids, message, extraAttrs) => {
223
247
  const patched = await patchMessageBeforeSending(message, jids);
224
248
  const bytes = (0, Utils_1.encodeWAMessage)(patched);
@@ -246,7 +270,8 @@ const makeMessagesSocket = (config) => {
246
270
  }));
247
271
  return { nodes, shouldIncludeDeviceIdentity };
248
272
  };
249
- const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache, cachedGroupMetadata, statusJidList }) => {
273
+ const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList }) => {
274
+ var _a;
250
275
  const meId = authState.creds.me.id;
251
276
  let shouldIncludeDeviceIdentity = false;
252
277
  const { user, server } = (0, WABinary_1.jidDecode)(jid);
@@ -254,8 +279,9 @@ const makeMessagesSocket = (config) => {
254
279
  const isGroup = server === 'g.us';
255
280
  const isStatus = jid === statusJid;
256
281
  const isLid = server === 'lid';
257
- msgId = msgId || (0, Utils_1.generateMessageID)();
282
+ msgId = msgId || (0, Utils_1.generateMessageIDV2)((_a = sock.user) === null || _a === void 0 ? void 0 : _a.id);
258
283
  useUserDevicesCache = useUserDevicesCache !== false;
284
+ useCachedGroupMetadata = useCachedGroupMetadata !== false && !isStatus;
259
285
  const participants = [];
260
286
  const destinationJid = (!isStatus) ? (0, WABinary_1.jidEncode)(user, isLid ? 'lid' : isGroup ? 'g.us' : 's.whatsapp.net') : statusJid;
261
287
  const binaryNodeContent = [];
@@ -266,6 +292,7 @@ const makeMessagesSocket = (config) => {
266
292
  message
267
293
  }
268
294
  };
295
+ const extraAttrs = {};
269
296
  if (participant) {
270
297
  // when the retry request is not for a group
271
298
  // only send to the specific device that asked for a retry
@@ -277,16 +304,22 @@ const makeMessagesSocket = (config) => {
277
304
  devices.push({ user, device });
278
305
  }
279
306
  await authState.keys.transaction(async () => {
280
- var _a, _b;
307
+ var _a, _b, _c, _d, _e;
281
308
  const mediaType = getMediaType(message);
309
+ if (mediaType) {
310
+ extraAttrs['mediatype'] = mediaType;
311
+ }
312
+ if ((_a = (0, Utils_1.normalizeMessageContent)(message)) === null || _a === void 0 ? void 0 : _a.pinInChatMessage) {
313
+ extraAttrs['decrypt-fail'] = 'hide';
314
+ }
282
315
  if (isGroup || isStatus) {
283
316
  const [groupData, senderKeyMap] = await Promise.all([
284
317
  (async () => {
285
- let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined;
286
- if (groupData) {
318
+ let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined;
319
+ if (groupData && Array.isArray(groupData === null || groupData === void 0 ? void 0 : groupData.participants)) {
287
320
  logger.trace({ jid, participants: groupData.participants.length }, 'using cached group metadata');
288
321
  }
289
- if (!groupData && !isStatus) {
322
+ else {
290
323
  groupData = await groupMetadata(jid);
291
324
  }
292
325
  return groupData;
@@ -335,7 +368,7 @@ const makeMessagesSocket = (config) => {
335
368
  }
336
369
  };
337
370
  await assertSessions(senderKeyJids, false);
338
- const result = await createParticipantNodes(senderKeyJids, senderKeyMsg, mediaType ? { mediatype: mediaType } : undefined);
371
+ const result = await createParticipantNodes(senderKeyJids, senderKeyMsg, extraAttrs);
339
372
  shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || result.shouldIncludeDeviceIdentity;
340
373
  participants.push(...result.nodes);
341
374
  }
@@ -351,18 +384,20 @@ const makeMessagesSocket = (config) => {
351
384
  if (!participant) {
352
385
  devices.push({ user });
353
386
  // do not send message to self if the device is 0 (mobile)
354
- if (meDevice !== undefined && meDevice !== 0) {
355
- devices.push({ user: meUser });
387
+ if (!((additionalAttributes === null || additionalAttributes === void 0 ? void 0 : additionalAttributes['category']) === 'peer' && user === meUser)) {
388
+ if (meDevice !== undefined && meDevice !== 0) {
389
+ devices.push({ user: meUser });
390
+ }
391
+ const additionalDevices = await getUSyncDevices([meId, jid], !!useUserDevicesCache, true);
392
+ devices.push(...additionalDevices);
356
393
  }
357
- const additionalDevices = await getUSyncDevices([meId, jid], !!useUserDevicesCache, true);
358
- devices.push(...additionalDevices);
359
394
  }
360
395
  const allJids = [];
361
396
  const meJids = [];
362
397
  const otherJids = [];
363
398
  for (const { user, device } of devices) {
364
399
  const isMe = user === meUser;
365
- const jid = (0, WABinary_1.jidEncode)(isMe && isLid ? ((_b = (_a = authState.creds) === null || _a === void 0 ? void 0 : _a.me) === null || _b === void 0 ? void 0 : _b.lid.split(':')[0]) || user : user, isLid ? 'lid' : 's.whatsapp.net', device);
400
+ const jid = (0, WABinary_1.jidEncode)(isMe && isLid ? ((_c = (_b = authState.creds) === null || _b === void 0 ? void 0 : _b.me) === null || _c === void 0 ? void 0 : _c.lid.split(':')[0]) || user : user, isLid ? 'lid' : 's.whatsapp.net', device);
366
401
  if (isMe) {
367
402
  meJids.push(jid);
368
403
  }
@@ -373,19 +408,27 @@ const makeMessagesSocket = (config) => {
373
408
  }
374
409
  await assertSessions(allJids, false);
375
410
  const [{ nodes: meNodes, shouldIncludeDeviceIdentity: s1 }, { nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }] = await Promise.all([
376
- createParticipantNodes(meJids, meMsg, mediaType ? { mediatype: mediaType } : undefined),
377
- createParticipantNodes(otherJids, message, mediaType ? { mediatype: mediaType } : undefined)
411
+ createParticipantNodes(meJids, meMsg, extraAttrs),
412
+ createParticipantNodes(otherJids, message, extraAttrs)
378
413
  ]);
379
414
  participants.push(...meNodes);
380
415
  participants.push(...otherNodes);
381
416
  shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2;
382
417
  }
383
418
  if (participants.length) {
384
- binaryNodeContent.push({
385
- tag: 'participants',
386
- attrs: {},
387
- content: participants
388
- });
419
+ if ((additionalAttributes === null || additionalAttributes === void 0 ? void 0 : additionalAttributes['category']) === 'peer') {
420
+ const peerNode = (_e = (_d = participants[0]) === null || _d === void 0 ? void 0 : _d.content) === null || _e === void 0 ? void 0 : _e[0];
421
+ if (peerNode) {
422
+ binaryNodeContent.push(peerNode); // push only enc
423
+ }
424
+ }
425
+ else {
426
+ binaryNodeContent.push({
427
+ tag: 'participants',
428
+ attrs: {},
429
+ content: participants
430
+ });
431
+ }
389
432
  }
390
433
  const stanza = {
391
434
  tag: 'message',
@@ -423,19 +466,8 @@ const makeMessagesSocket = (config) => {
423
466
  });
424
467
  logger.debug({ jid }, 'adding device identity');
425
468
  }
426
- const buttonType = getButtonType(message);
427
- if (buttonType) {
428
- stanza.content.push({
429
- tag: 'biz',
430
- attrs: {},
431
- content: [
432
- {
433
- tag: buttonType,
434
- attrs: getButtonArgs(message),
435
- }
436
- ]
437
- });
438
- logger.debug({ jid }, 'adding business node');
469
+ if (additionalNodes && additionalNodes.length > 0) {
470
+ stanza.content.push(...additionalNodes);
439
471
  }
440
472
  logger.debug({ msgId }, `sending message to ${participants.length} devices`);
441
473
  await sendNode(stanza);
@@ -485,38 +517,8 @@ const makeMessagesSocket = (config) => {
485
517
  else if (message.interactiveResponseMessage) {
486
518
  return 'native_flow_response';
487
519
  }
488
- };
489
- const getButtonType = (message) => {
490
- if (message.buttonsMessage) {
491
- return 'buttons';
492
- }
493
- else if (message.buttonsResponseMessage) {
494
- return 'buttons_response';
495
- }
496
- else if (message.interactiveResponseMessage) {
497
- return 'interactive_response';
498
- }
499
- else if (message.listMessage) {
500
- return 'list';
501
- }
502
- else if (message.listResponseMessage) {
503
- return 'list_response';
504
- }
505
- };
506
- const getButtonArgs = (message) => {
507
- if (message.templateMessage) {
508
- // TODO: Add attributes
509
- return {};
510
- }
511
- else if (message.listMessage) {
512
- const type = message.listMessage.listType;
513
- if (!type) {
514
- throw new boom_1.Boom('Expected list type inside message');
515
- }
516
- return { v: '2', type: ListType[type].toLowerCase() };
517
- }
518
- else {
519
- return {};
520
+ else if (message.groupInviteMessage) {
521
+ return 'url';
520
522
  }
521
523
  };
522
524
  const getPrivacyTokens = async (jids) => {
@@ -554,11 +556,11 @@ const makeMessagesSocket = (config) => {
554
556
  relayMessage,
555
557
  sendReceipt,
556
558
  sendReceipts,
557
- getButtonArgs,
558
559
  readMessages,
559
560
  refreshMediaConn,
560
561
  waUploadToServer,
561
562
  fetchPrivacySettings,
563
+ sendPeerDataOperationMessage,
562
564
  updateMediaMessage: async (message) => {
563
565
  const content = (0, Utils_1.assertMediaContent)(message.message);
564
566
  const mediaKey = content.mediaKey;
@@ -601,7 +603,7 @@ const makeMessagesSocket = (config) => {
601
603
  return message;
602
604
  },
603
605
  sendMessage: async (jid, content, options = {}) => {
604
- var _a, _b;
606
+ var _a, _b, _c;
605
607
  const userJid = authState.creds.me.id;
606
608
  if (typeof content === 'object' &&
607
609
  'disappearingMessagesInChat' in content &&
@@ -628,18 +630,22 @@ const makeMessagesSocket = (config) => {
628
630
  ? waUploadToServer
629
631
  : undefined
630
632
  }),
633
+ //TODO: CACHE
634
+ getProfilePicUrl: sock.profilePictureUrl,
631
635
  upload: waUploadToServer,
632
636
  mediaCache: config.mediaCache,
633
637
  options: config.options,
638
+ messageId: (0, Utils_1.generateMessageIDV2)((_a = sock.user) === null || _a === void 0 ? void 0 : _a.id),
634
639
  ...options,
635
640
  });
636
641
  const isDeleteMsg = 'delete' in content && !!content.delete;
637
642
  const isEditMsg = 'edit' in content && !!content.edit;
643
+ const isPinMsg = 'pin' in content && !!content.pin;
638
644
  const additionalAttributes = {};
639
645
  // required for delete
640
646
  if (isDeleteMsg) {
641
647
  // if the chat is a group, and I am not the author, then delete the message as an admin
642
- if ((0, WABinary_1.isJidGroup)((_a = content.delete) === null || _a === void 0 ? void 0 : _a.remoteJid) && !((_b = content.delete) === null || _b === void 0 ? void 0 : _b.fromMe)) {
648
+ if ((0, WABinary_1.isJidGroup)((_b = content.delete) === null || _b === void 0 ? void 0 : _b.remoteJid) && !((_c = content.delete) === null || _c === void 0 ? void 0 : _c.fromMe)) {
643
649
  additionalAttributes.edit = '8';
644
650
  }
645
651
  else {
@@ -649,7 +655,13 @@ const makeMessagesSocket = (config) => {
649
655
  else if (isEditMsg) {
650
656
  additionalAttributes.edit = '1';
651
657
  }
652
- await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id, cachedGroupMetadata: options.cachedGroupMetadata, additionalAttributes, statusJidList: options.statusJidList });
658
+ else if (isPinMsg) {
659
+ additionalAttributes.edit = '2';
660
+ }
661
+ if ('cachedGroupMetadata' in options) {
662
+ console.warn('cachedGroupMetadata in sendMessage are deprecated, now cachedGroupMetadata is part of the socket config.');
663
+ }
664
+ await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id, useCachedGroupMetadata: options.useCachedGroupMetadata, additionalAttributes, statusJidList: options.statusJidList });
653
665
  if (config.emitOwnEvents) {
654
666
  process.nextTick(() => {
655
667
  processingMutex.mutex(() => (upsertMessage(fullMsg, 'append')));
@@ -1,3 +1,4 @@
1
+ /// <reference types="long" />
1
2
  /// <reference types="node" />
2
3
  import { AxiosRequestConfig } from 'axios';
3
4
  import { KeyPair, SignedKeyPair, SocketConfig } from '../Types';
@@ -21,20 +22,20 @@ export declare const makeRegistrationSocket: (config: SocketConfig) => {
21
22
  sendMessageAck: ({ tag, attrs, content }: import("../WABinary").BinaryNode) => Promise<void>;
22
23
  sendRetryRequest: (node: import("../WABinary").BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
23
24
  rejectCall: (callId: string, callFrom: string) => Promise<void>;
25
+ fetchMessageHistory: (count: number, oldestMsgKey: import("../Types").WAProto.IMessageKey, oldestMsgTimestamp: number | import("long").Long) => Promise<string>;
26
+ requestPlaceholderResend: (messageKey: import("../Types").WAProto.IMessageKey) => Promise<string | undefined>;
24
27
  getPrivacyTokens: (jids: string[]) => Promise<import("../WABinary").BinaryNode>;
25
28
  assertSessions: (jids: string[], force: boolean) => Promise<boolean>;
26
- relayMessage: (jid: string, message: import("../Types").WAProto.IMessage, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache, cachedGroupMetadata, statusJidList }: import("../Types").MessageRelayOptions) => Promise<string>;
29
+ relayMessage: (jid: string, message: import("../Types").WAProto.IMessage, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList }: import("../Types").MessageRelayOptions) => Promise<string>;
27
30
  sendReceipt: (jid: string, participant: string | undefined, messageIds: string[], type: import("../Types").MessageReceiptType) => Promise<void>;
28
31
  sendReceipts: (keys: import("../Types").WAProto.IMessageKey[], type: import("../Types").MessageReceiptType) => Promise<void>;
29
- getButtonArgs: (message: import("../Types").WAProto.IMessage) => {
30
- [key: string]: string;
31
- };
32
32
  readMessages: (keys: import("../Types").WAProto.IMessageKey[]) => Promise<void>;
33
33
  refreshMediaConn: (forceGet?: boolean) => Promise<import("../Types").MediaConnInfo>;
34
34
  waUploadToServer: import("../Types").WAMediaUploadFunction;
35
35
  fetchPrivacySettings: (force?: boolean) => Promise<{
36
36
  [_: string]: string;
37
37
  }>;
38
+ sendPeerDataOperationMessage: (pdoMessage: import("../Types").WAProto.Message.IPeerDataOperationRequestMessage) => Promise<string>;
38
39
  updateMediaMessage: (message: import("../Types").WAProto.IWebMessageInfo) => Promise<import("../Types").WAProto.IWebMessageInfo>;
39
40
  sendMessage: (jid: string, content: import("../Types").AnyMessageContent, options?: import("../Types").MiscMessageGenerationOptions) => Promise<import("../Types").WAProto.WebMessageInfo | undefined>;
40
41
  groupMetadata: (jid: string) => Promise<import("../Types").GroupMetadata>;
@@ -57,6 +58,7 @@ export declare const makeRegistrationSocket: (config: SocketConfig) => {
57
58
  groupInviteCode: (jid: string) => Promise<string | undefined>;
58
59
  groupRevokeInvite: (jid: string) => Promise<string | undefined>;
59
60
  groupAcceptInvite: (code: string) => Promise<string | undefined>;
61
+ groupRevokeInviteV4: (groupJid: string, invitedJid: string) => Promise<boolean>;
60
62
  groupAcceptInviteV4: (key: string | import("../Types").WAProto.IMessageKey, inviteMessage: import("../Types").WAProto.Message.IGroupInviteMessage) => Promise<string>;
61
63
  groupGetInviteInfo: (code: string) => Promise<import("../Types").GroupMetadata>;
62
64
  groupToggleEphemeral: (jid: string, ephemeralExpiration: number) => Promise<void>;
@@ -88,12 +90,13 @@ export declare const makeRegistrationSocket: (config: SocketConfig) => {
88
90
  updateProfileStatus: (status: string) => Promise<void>;
89
91
  updateProfileName: (name: string) => Promise<void>;
90
92
  updateBlockStatus: (jid: string, action: "block" | "unblock") => Promise<void>;
93
+ updateCallPrivacy: (value: import("../Types").WAPrivacyCallValue) => Promise<void>;
91
94
  updateLastSeenPrivacy: (value: import("../Types").WAPrivacyValue) => Promise<void>;
92
95
  updateOnlinePrivacy: (value: import("../Types").WAPrivacyOnlineValue) => Promise<void>;
93
96
  updateProfilePicturePrivacy: (value: import("../Types").WAPrivacyValue) => Promise<void>;
94
97
  updateStatusPrivacy: (value: import("../Types").WAPrivacyValue) => Promise<void>;
95
98
  updateReadReceiptsPrivacy: (value: import("../Types").WAReadReceiptsValue) => Promise<void>;
96
- updateGroupsAddPrivacy: (value: import("../Types").WAPrivacyValue) => Promise<void>;
99
+ updateGroupsAddPrivacy: (value: import("../Types").WAPrivacyGroupAddValue) => Promise<void>;
97
100
  updateDefaultDisappearingMode: (duration: number) => Promise<void>;
98
101
  getBusinessProfile: (jid: string) => Promise<void | import("../Types").WABusinessProfile>;
99
102
  resyncAppState: (collections: readonly ("critical_block" | "critical_unblock_low" | "regular_high" | "regular_low" | "regular")[], isInitialSync: boolean) => Promise<void>;
@@ -403,7 +403,7 @@ const makeSocket = (config) => {
403
403
  {
404
404
  tag: 'companion_platform_id',
405
405
  attrs: {},
406
- content: '49' // Chrome
406
+ content: (0, Utils_1.getPlatformId)(browser[1])
407
407
  },
408
408
  {
409
409
  tag: 'companion_platform_display',
@@ -424,7 +424,7 @@ const makeSocket = (config) => {
424
424
  async function generatePairingKey() {
425
425
  const salt = (0, crypto_1.randomBytes)(32);
426
426
  const randomIv = (0, crypto_1.randomBytes)(16);
427
- const key = (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
427
+ const key = await (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
428
428
  const ciphered = (0, Utils_1.aesEncryptCTR)(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
429
429
  return Buffer.concat([salt, randomIv, ciphered]);
430
430
  }
@@ -66,7 +66,11 @@ exports.default = (config) => {
66
66
  ev.on('connection.update', update => {
67
67
  Object.assign(state, update);
68
68
  });
69
- ev.on('messaging-history.set', ({ chats: newChats, contacts: newContacts, messages: newMessages, isLatest }) => {
69
+ ev.on('messaging-history.set', ({ chats: newChats, contacts: newContacts, messages: newMessages, isLatest, syncType }) => {
70
+ if (syncType === WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND) {
71
+ return; // FOR NOW,
72
+ //TODO: HANDLE
73
+ }
70
74
  if (isLatest) {
71
75
  chats.clear();
72
76
  for (const id in messages) {
@@ -7,7 +7,9 @@ import type { MinimalMessage } from './Message';
7
7
  /** privacy settings in WhatsApp Web */
8
8
  export type WAPrivacyValue = 'all' | 'contacts' | 'contact_blacklist' | 'none';
9
9
  export type WAPrivacyOnlineValue = 'all' | 'match_last_seen';
10
+ export type WAPrivacyGroupAddValue = 'all' | 'contacts' | 'contact_blacklist';
10
11
  export type WAReadReceiptsValue = 'all' | 'none';
12
+ export type WAPrivacyCallValue = 'all' | 'known';
11
13
  /** set of statuses visible to other people; see updatePresence() in WhatsAppWeb.Send */
12
14
  export type WAPresence = 'unavailable' | 'available' | 'composing' | 'recording' | 'paused';
13
15
  export declare const ALL_WA_PATCH_NAMES: readonly ["critical_block", "critical_unblock_low", "regular_high", "regular_low", "regular"];
@@ -19,7 +19,9 @@ export type BaileysEventMap = {
19
19
  chats: Chat[];
20
20
  contacts: Contact[];
21
21
  messages: WAMessage[];
22
- isLatest: boolean;
22
+ isLatest?: boolean;
23
+ progress?: number | null;
24
+ syncType?: proto.HistorySync.HistorySyncType;
23
25
  };
24
26
  /** upsert chats */
25
27
  'chats.upsert': Chat[];
@@ -58,10 +60,12 @@ export type BaileysEventMap = {
58
60
  /**
59
61
  * add/update the given messages. If they were received while the connection was online,
60
62
  * the update will have type: "notify"
63
+ * if requestId is provided, then the messages was received from the phone due to it being unavailable
61
64
  * */
62
65
  'messages.upsert': {
63
66
  messages: WAMessage[];
64
67
  type: MessageUpsertType;
68
+ requestId?: string;
65
69
  };
66
70
  /** message was reacted to. If reaction was removed -- then "reaction.text" will be falsey */
67
71
  'messages.reaction': {
@@ -4,7 +4,7 @@ export type GroupParticipant = (Contact & {
4
4
  isSuperAdmin?: boolean;
5
5
  admin?: 'admin' | 'superadmin' | null;
6
6
  });
7
- export type ParticipantAction = 'add' | 'remove' | 'promote' | 'demote';
7
+ export type ParticipantAction = 'add' | 'remove' | 'promote' | 'demote' | 'modify';
8
8
  export type RequestJoinAction = 'created' | 'revoked' | 'rejected';
9
9
  export type RequestJoinMethod = 'invite_link' | 'linked_group_join' | 'non_admin_add' | undefined;
10
10
  export interface GroupMetadata {
@@ -7,6 +7,7 @@ import type { Readable } from 'stream';
7
7
  import type { URL } from 'url';
8
8
  import { proto } from '../../WAProto';
9
9
  import { MEDIA_HKDF_KEY_MAPPING } from '../Defaults';
10
+ import { BinaryNode } from '../WABinary';
10
11
  import type { GroupMetadata } from './GroupMetadata';
11
12
  import { CacheStore } from './Socket';
12
13
  export { proto as WAProto };
@@ -63,26 +64,9 @@ type Contextable = {
63
64
  type ViewOnce = {
64
65
  viewOnce?: boolean;
65
66
  };
66
- type Buttonable = {
67
- /** add buttons to the message */
68
- buttons?: proto.Message.ButtonsMessage.IButton[];
69
- };
70
- type Templatable = {
71
- /** add buttons to the message (conflicts with normal buttons)*/
72
- templateButtons?: proto.IHydratedTemplateButton[];
73
- footer?: string;
74
- };
75
67
  type Editable = {
76
68
  edit?: WAMessageKey;
77
69
  };
78
- type Listable = {
79
- /** Sections of the List */
80
- sections?: proto.Message.ListMessage.ISection[];
81
- /** Title of a List Message only */
82
- title?: string;
83
- /** Text of the bnutton on the list (required) */
84
- buttonText?: string;
85
- };
86
70
  type WithDimensions = {
87
71
  width?: number;
88
72
  height?: number;
@@ -93,6 +77,7 @@ export type PollMessageOptions = {
93
77
  values: string[];
94
78
  /** 32 byte message secret to encrypt poll selections */
95
79
  messageSecret?: Uint8Array;
80
+ toAnnouncementGroup?: boolean;
96
81
  };
97
82
  type SharePhoneNumber = {
98
83
  sharePhoneNumber: boolean;
@@ -105,14 +90,14 @@ export type AnyMediaMessageContent = (({
105
90
  image: WAMediaUpload;
106
91
  caption?: string;
107
92
  jpegThumbnail?: string;
108
- } & Mentionable & Contextable & Buttonable & Templatable & WithDimensions) | ({
93
+ } & Mentionable & Contextable & WithDimensions) | ({
109
94
  video: WAMediaUpload;
110
95
  caption?: string;
111
96
  gifPlayback?: boolean;
112
97
  jpegThumbnail?: string;
113
98
  /** if set to true, will send as a `video note` */
114
99
  ptv?: boolean;
115
- } & Mentionable & Contextable & Buttonable & Templatable & WithDimensions) | {
100
+ } & Mentionable & Contextable & WithDimensions) | {
116
101
  audio: WAMediaUpload;
117
102
  /** if set to true, will send as a `voice note` */
118
103
  ptt?: boolean;
@@ -126,7 +111,7 @@ export type AnyMediaMessageContent = (({
126
111
  mimetype: string;
127
112
  fileName?: string;
128
113
  caption?: string;
129
- } & Contextable & Buttonable & Templatable)) & {
114
+ } & Contextable)) & {
130
115
  mimetype?: string;
131
116
  } & Editable;
132
117
  export type ButtonReplyInfo = {
@@ -134,15 +119,22 @@ export type ButtonReplyInfo = {
134
119
  id: string;
135
120
  index: number;
136
121
  };
122
+ export type GroupInviteInfo = {
123
+ inviteCode: string;
124
+ inviteExpiration: number;
125
+ text: string;
126
+ jid: string;
127
+ subject: string;
128
+ };
137
129
  export type WASendableProduct = Omit<proto.Message.ProductMessage.IProductSnapshot, 'productImage'> & {
138
130
  productImage: WAMediaUpload;
139
131
  };
140
132
  export type AnyRegularMessageContent = (({
141
133
  text: string;
142
134
  linkPreview?: WAUrlInfo | null;
143
- } & Mentionable & Contextable & Buttonable & Templatable & Listable & Editable) | AnyMediaMessageContent | ({
135
+ } & Mentionable & Contextable & Editable) | AnyMediaMessageContent | ({
144
136
  poll: PollMessageOptions;
145
- } & Mentionable & Contextable & Buttonable & Templatable & Editable) | {
137
+ } & Mentionable & Contextable & Editable) | {
146
138
  contacts: {
147
139
  displayName?: string;
148
140
  contacts: proto.Message.IContactMessage[];
@@ -154,8 +146,17 @@ export type AnyRegularMessageContent = (({
154
146
  } | {
155
147
  buttonReply: ButtonReplyInfo;
156
148
  type: 'template' | 'plain';
149
+ } | {
150
+ groupInvite: GroupInviteInfo;
157
151
  } | {
158
152
  listReply: Omit<proto.Message.IListResponseMessage, 'contextInfo'>;
153
+ } | {
154
+ pin: WAMessageKey;
155
+ type: proto.PinInChat.Type;
156
+ /**
157
+ * 24 hours, 7 days, 30 days
158
+ */
159
+ time?: 86400 | 604800 | 2592000;
159
160
  } | {
160
161
  product: WASendableProduct;
161
162
  businessOwnerJid?: string;
@@ -175,8 +176,8 @@ export type GroupMetadataParticipants = Pick<GroupMetadata, 'participants'>;
175
176
  type MinimalRelayOptions = {
176
177
  /** override the message ID with a custom provided string */
177
178
  messageId?: string;
178
- /** cached group metadata, use to prevent redundant requests to WA & speed up msg sending */
179
- cachedGroupMetadata?: (jid: string) => Promise<GroupMetadataParticipants | undefined>;
179
+ /** should we use group metadata cache, or fetch afresh from the server; default assumed to be "true" */
180
+ useCachedGroupMetadata?: boolean;
180
181
  };
181
182
  export type MessageRelayOptions = MinimalRelayOptions & {
182
183
  /** only send to a specific participant; used when a message decryption fails for a single user */
@@ -188,6 +189,7 @@ export type MessageRelayOptions = MinimalRelayOptions & {
188
189
  additionalAttributes?: {
189
190
  [_: string]: string;
190
191
  };
192
+ additionalNodes?: BinaryNode[];
191
193
  /** should we use the devices cache, or fetch afresh from the server; default assumed to be "true" */
192
194
  useUserDevicesCache?: boolean;
193
195
  /** jid list of participants for status@broadcast */
@@ -237,6 +239,7 @@ export type MediaGenerationOptions = {
237
239
  };
238
240
  export type MessageContentGenerationOptions = MediaGenerationOptions & {
239
241
  getUrlInfo?: (text: string) => Promise<WAUrlInfo | undefined>;
242
+ getProfilePicUrl?: (jid: string, type: 'image' | 'preview') => Promise<string | undefined>;
240
243
  };
241
244
  export type MessageGenerationOptions = MessageContentGenerationOptions & MessageGenerationOptionsFromContent;
242
245
  /**
@@ -6,6 +6,7 @@ import type { Logger } from 'pino';
6
6
  import type { URL } from 'url';
7
7
  import { proto } from '../../WAProto';
8
8
  import { AuthenticationState, SignalAuthState, TransactionCapabilityOptions } from './Auth';
9
+ import { GroupMetadata } from './GroupMetadata';
9
10
  import { MediaConnInfo } from './Message';
10
11
  import { SignalRepository } from './Signal';
11
12
  export type WAVersion = [number, number, number];
@@ -71,6 +72,8 @@ export type SocketConfig = {
71
72
  userDevicesCache?: CacheStore;
72
73
  /** cache to store call offers */
73
74
  callOfferCache?: CacheStore;
75
+ /** cache to track placeholder resends */
76
+ placeholderResendCache?: CacheStore;
74
77
  /** width for link preview images */
75
78
  linkPreviewImageThumbnailWidth: number;
76
79
  /** Should Baileys ask the phone for full history, will be received async */
@@ -105,6 +108,8 @@ export type SocketConfig = {
105
108
  * (solves the "this message can take a while" issue) can be retried
106
109
  * */
107
110
  getMessage: (key: proto.IMessageKey) => Promise<proto.IMessage | undefined>;
111
+ /** cached group metadata, use to prevent redundant requests to WA & speed up msg sending */
112
+ cachedGroupMetadata: (jid: string) => Promise<GroupMetadata | undefined>;
108
113
  makeSignalRepository: (auth: SignalAuthState) => SignalRepository;
109
114
  /** Socket passthrough */
110
115
  socket?: any;
@@ -14,6 +14,13 @@ import { SocketConfig } from './Socket';
14
14
  export type UserFacingSocketConfig = Partial<SocketConfig> & {
15
15
  auth: AuthenticationState;
16
16
  };
17
+ export type BrowsersMap = {
18
+ ubuntu(browser: string): [string, string, string];
19
+ macOS(browser: string): [string, string, string];
20
+ baileys(browser: string): [string, string, string];
21
+ windows(browser: string): [string, string, string];
22
+ appropriate(browser: string): [string, string, string];
23
+ };
17
24
  export declare enum DisconnectReason {
18
25
  connectionClosed = 428,
19
26
  connectionLost = 408,
@@ -38,4 +38,4 @@ export declare function hkdf(buffer: Uint8Array | Buffer, expandedLength: number
38
38
  salt?: Buffer;
39
39
  info?: string;
40
40
  }): Buffer;
41
- export declare function derivePairingCodeKey(pairingCode: string, salt: Buffer): Buffer;
41
+ export declare function derivePairingCodeKey(pairingCode: string, salt: Buffer): Promise<Buffer>;
@@ -30,7 +30,9 @@ exports.derivePairingCodeKey = exports.hkdf = exports.md5 = exports.sha256 = exp
30
30
  const crypto_1 = require("crypto");
31
31
  const futoin_hkdf_1 = __importDefault(require("futoin-hkdf"));
32
32
  const libsignal = __importStar(require("libsignal"));
33
+ const util_1 = require("util");
33
34
  const Defaults_1 = require("../Defaults");
35
+ const pbkdf2Promise = (0, util_1.promisify)(crypto_1.pbkdf2);
34
36
  /** prefix version byte to the pub keys, required for some curve crypto functions */
35
37
  const generateSignalPubKey = (pubKey) => (pubKey.length === 33
36
38
  ? pubKey
@@ -145,7 +147,7 @@ function hkdf(buffer, expandedLength, info) {
145
147
  return (0, futoin_hkdf_1.default)(!Buffer.isBuffer(buffer) ? Buffer.from(buffer) : buffer, expandedLength, info);
146
148
  }
147
149
  exports.hkdf = hkdf;
148
- function derivePairingCodeKey(pairingCode, salt) {
149
- return (0, crypto_1.pbkdf2Sync)(pairingCode, salt, 2 << 16, 32, 'sha256');
150
+ async function derivePairingCodeKey(pairingCode, salt) {
151
+ return await pbkdf2Promise(pairingCode, salt, 2 << 16, 32, 'sha256');
150
152
  }
151
153
  exports.derivePairingCodeKey = derivePairingCodeKey;
@@ -2,6 +2,7 @@ import { Logger } from 'pino';
2
2
  import { proto } from '../../WAProto';
3
3
  import { SignalRepository } from '../Types';
4
4
  import { BinaryNode } from '../WABinary';
5
+ export declare const NO_MESSAGE_FOUND_ERROR_TEXT = "Message absent from node";
5
6
  /**
6
7
  * Decode the received node as a message.
7
8
  * @note this will only parse the message, not decrypt it