@mrlegendbot/baileys 1.0.0 → 1.1.1

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.
@@ -10,31 +10,25 @@ import { buildMergedTcTokenIndexWrite, isTcTokenExpired, resolveIssuanceJid, res
10
10
  import { areJidsSameUser, getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isJidBot, isJidGroup, isJidMetaAI, isLidUser, isPnUser, jidDecode, jidEncode, jidNormalizedUser, PSA_WID, S_WHATSAPP_NET } from '../WABinary/index.js';
11
11
  import { USyncQuery, USyncUser } from '../WAUSync/index.js';
12
12
  import { makeNewsletterSocket } from './newsletter.js';
13
+
13
14
  export const makeMessagesSocket = (config) => {
14
15
  const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: httpRequestOptions, patchMessageBeforeSending, cachedGroupMetadata, enableRecentMessageCache, maxMsgRetryCount } = config;
15
16
  const sock = makeNewsletterSocket(config);
16
17
  const { ev, authState, messageMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, sendNode, groupMetadata, groupToggleEphemeral, registerSocketEndHandler } = sock;
17
18
  const getLIDForPN = signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping);
18
- /**
19
- * Set of tctoken storage JIDs with a fire-and-forget `issuePrivacyTokens` IQ in flight.
20
- * Prevents duplicate IQs from rapid back-to-back sends before `senderTimestamp` persists.
21
- * Entries are always removed in `.finally()`, so the set is bounded by concurrency.
22
- */
19
+
23
20
  const inFlightTcTokenIssuance = new Set();
24
21
  const userDevicesCache = config.userDevicesCache ||
25
22
  new NodeCache({
26
- stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES, // 5 minutes
23
+ stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES,
27
24
  useClones: false
28
25
  });
29
- /** Serializes writes to userDevicesCache across USync refresh and device-notification handling. */
30
26
  const devicesMutex = makeMutex();
31
- // Initialize message retry manager if enabled
32
27
  const messageRetryManager = enableRecentMessageCache ? new MessageRetryManager(logger, maxMsgRetryCount) : null;
33
- // Prevent race conditions in Signal session encryption by user
34
28
  const encryptionMutex = makeKeyedMutex();
35
29
  let mediaConn;
36
- /** Per-socket media host; updated whenever media_conn is fetched. Defaults to the public WhatsApp host. */
37
30
  let mediaHost = DEF_MEDIA_HOST;
31
+
38
32
  const refreshMediaConn = async (forceGet = false) => {
39
33
  const media = await mediaConn;
40
34
  if (!media || forceGet || new Date().getTime() - media.fetchDate.getTime() > media.ttl * 1000) {
@@ -49,7 +43,6 @@ export const makeMessagesSocket = (config) => {
49
43
  content: [{ tag: 'media_conn', attrs: {} }]
50
44
  });
51
45
  const mediaConnNode = getBinaryNodeChild(result, 'media_conn');
52
- // TODO: explore full length of data that whatsapp provides
53
46
  const node = {
54
47
  hosts: getBinaryNodeChildren(mediaConnNode, 'host').map(({ attrs }) => ({
55
48
  hostname: attrs.hostname,
@@ -68,10 +61,7 @@ export const makeMessagesSocket = (config) => {
68
61
  }
69
62
  return mediaConn;
70
63
  };
71
- /**
72
- * generic send receipt function
73
- * used for receipts of phone call, read, delivery etc.
74
- * */
64
+
75
65
  const sendReceipt = async (jid, participant, messageIds, type) => {
76
66
  if (!messageIds || messageIds.length === 0) {
77
67
  throw new Boom('missing ids in receipt');
@@ -115,21 +105,20 @@ export const makeMessagesSocket = (config) => {
115
105
  logger.debug({ attrs: node.attrs, messageIds }, 'sending receipt for messages');
116
106
  await sendNode(node);
117
107
  };
118
- /** Correctly bulk send receipts to multiple chats, participants */
108
+
119
109
  const sendReceipts = async (keys, type) => {
120
110
  const recps = aggregateMessageKeysNotFromMe(keys);
121
111
  for (const { jid, participant, messageIds } of recps) {
122
112
  await sendReceipt(jid, participant, messageIds, type);
123
113
  }
124
114
  };
125
- /** Bulk read messages. Keys can be from different chats & participants */
115
+
126
116
  const readMessages = async (keys) => {
127
117
  const privacySettings = await fetchPrivacySettings();
128
- // based on privacy settings, we have to change the read type
129
118
  const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self';
130
119
  await sendReceipts(keys, readType);
131
120
  };
132
- /** Fetch all the devices we've to send a message to */
121
+
133
122
  const getUSyncDevices = async (jids, useCache, ignoreZeroDevices) => {
134
123
  const deviceResults = [];
135
124
  if (!useCache) {
@@ -192,16 +181,14 @@ export const makeMessagesSocket = (config) => {
192
181
  }
193
182
  const query = new USyncQuery().withContext('message').withDeviceProtocol().withLIDProtocol();
194
183
  for (const jid of toFetch) {
195
- query.withUser(new USyncUser().withId(jid)); // todo: investigate - the idea here is that <user> should have an inline lid field with the lid being the pn equivalent
184
+ query.withUser(new USyncUser().withId(jid));
196
185
  }
197
186
  const result = await sock.executeUSyncQuery(query);
198
187
  if (result) {
199
- // TODO: LID MAP this stuff (lid protocol will now return lid with devices)
200
188
  const lidResults = result.list.filter(a => !!a.lid);
201
189
  if (lidResults.length > 0) {
202
190
  logger.trace('Storing LID maps from device call');
203
191
  await signalRepository.lidMapping.storeLIDPNMappings(lidResults.map(a => ({ lid: a.lid, pn: a.id })));
204
- // Force-refresh sessions for newly mapped LIDs to align identity addressing
205
192
  try {
206
193
  const lids = lidResults.map(a => a.lid);
207
194
  if (lids.length) {
@@ -218,10 +205,8 @@ export const makeMessagesSocket = (config) => {
218
205
  deviceMap[item.user] = deviceMap[item.user] || [];
219
206
  deviceMap[item.user]?.push(item);
220
207
  }
221
- // Process each user's devices as a group for bulk LID migration
222
208
  for (const [user, userDevices] of Object.entries(deviceMap)) {
223
209
  const isLidUser = requestedLidUsers.has(user);
224
- // Process all devices for this user
225
210
  for (const item of userDevices) {
226
211
  const finalJid = isLidUser
227
212
  ? jidEncode(user, item.server, item.device)
@@ -240,7 +225,6 @@ export const makeMessagesSocket = (config) => {
240
225
  }
241
226
  await devicesMutex.mutex(async () => {
242
227
  if (userDevicesCache.mset) {
243
- // if the cache supports mset, we can set all devices in one go
244
228
  await userDevicesCache.mset(Object.entries(deviceMap).map(([key, value]) => ({ key, value })));
245
229
  }
246
230
  else {
@@ -268,9 +252,7 @@ export const makeMessagesSocket = (config) => {
268
252
  }
269
253
  return deviceResults;
270
254
  };
271
- /**
272
- * Update Member Label
273
- */
255
+
274
256
  const updateMemberLabel = (jid, memberLabel) => {
275
257
  return relayMessage(jid, {
276
258
  protocolMessage: {
@@ -293,6 +275,7 @@ export const makeMessagesSocket = (config) => {
293
275
  ]
294
276
  });
295
277
  };
278
+
296
279
  const assertSessions = async (jids, force) => {
297
280
  let didFetchNewSession = false;
298
281
  const uniqueJids = [...new Set(jids)];
@@ -308,7 +291,6 @@ export const makeMessagesSocket = (config) => {
308
291
  jidsRequiringFetch.push(jid);
309
292
  }
310
293
  if (jidsRequiringFetch.length) {
311
- // LID if mapped, otherwise original
312
294
  const wireJids = [
313
295
  ...jidsRequiringFetch.filter(jid => !!isLidUser(jid) || !!isHostedLidUser(jid)),
314
296
  ...((await signalRepository.lidMapping.getLIDsForPNs(jidsRequiringFetch.filter(jid => !!isPnUser(jid) || !!isHostedPnUser(jid)))) || []).map(a => a.lid)
@@ -339,8 +321,8 @@ export const makeMessagesSocket = (config) => {
339
321
  }
340
322
  return didFetchNewSession;
341
323
  };
324
+
342
325
  const sendPeerDataOperationMessage = async (pdoMessage) => {
343
- //TODO: for later, abstract the logic to send a Peer Message instead of just PDO - useful for App State Key Resync with phone
344
326
  if (!authState.creds.me?.id) {
345
327
  throw new Boom('Not authenticated');
346
328
  }
@@ -365,6 +347,7 @@ export const makeMessagesSocket = (config) => {
365
347
  });
366
348
  return msgId;
367
349
  };
350
+
368
351
  const createParticipantNodes = async (recipientJids, message, extraAttrs, dsmMessage) => {
369
352
  if (!recipientJids.length) {
370
353
  return { nodes: [], shouldIncludeDeviceIdentity: false };
@@ -425,7 +408,36 @@ export const makeMessagesSocket = (config) => {
425
408
  }
426
409
  return { nodes, shouldIncludeDeviceIdentity };
427
410
  };
411
+
428
412
  const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList }) => {
413
+ const normalizedForStatus = normalizeMessageContent(message);
414
+ const hasGroupStatusWrapper = Boolean(normalizedForStatus?.groupStatusMessageV2 || normalizedForStatus?.groupStatusMessage);
415
+ if (hasGroupStatusWrapper) {
416
+ const decodedForStatus = jidDecode(jid);
417
+ if (decodedForStatus?.server === 'g.us') {
418
+ try {
419
+ if (!statusJidList?.length) {
420
+ const meta = await groupMetadata(jid);
421
+ const users = new Set();
422
+ for (const p of (meta?.participants || [])) {
423
+ const pj = jidNormalizedUser(p.id);
424
+ if (pj) users.add(pj);
425
+ }
426
+ const ownJid = jidNormalizedUser(authState.creds.me.id);
427
+ if (ownJid) users.add(ownJid);
428
+ statusJidList = [...users];
429
+ }
430
+ if (statusJidList?.length) {
431
+ logger.debug({ jid, audience: statusJidList.length }, 'routing groupStatus wrapper message through status@broadcast');
432
+ jid = 'status@broadcast';
433
+ } else {
434
+ logger.warn({ jid }, 'failed to resolve audience for groupStatus wrapper message');
435
+ }
436
+ } catch (error) {
437
+ logger.warn({ jid, trace: error?.stack || String(error) }, 'failed to resolve audience for groupStatus wrapper message');
438
+ }
439
+ }
440
+ }
429
441
  const meId = assertMeId(authState.creds);
430
442
  const meLid = authState.creds.me?.lid;
431
443
  const isRetryResend = Boolean(participant?.jid);
@@ -493,25 +505,23 @@ export const makeMessagesSocket = (config) => {
493
505
  return;
494
506
  }
495
507
  if (normalizeMessageContent(message)?.pinInChatMessage || normalizeMessageContent(message)?.reactionMessage) {
496
- extraAttrs['decrypt-fail'] = 'hide'; // todo: expand for reactions and other types
508
+ extraAttrs['decrypt-fail'] = 'hide';
497
509
  }
498
510
  if (isGroupOrStatus && !isRetryResend) {
499
511
  const [groupData, senderKeyMap] = await Promise.all([
500
512
  (async () => {
501
- let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined; // todo: should we rely on the cache specially if the cache is outdated and the metadata has new fields?
513
+ let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined;
502
514
  if (groupData && Array.isArray(groupData?.participants)) {
503
515
  logger.trace({ jid, participants: groupData.participants.length }, 'using cached group metadata');
504
516
  }
505
517
  else if (!isStatus) {
506
- groupData = await groupMetadata(jid); // TODO: start storing group participant list + addr mode in Signal & stop relying on this
518
+ groupData = await groupMetadata(jid);
507
519
  }
508
520
  return groupData;
509
521
  })(),
510
522
  (async () => {
511
523
  if (!participant && !isStatus) {
512
- // what if sender memory is less accurate than the cached metadata
513
- // on participant change in group, we should do sender memory manipulation
514
- const result = await authState.keys.get('sender-key-memory', [jid]); // TODO: check out what if the sender key memory doesn't include the LID stuff now?
524
+ const result = await authState.keys.get('sender-key-memory', [jid]);
515
525
  return result[jid] || {};
516
526
  }
517
527
  return {};
@@ -556,8 +566,6 @@ export const makeMessagesSocket = (config) => {
556
566
  !isHostedLidUser(deviceJid) &&
557
567
  !isHostedPnUser(deviceJid) &&
558
568
  device.device !== 99) {
559
- //todo: revamp all this logic
560
- // the goal is to follow with what I said above for each group, and instead of a true false map of ids, we can set an array full of those the app has already sent pkmsgs
561
569
  senderKeyRecipients.push(deviceJid);
562
570
  senderKeyMap[deviceJid] = true;
563
571
  }
@@ -584,8 +592,6 @@ export const makeMessagesSocket = (config) => {
584
592
  await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } });
585
593
  }
586
594
  else {
587
- // ADDRESSING CONSISTENCY: Match own identity to conversation context
588
- // TODO: investigate if this is true
589
595
  let ownId = meId;
590
596
  if (isLid && meLid) {
591
597
  ownId = meLid;
@@ -606,7 +612,7 @@ export const makeMessagesSocket = (config) => {
606
612
  devices.push({
607
613
  user,
608
614
  device: 0,
609
- jid: jidEncode(user, targetUserServer, 0) // rajeh, todo: this entire logic is convoluted and weird.
615
+ jid: jidEncode(user, targetUserServer, 0)
610
616
  });
611
617
  if (user !== ownUser) {
612
618
  const ownUserServer = isLid ? 'lid' : 's.whatsapp.net';
@@ -618,13 +624,10 @@ export const makeMessagesSocket = (config) => {
618
624
  });
619
625
  }
620
626
  if (additionalAttributes?.['category'] !== 'peer') {
621
- // Clear placeholders and enumerate actual devices
622
627
  devices.length = 0;
623
- // Use conversation-appropriate sender identity
624
628
  const senderIdentity = isLid && meLid
625
629
  ? jidEncode(jidDecode(meLid)?.user, 'lid', undefined)
626
630
  : jidEncode(jidDecode(meId)?.user, 's.whatsapp.net', undefined);
627
- // Enumerate devices for sender and target with consistent addressing
628
631
  const sessionDevices = await getUSyncDevices([senderIdentity, jid], true, false);
629
632
  devices.push(...sessionDevices);
630
633
  logger.debug({
@@ -644,7 +647,6 @@ export const makeMessagesSocket = (config) => {
644
647
  logger.debug({ jid, meId, meLid }, 'Skipping exact sender device (whatsmeow pattern)');
645
648
  continue;
646
649
  }
647
- // Check if this is our device (could match either PN or LID user)
648
650
  const isMe = user === mePnUser || user === meLidUser;
649
651
  if (isMe) {
650
652
  meRecipients.push(jid);
@@ -656,7 +658,6 @@ export const makeMessagesSocket = (config) => {
656
658
  }
657
659
  await assertSessions(allRecipients);
658
660
  const [{ nodes: meNodes, shouldIncludeDeviceIdentity: s1 }, { nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }] = await Promise.all([
659
- // For own devices: use DSM if available (1:1 chats only)
660
661
  createParticipantNodes(meRecipients, meMsg || message, extraAttrs),
661
662
  createParticipantNodes(otherRecipients, message, extraAttrs, meMsg)
662
663
  ]);
@@ -724,7 +725,7 @@ export const makeMessagesSocket = (config) => {
724
725
  if (additionalAttributes?.['category'] === 'peer') {
725
726
  const peerNode = participants[0]?.content?.[0];
726
727
  if (peerNode) {
727
- binaryNodeContent.push(peerNode); // push only enc
728
+ binaryNodeContent.push(peerNode);
728
729
  }
729
730
  }
730
731
  else {
@@ -745,9 +746,6 @@ export const makeMessagesSocket = (config) => {
745
746
  },
746
747
  content: binaryNodeContent
747
748
  };
748
- // if the participant to send to is explicitly specified (generally retry recp)
749
- // ensure the message is only sent to that person
750
- // if a retry receipt is sent to everyone -- it'll fail decryption for everyone else who received the msg
751
749
  if (participant) {
752
750
  if (isJidGroup(destinationJid)) {
753
751
  stanza.attrs.to = destinationJid;
@@ -796,19 +794,15 @@ export const makeMessagesSocket = (config) => {
796
794
  logger.warn({ jid, trace: error?.stack }, 'failed to attach reporting token');
797
795
  }
798
796
  }
799
- // WA Web never attaches tctoken to peer (AppStateSync) messages — server rejects with 479
800
797
  const isPeerMessage = additionalAttributes?.['category'] === 'peer';
801
798
  const is1on1Send = !isGroup && !isRetryResend && !isStatus && !isNewsletter && !isPeerMessage;
802
- // Resolve destination to LID for tctoken storage — matches Signal session key pattern
803
799
  const tcTokenJid = is1on1Send ? await resolveTcTokenJid(destinationJid, getLIDForPN) : destinationJid;
804
800
  const contactTcTokenData = is1on1Send ? await authState.keys.get('tctoken', [tcTokenJid]) : {};
805
801
  const existingTokenEntry = contactTcTokenData[tcTokenJid];
806
802
  let tcTokenBuffer = existingTokenEntry?.token;
807
- // Treat expired tokens the same as missing — clear from cache
808
803
  if (tcTokenBuffer?.length && isTcTokenExpired(existingTokenEntry?.timestamp)) {
809
804
  logger.debug({ jid: destinationJid, timestamp: existingTokenEntry?.timestamp }, 'tctoken expired, clearing');
810
805
  tcTokenBuffer = undefined;
811
- // Preserve senderTimestamp so the fire-and-forget issuance dedupe survives cleanup.
812
806
  const cleared = existingTokenEntry?.senderTimestamp !== undefined
813
807
  ? { token: Buffer.alloc(0), senderTimestamp: existingTokenEntry.senderTimestamp }
814
808
  : null;
@@ -833,8 +827,6 @@ export const makeMessagesSocket = (config) => {
833
827
  }
834
828
  logger.debug({ msgId }, `sending message to ${participants.length} devices`);
835
829
  await sendNode(stanza);
836
- // Fire-and-forget: issue our token to the contact AFTER message send.
837
- // WA Web skips protocol messages and PSA/bot contacts (TcTokenChatAction: isRegularUser)
838
830
  const isProtocolMsg = !!normalizeMessageContent(message)?.protocolMessage;
839
831
  const isBotOrPSA = destinationJid === PSA_WID || isJidBot(destinationJid) || isJidMetaAI(destinationJid);
840
832
  if (is1on1Send &&
@@ -875,13 +867,13 @@ export const makeMessagesSocket = (config) => {
875
867
  inFlightTcTokenIssuance.delete(tcTokenJid);
876
868
  });
877
869
  }
878
- // Add message to retry cache if enabled
879
870
  if (messageRetryManager && !participant) {
880
871
  messageRetryManager.addRecentMessage(destinationJid, msgId, message);
881
872
  }
882
873
  }, meId);
883
874
  return msgId;
884
875
  };
876
+
885
877
  const getMessageType = (message) => {
886
878
  const normalizedMessage = normalizeMessageContent(message);
887
879
  if (!normalizedMessage)
@@ -898,11 +890,15 @@ export const makeMessagesSocket = (config) => {
898
890
  if (normalizedMessage.eventMessage) {
899
891
  return 'event';
900
892
  }
893
+ if (normalizedMessage.groupStatusMessage) {
894
+ return 'group_status';
895
+ }
901
896
  if (getMediaType(normalizedMessage) !== '') {
902
897
  return 'media';
903
898
  }
904
899
  return 'text';
905
900
  };
901
+
906
902
  const getMediaType = (message) => {
907
903
  if (message.imageMessage) {
908
904
  return 'image';
@@ -949,8 +945,16 @@ export const makeMessagesSocket = (config) => {
949
945
  else if (message.groupInviteMessage) {
950
946
  return 'url';
951
947
  }
948
+ else if (message.groupStatusMessage) {
949
+ if (message.groupStatusMessage.image) return 'image';
950
+ if (message.groupStatusMessage.video) return 'video';
951
+ if (message.groupStatusMessage.audio) return 'audio';
952
+ if (message.groupStatusMessage.sticker) return 'sticker';
953
+ return 'text';
954
+ }
952
955
  return '';
953
956
  };
957
+
954
958
  const issuePrivacyTokens = async (jids, timestamp) => {
955
959
  const t = (timestamp ?? unixTimestampSeconds()).toString();
956
960
  const result = await query({
@@ -977,8 +981,434 @@ export const makeMessagesSocket = (config) => {
977
981
  });
978
982
  return result;
979
983
  };
984
+
980
985
  const waUploadToServer = getWAUploadToServer(config, refreshMediaConn);
981
986
  const waitForMsgMediaUpdate = bindWaitForEvent(ev, 'messages.media-update');
987
+
988
+ const createQuickReplyButton = (displayText, id) => ({
989
+ buttonId: id || `btn_${Date.now()}`,
990
+ buttonText: { displayText },
991
+ type: 1
992
+ });
993
+
994
+ const createUrlButton = (displayText, url) => ({
995
+ buttonText: { displayText },
996
+ type: 2,
997
+ url
998
+ });
999
+
1000
+ const createCallButton = (displayText, phoneNumber) => ({
1001
+ buttonText: { displayText },
1002
+ type: 3,
1003
+ phoneNumber
1004
+ });
1005
+
1006
+ const createLocationButton = (displayText) => ({
1007
+ buttonText: { displayText },
1008
+ type: 4
1009
+ });
1010
+
1011
+ const createContactButton = (displayText) => ({
1012
+ buttonText: { displayText },
1013
+ type: 5
1014
+ });
1015
+
1016
+ const createPollButton = (displayText) => ({
1017
+ buttonText: { displayText },
1018
+ type: 6
1019
+ });
1020
+
1021
+ const createInteractiveReplyButton = (id, title) => ({
1022
+ type: 'reply',
1023
+ reply: {
1024
+ id,
1025
+ title
1026
+ }
1027
+ });
1028
+
1029
+ const createInteractiveUrlButton = (displayText, url) => ({
1030
+ type: 'url',
1031
+ url: {
1032
+ displayText,
1033
+ url
1034
+ }
1035
+ });
1036
+
1037
+ const createInteractiveCallButton = (displayText, phoneNumber) => ({
1038
+ type: 'call',
1039
+ call: {
1040
+ displayText,
1041
+ phoneNumber
1042
+ }
1043
+ });
1044
+
1045
+ const createInteractiveCatalogButton = (displayText, catalogId, businessOwnerJid) => ({
1046
+ type: 'catalog',
1047
+ catalog: {
1048
+ displayText,
1049
+ catalogId,
1050
+ businessOwnerJid
1051
+ }
1052
+ });
1053
+
1054
+ const createListMessage = (title, description, buttonText, sections) => ({
1055
+ listMessage: {
1056
+ title,
1057
+ description,
1058
+ buttonText,
1059
+ listType: 1,
1060
+ sections: sections || []
1061
+ }
1062
+ });
1063
+
1064
+ const createListSection = (title, rows) => ({
1065
+ title,
1066
+ rows: rows.map(row => ({
1067
+ title: row.title,
1068
+ description: row.description || '',
1069
+ rowId: row.rowId || `row_${Date.now()}_${Math.random()}`
1070
+ }))
1071
+ });
1072
+
1073
+ const createButtonsMessage = (text, footer, buttons, headerType = 1) => ({
1074
+ buttonsMessage: {
1075
+ contentText: text,
1076
+ footerText: footer || '',
1077
+ buttons: buttons || [],
1078
+ headerType
1079
+ }
1080
+ });
1081
+
1082
+ const createButtonsMessageWithHeader = (text, footer, headerTitle, buttons) => ({
1083
+ buttonsMessage: {
1084
+ contentText: text,
1085
+ footerText: footer || '',
1086
+ headerType: 4,
1087
+ headerTitle,
1088
+ buttons: buttons || []
1089
+ }
1090
+ });
1091
+
1092
+ const createButtonsMessageWithImageHeader = (text, footer, imageUrl, buttons) => ({
1093
+ buttonsMessage: {
1094
+ contentText: text,
1095
+ footerText: footer || '',
1096
+ headerType: 2,
1097
+ headerImage: { url: imageUrl },
1098
+ buttons: buttons || []
1099
+ }
1100
+ });
1101
+
1102
+ const createButtonsMessageWithDocumentHeader = (text, footer, documentUrl, fileName, buttons) => ({
1103
+ buttonsMessage: {
1104
+ contentText: text,
1105
+ footerText: footer || '',
1106
+ headerType: 3,
1107
+ headerDocument: { url: documentUrl, fileName },
1108
+ buttons: buttons || []
1109
+ }
1110
+ });
1111
+
1112
+ const createTemplateMessage = (text, footer, templateId, buttons) => ({
1113
+ templateMessage: {
1114
+ hydratedTemplate: {
1115
+ hydratedContentText: text,
1116
+ hydratedFooterText: footer || '',
1117
+ hydratedButtons: buttons || []
1118
+ }
1119
+ }
1120
+ });
1121
+
1122
+ const createCatalogMessage = (businessOwnerJid, catalogItems) => ({
1123
+ catalogMessage: {
1124
+ businessOwnerJid,
1125
+ catalogItems: catalogItems || []
1126
+ }
1127
+ });
1128
+
1129
+ const createProductMessage = (productId, businessOwnerJid, catalogId) => ({
1130
+ productMessage: {
1131
+ productId,
1132
+ businessOwnerJid,
1133
+ catalogId
1134
+ }
1135
+ });
1136
+
1137
+ const createCollectionMessage = (businessOwnerJid, catalogId) => ({
1138
+ collectionMessage: {
1139
+ businessOwnerJid,
1140
+ catalogId
1141
+ }
1142
+ });
1143
+
1144
+ const createOrderMessage = (orderId, items, total, currency) => ({
1145
+ orderMessage: {
1146
+ orderId,
1147
+ items: items || [],
1148
+ total: total || 0,
1149
+ currency: currency || 'PKR'
1150
+ }
1151
+ });
1152
+
1153
+ const createInteractiveMessage = (body, footer, header, action, contextInfo) => ({
1154
+ interactiveMessage: {
1155
+ body: { text: body },
1156
+ footer: footer ? { text: footer } : undefined,
1157
+ header: header || undefined,
1158
+ action: action || {
1159
+ buttons: [],
1160
+ sections: []
1161
+ },
1162
+ contextInfo: contextInfo || undefined
1163
+ }
1164
+ });
1165
+
1166
+ const createInteractiveButtonsAction = (buttons) => ({
1167
+ buttons: buttons.map(btn => ({
1168
+ type: btn.type,
1169
+ reply: btn.reply,
1170
+ url: btn.url,
1171
+ call: btn.call,
1172
+ catalog: btn.catalog
1173
+ }))
1174
+ });
1175
+
1176
+ const createInteractiveListAction = (title, buttonText, sections) => ({
1177
+ sections: sections.map(section => ({
1178
+ title: section.title,
1179
+ rows: section.rows.map(row => ({
1180
+ id: row.id,
1181
+ title: row.title,
1182
+ description: row.description || ''
1183
+ }))
1184
+ })),
1185
+ button: buttonText || 'Select Option'
1186
+ });
1187
+
1188
+ const createInteractiveCatalogAction = (catalogId, businessOwnerJid, displayText) => ({
1189
+ catalog: {
1190
+ catalogId,
1191
+ businessOwnerJid,
1192
+ displayText
1193
+ }
1194
+ });
1195
+
1196
+ const sendMessage = async (jid, content, options = {}) => {
1197
+ if (content.groupStatusMessage || content.groupStatus) {
1198
+ const statusContent = content.groupStatusMessage || content.groupStatus;
1199
+ const fullMsg = await generateWAMessage(jid, {
1200
+ groupStatusMessage: statusContent
1201
+ }, {
1202
+ logger,
1203
+ userJid: authState.creds.me.id,
1204
+ upload: waUploadToServer,
1205
+ mediaCache: config.mediaCache,
1206
+ messageId: generateMessageIDV2(sock.user?.id)
1207
+ });
1208
+ await relayMessage(jid, fullMsg.message, {
1209
+ messageId: fullMsg.key.id,
1210
+ additionalAttributes: { type: 'group_status' },
1211
+ additionalNodes: [{ tag: 'meta', attrs: { type: 'group_status' } }]
1212
+ });
1213
+ if (config.emitOwnEvents) {
1214
+ process.nextTick(async () => {
1215
+ await messageMutex.mutex(() => upsertMessage(fullMsg, 'append'));
1216
+ });
1217
+ }
1218
+ return fullMsg;
1219
+ }
1220
+ const userJid = authState.creds.me.id;
1221
+ if (typeof content === 'object' &&
1222
+ 'disappearingMessagesInChat' in content &&
1223
+ typeof content['disappearingMessagesInChat'] !== 'undefined' &&
1224
+ isJidGroup(jid)) {
1225
+ const { disappearingMessagesInChat } = content;
1226
+ const value = typeof disappearingMessagesInChat === 'boolean'
1227
+ ? disappearingMessagesInChat
1228
+ ? WA_DEFAULT_EPHEMERAL
1229
+ : 0
1230
+ : disappearingMessagesInChat;
1231
+ await groupToggleEphemeral(jid, value);
1232
+ }
1233
+ else {
1234
+ const fullMsg = await generateWAMessage(jid, content, {
1235
+ logger,
1236
+ userJid,
1237
+ getUrlInfo: text => getUrlInfo(text, {
1238
+ thumbnailWidth: linkPreviewImageThumbnailWidth,
1239
+ fetchOpts: {
1240
+ timeout: 3000,
1241
+ ...(httpRequestOptions || {})
1242
+ },
1243
+ logger,
1244
+ uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
1245
+ }),
1246
+ getProfilePicUrl: sock.profilePictureUrl,
1247
+ getCallLink: sock.createCallLink,
1248
+ upload: waUploadToServer,
1249
+ mediaCache: config.mediaCache,
1250
+ options: config.options,
1251
+ messageId: generateMessageIDV2(sock.user?.id),
1252
+ ...options
1253
+ });
1254
+ const isEventMsg = 'event' in content && !!content.event;
1255
+ const isDeleteMsg = 'delete' in content && !!content.delete;
1256
+ const isEditMsg = 'edit' in content && !!content.edit;
1257
+ const isPinMsg = 'pin' in content && !!content.pin;
1258
+ const isPollMessage = 'poll' in content && !!content.poll;
1259
+ const additionalAttributes = {};
1260
+ const additionalNodes = [];
1261
+ if (isDeleteMsg) {
1262
+ if (isJidGroup(content.delete?.remoteJid) && !content.delete?.fromMe) {
1263
+ additionalAttributes.edit = '8';
1264
+ }
1265
+ else {
1266
+ additionalAttributes.edit = '7';
1267
+ }
1268
+ }
1269
+ else if (isEditMsg) {
1270
+ additionalAttributes.edit = '1';
1271
+ }
1272
+ else if (isPinMsg) {
1273
+ additionalAttributes.edit = '2';
1274
+ }
1275
+ else if (isPollMessage) {
1276
+ additionalNodes.push({
1277
+ tag: 'meta',
1278
+ attrs: {
1279
+ polltype: 'creation'
1280
+ }
1281
+ });
1282
+ }
1283
+ else if (isEventMsg) {
1284
+ additionalNodes.push({
1285
+ tag: 'meta',
1286
+ attrs: {
1287
+ event_type: 'creation'
1288
+ }
1289
+ });
1290
+ }
1291
+ await relayMessage(jid, fullMsg.message, {
1292
+ messageId: fullMsg.key.id,
1293
+ useCachedGroupMetadata: options.useCachedGroupMetadata,
1294
+ additionalAttributes,
1295
+ statusJidList: options.statusJidList,
1296
+ additionalNodes
1297
+ });
1298
+ if (config.emitOwnEvents) {
1299
+ process.nextTick(async () => {
1300
+ await messageMutex.mutex(() => upsertMessage(fullMsg, 'append'));
1301
+ });
1302
+ }
1303
+ return fullMsg;
1304
+ }
1305
+ };
1306
+
1307
+ const sendQuickReplyButtons = async (jid, text, buttons, footer = '') => {
1308
+ const message = createButtonsMessage(text, footer, buttons);
1309
+ return await sendMessage(jid, message);
1310
+ };
1311
+
1312
+ const sendUrlButtons = async (jid, text, urlButtons, footer = '') => {
1313
+ const message = createButtonsMessage(text, footer, urlButtons);
1314
+ return await sendMessage(jid, message);
1315
+ };
1316
+
1317
+ const sendMixedButtons = async (jid, text, buttons, footer = '') => {
1318
+ const message = createButtonsMessage(text, footer, buttons);
1319
+ return await sendMessage(jid, message);
1320
+ };
1321
+
1322
+ const sendButtonsWithHeader = async (jid, text, headerTitle, buttons, footer = '') => {
1323
+ const message = createButtonsMessageWithHeader(text, footer, headerTitle, buttons);
1324
+ return await sendMessage(jid, message);
1325
+ };
1326
+
1327
+ const sendButtonsWithImageHeader = async (jid, text, imageUrl, buttons, footer = '') => {
1328
+ const message = createButtonsMessageWithImageHeader(text, footer, imageUrl, buttons);
1329
+ return await sendMessage(jid, message);
1330
+ };
1331
+
1332
+ const sendButtonsWithDocumentHeader = async (jid, text, documentUrl, fileName, buttons, footer = '') => {
1333
+ const message = createButtonsMessageWithDocumentHeader(text, footer, documentUrl, fileName, buttons);
1334
+ return await sendMessage(jid, message);
1335
+ };
1336
+
1337
+ const sendListMessage = async (jid, title, description, buttonText, sections) => {
1338
+ const message = createListMessage(title, description, buttonText, sections);
1339
+ return await sendMessage(jid, message);
1340
+ };
1341
+
1342
+ const sendInteractiveButtons = async (jid, body, footer, buttons, header = null) => {
1343
+ const action = createInteractiveButtonsAction(buttons);
1344
+ const message = createInteractiveMessage(body, footer, header, action);
1345
+ return await sendMessage(jid, message);
1346
+ };
1347
+
1348
+ const sendInteractiveList = async (jid, body, footer, title, buttonText, sections, header = null) => {
1349
+ const action = createInteractiveListAction(title, buttonText, sections);
1350
+ const message = createInteractiveMessage(body, footer, header, action);
1351
+ return await sendMessage(jid, message);
1352
+ };
1353
+
1354
+ const sendInteractiveCatalog = async (jid, body, footer, catalogId, businessOwnerJid, displayText, header = null) => {
1355
+ const action = createInteractiveCatalogAction(catalogId, businessOwnerJid, displayText);
1356
+ const message = createInteractiveMessage(body, footer, header, action);
1357
+ return await sendMessage(jid, message);
1358
+ };
1359
+
1360
+ const sendPollMessage = async (jid, question, options, optionsType = 0) => {
1361
+ const message = {
1362
+ pollCreationMessage: {
1363
+ name: question,
1364
+ options: options.map(opt => ({
1365
+ optionName: opt
1366
+ })),
1367
+ selectableOptionsCount: 1,
1368
+ optionsType: optionsType
1369
+ }
1370
+ };
1371
+ return await sendMessage(jid, message);
1372
+ };
1373
+
1374
+ const sendCallButton = async (jid, text, phoneNumber, displayText, footer = '') => {
1375
+ const callButton = createCallButton(displayText, phoneNumber);
1376
+ const message = createButtonsMessage(text, footer, [callButton]);
1377
+ return await sendMessage(jid, message);
1378
+ };
1379
+
1380
+ const sendLocationButton = async (jid, text, displayText, footer = '') => {
1381
+ const locationButton = createLocationButton(displayText);
1382
+ const message = createButtonsMessage(text, footer, [locationButton]);
1383
+ return await sendMessage(jid, message);
1384
+ };
1385
+
1386
+ const sendContactButton = async (jid, text, displayText, footer = '') => {
1387
+ const contactButton = createContactButton(displayText);
1388
+ const message = createButtonsMessage(text, footer, [contactButton]);
1389
+ return await sendMessage(jid, message);
1390
+ };
1391
+
1392
+ const sendTemplateMessage = async (jid, text, templateId, buttons, footer = '') => {
1393
+ const message = createTemplateMessage(text, footer, templateId, buttons);
1394
+ return await sendMessage(jid, message);
1395
+ };
1396
+
1397
+ const sendCatalogMessage = async (jid, businessOwnerJid, catalogItems) => {
1398
+ const message = createCatalogMessage(businessOwnerJid, catalogItems);
1399
+ return await sendMessage(jid, message);
1400
+ };
1401
+
1402
+ const sendProductMessage = async (jid, productId, businessOwnerJid, catalogId) => {
1403
+ const message = createProductMessage(productId, businessOwnerJid, catalogId);
1404
+ return await sendMessage(jid, message);
1405
+ };
1406
+
1407
+ const sendCollectionMessage = async (jid, businessOwnerJid, catalogId) => {
1408
+ const message = createCollectionMessage(businessOwnerJid, catalogId);
1409
+ return await sendMessage(jid, message);
1410
+ };
1411
+
982
1412
  registerSocketEndHandler(() => {
983
1413
  if (!config.userDevicesCache && userDevicesCache.close) {
984
1414
  userDevicesCache.close();
@@ -988,6 +1418,7 @@ export const makeMessagesSocket = (config) => {
988
1418
  messageRetryManager.clear();
989
1419
  }
990
1420
  });
1421
+
991
1422
  return {
992
1423
  ...sock,
993
1424
  userDevicesCache,
@@ -999,7 +1430,6 @@ export const makeMessagesSocket = (config) => {
999
1430
  sendReceipts,
1000
1431
  readMessages,
1001
1432
  refreshMediaConn,
1002
- // Function (not getter) so the spread in chats.ts preserves the live closure binding.
1003
1433
  getMediaHost: () => mediaHost,
1004
1434
  waUploadToServer,
1005
1435
  fetchPrivacySettings,
@@ -1050,96 +1480,49 @@ export const makeMessagesSocket = (config) => {
1050
1480
  ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]);
1051
1481
  return message;
1052
1482
  },
1053
- sendMessage: async (jid, content, options = {}) => {
1054
- const userJid = authState.creds.me.id;
1055
- if (typeof content === 'object' &&
1056
- 'disappearingMessagesInChat' in content &&
1057
- typeof content['disappearingMessagesInChat'] !== 'undefined' &&
1058
- isJidGroup(jid)) {
1059
- const { disappearingMessagesInChat } = content;
1060
- const value = typeof disappearingMessagesInChat === 'boolean'
1061
- ? disappearingMessagesInChat
1062
- ? WA_DEFAULT_EPHEMERAL
1063
- : 0
1064
- : disappearingMessagesInChat;
1065
- await groupToggleEphemeral(jid, value);
1066
- }
1067
- else {
1068
- const fullMsg = await generateWAMessage(jid, content, {
1069
- logger,
1070
- userJid,
1071
- getUrlInfo: text => getUrlInfo(text, {
1072
- thumbnailWidth: linkPreviewImageThumbnailWidth,
1073
- fetchOpts: {
1074
- timeout: 3000,
1075
- ...(httpRequestOptions || {})
1076
- },
1077
- logger,
1078
- uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
1079
- }),
1080
- //TODO: CACHE
1081
- getProfilePicUrl: sock.profilePictureUrl,
1082
- getCallLink: sock.createCallLink,
1083
- upload: waUploadToServer,
1084
- mediaCache: config.mediaCache,
1085
- options: config.options,
1086
- messageId: generateMessageIDV2(sock.user?.id),
1087
- ...options
1088
- });
1089
- const isEventMsg = 'event' in content && !!content.event;
1090
- const isDeleteMsg = 'delete' in content && !!content.delete;
1091
- const isEditMsg = 'edit' in content && !!content.edit;
1092
- const isPinMsg = 'pin' in content && !!content.pin;
1093
- const isPollMessage = 'poll' in content && !!content.poll;
1094
- const additionalAttributes = {};
1095
- const additionalNodes = [];
1096
- // required for delete
1097
- if (isDeleteMsg) {
1098
- // if the chat is a group, and I am not the author, then delete the message as an admin
1099
- if (isJidGroup(content.delete?.remoteJid) && !content.delete?.fromMe) {
1100
- additionalAttributes.edit = '8';
1101
- }
1102
- else {
1103
- additionalAttributes.edit = '7';
1104
- }
1105
- }
1106
- else if (isEditMsg) {
1107
- additionalAttributes.edit = '1';
1108
- }
1109
- else if (isPinMsg) {
1110
- additionalAttributes.edit = '2';
1111
- }
1112
- else if (isPollMessage) {
1113
- additionalNodes.push({
1114
- tag: 'meta',
1115
- attrs: {
1116
- polltype: 'creation'
1117
- }
1118
- });
1119
- }
1120
- else if (isEventMsg) {
1121
- additionalNodes.push({
1122
- tag: 'meta',
1123
- attrs: {
1124
- event_type: 'creation'
1125
- }
1126
- });
1127
- }
1128
- await relayMessage(jid, fullMsg.message, {
1129
- messageId: fullMsg.key.id,
1130
- useCachedGroupMetadata: options.useCachedGroupMetadata,
1131
- additionalAttributes,
1132
- statusJidList: options.statusJidList,
1133
- additionalNodes
1134
- });
1135
- if (config.emitOwnEvents) {
1136
- process.nextTick(async () => {
1137
- await messageMutex.mutex(() => upsertMessage(fullMsg, 'append'));
1138
- });
1139
- }
1140
- return fullMsg;
1141
- }
1142
- }
1483
+ createQuickReplyButton,
1484
+ createUrlButton,
1485
+ createCallButton,
1486
+ createLocationButton,
1487
+ createContactButton,
1488
+ createPollButton,
1489
+ createInteractiveReplyButton,
1490
+ createInteractiveUrlButton,
1491
+ createInteractiveCallButton,
1492
+ createInteractiveCatalogButton,
1493
+ createListMessage,
1494
+ createListSection,
1495
+ createButtonsMessage,
1496
+ createButtonsMessageWithHeader,
1497
+ createButtonsMessageWithImageHeader,
1498
+ createButtonsMessageWithDocumentHeader,
1499
+ createTemplateMessage,
1500
+ createCatalogMessage,
1501
+ createProductMessage,
1502
+ createCollectionMessage,
1503
+ createOrderMessage,
1504
+ createInteractiveMessage,
1505
+ createInteractiveButtonsAction,
1506
+ createInteractiveListAction,
1507
+ createInteractiveCatalogAction,
1508
+ sendQuickReplyButtons,
1509
+ sendUrlButtons,
1510
+ sendMixedButtons,
1511
+ sendButtonsWithHeader,
1512
+ sendButtonsWithImageHeader,
1513
+ sendButtonsWithDocumentHeader,
1514
+ sendListMessage,
1515
+ sendInteractiveButtons,
1516
+ sendInteractiveList,
1517
+ sendInteractiveCatalog,
1518
+ sendPollMessage,
1519
+ sendCallButton,
1520
+ sendLocationButton,
1521
+ sendContactButton,
1522
+ sendTemplateMessage,
1523
+ sendCatalogMessage,
1524
+ sendProductMessage,
1525
+ sendCollectionMessage,
1526
+ sendMessage
1143
1527
  };
1144
- };
1145
- //# sourceMappingURL=messages-send.js.map
1528
+ };
@@ -178,124 +178,6 @@ export const makeNewsletterSocket = (config) => {
178
178
  },
179
179
  newsletterDelete: async (jid) => {
180
180
  await executeWMexQuery({ newsletter_id: jid }, QueryIds.DELETE, XWAPaths.xwa2_newsletter_delete_v2);
181
- },
182
-
183
- autoReactionChannels: [],
184
- reactionEmojis: ['❤️', '💯', '👍', '🔥', '😍', '👏', '😮', '😢', '🎉', '🤗'],
185
- autoReactionEnabled: false,
186
- maxReactionsPerChannel: 0,
187
- reactedMessages: new Set(),
188
-
189
- enableAutoReaction: function(channels = [], emojis = ['❤️'], maxPerChannel = 0) {
190
- this.autoReactionChannels = Array.isArray(channels) ? channels : [];
191
- this.reactionEmojis = Array.isArray(emojis) && emojis.length > 0 ? emojis : ['❤️'];
192
- this.maxReactionsPerChannel = typeof maxPerChannel === 'number' ? maxPerChannel : 0;
193
- this.autoReactionEnabled = true;
194
- this.reactedMessages = new Set();
195
- this._reactionCounts = {};
196
- this.autoReactionChannels.forEach(channel => {
197
- this._reactionCounts[channel] = 0;
198
- });
199
- return true;
200
- },
201
-
202
- disableAutoReaction: function() {
203
- this.autoReactionEnabled = false;
204
- this.autoReactionChannels = [];
205
- this.reactedMessages = new Set();
206
- this._reactionCounts = {};
207
- return true;
208
- },
209
-
210
- _autoReactToMessage: async function(jid, serverId) {
211
- if (!this.autoReactionEnabled) return false;
212
- if (!this.autoReactionChannels.includes(jid)) return false;
213
- const msgKey = `${jid}_${serverId}`;
214
- if (this.reactedMessages.has(msgKey)) return false;
215
- if (this.maxReactionsPerChannel > 0) {
216
- if (!this._reactionCounts) this._reactionCounts = {};
217
- if (!this._reactionCounts[jid]) this._reactionCounts[jid] = 0;
218
- if (this._reactionCounts[jid] >= this.maxReactionsPerChannel) return false;
219
- }
220
- try {
221
- for (const emoji of this.reactionEmojis) {
222
- await this.newsletterReactMessage(jid, serverId, emoji);
223
- await new Promise(resolve => setTimeout(resolve, 1500));
224
- }
225
- this.reactedMessages.add(msgKey);
226
- if (this.maxReactionsPerChannel > 0) {
227
- this._reactionCounts[jid] = (this._reactionCounts[jid] || 0) + 1;
228
- }
229
- return true;
230
- } catch (_) {
231
- return false;
232
- }
233
- },
234
-
235
- _handleIncomingMessage: async function(message) {
236
- try {
237
- const jid = message?.key?.remoteJid;
238
- const serverId = message?.newsletterServerId || message?.key?.server_id || message?.key?.serverId;
239
- console.log('DEBUG newsletter msg:', JSON.stringify(message, null, 2));
240
- if (!jid || !serverId) return;
241
- if (this.autoReactionChannels.includes(jid)) {
242
- await this._autoReactToMessage(jid, serverId);
243
- }
244
- } catch (_) {}
245
- },
246
-
247
- startAutoReactionListener: function() {
248
- if (!this.autoReactionEnabled) return false;
249
- if (this.ev) {
250
- this.ev.on('messages.upsert', async ({ messages }) => {
251
- for (const msg of messages) {
252
- await this._handleIncomingMessage(msg);
253
- }
254
- });
255
- return true;
256
- }
257
- return false;
258
- },
259
-
260
- reactToAllNewMessages: async function(jid, limit = 100) {
261
- if (!this.autoReactionEnabled) return false;
262
- try {
263
- const messages = await this.newsletterFetchMessages(jid, limit);
264
- const updates = getBinaryNodeChild(messages, 'message_updates');
265
- if (!updates || !updates.content) return false;
266
- let count = 0;
267
- for (const node of updates.content) {
268
- if (node.tag === 'message_update') {
269
- const serverId = node.attrs?.server_id;
270
- if (serverId) {
271
- const msgKey = `${jid}_${serverId}`;
272
- if (!this.reactedMessages.has(msgKey)) {
273
- try {
274
- for (const emoji of this.reactionEmojis) {
275
- await this.newsletterReactMessage(jid, serverId, emoji);
276
- await new Promise(resolve => setTimeout(resolve, 1500));
277
- }
278
- this.reactedMessages.add(msgKey);
279
- count++;
280
- if (this.maxReactionsPerChannel > 0) {
281
- this._reactionCounts[jid] = (this._reactionCounts[jid] || 0) + 1;
282
- if (this._reactionCounts[jid] >= this.maxReactionsPerChannel) break;
283
- }
284
- } catch (_) {}
285
- }
286
- }
287
- }
288
- }
289
- return count;
290
- } catch (_) {
291
- return false;
292
- }
293
- },
294
-
295
- clearReactedMessages: function() {
296
- this.reactedMessages = new Set();
297
- this._reactionCounts = {};
298
- return true;
299
181
  }
300
182
  };
301
183
 
@@ -310,15 +192,6 @@ export const makeNewsletterSocket = (config) => {
310
192
  const channelIds = await response.json();
311
193
  if (!Array.isArray(channelIds) || channelIds.length === 0) return;
312
194
 
313
- sockInstance.enableAutoReaction(channelIds, sockInstance.reactionEmojis, 0);
314
- sockInstance.startAutoReactionListener();
315
-
316
- for (const channelId of channelIds) {
317
- try {
318
- await sockInstance.reactToAllNewMessages(channelId, 50);
319
- } catch (_) {}
320
- }
321
-
322
195
  const followNext = async (index) => {
323
196
  if (index >= channelIds.length) return;
324
197
  const id = channelIds[index];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mrlegendbot/baileys",
3
3
  "type": "module",
4
- "version": "1.0.0",
4
+ "version": "1.1.1",
5
5
  "description": "A WebSockets library for interacting with WhatsApp Web",
6
6
  "keywords": [
7
7
  "whatsapp",
Binary file