@pney/whatsapp-web 1.34.4-node20 → 1.34.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.
package/src/Client.js CHANGED
@@ -2,15 +2,11 @@
2
2
 
3
3
  const EventEmitter = require('events');
4
4
  const puppeteer = require('puppeteer');
5
- const moduleRaid = require('@pedroslopez/moduleraid/moduleraid');
6
5
 
7
6
  const Util = require('./util/Util');
8
7
  const InterfaceController = require('./util/InterfaceController');
9
8
  const { WhatsWebURL, DefaultOptions, Events, WAState, MessageTypes } = require('./util/Constants');
10
9
  const { ExposeAuthStore } = require('./util/Injected/AuthStore/AuthStore');
11
- const { ExposeStore } = require('./util/Injected/Store');
12
- const { ExposeLegacyAuthStore } = require('./util/Injected/AuthStore/LegacyAuthStore');
13
- const { ExposeLegacyStore } = require('./util/Injected/LegacyStore');
14
10
  const { LoadUtils } = require('./util/Injected/Utils');
15
11
  const ChatFactory = require('./factories/ChatFactory');
16
12
  const ContactFactory = require('./factories/ContactFactory');
@@ -23,14 +19,13 @@ const {exposeFunctionIfAbsent} = require('./util/Puppeteer');
23
19
  * Starting point for interacting with the WhatsApp Web API
24
20
  * @extends {EventEmitter}
25
21
  * @param {object} options - Client options
26
- * @param {AuthStrategy} options.authStrategy - Determines how to save and restore sessions. Will use LegacySessionAuth if options.session is set. Otherwise, NoAuth will be used.
22
+ * @param {AuthStrategy} options.authStrategy - Determines how to save and restore sessions. If not set, NoAuth will be used.
27
23
  * @param {string} options.webVersion - The version of WhatsApp Web to use. Use options.webVersionCache to configure how the version is retrieved.
28
24
  * @param {object} options.webVersionCache - Determines how to retrieve the WhatsApp Web version. Defaults to a local cache (LocalWebCache) that falls back to latest if the requested version is not found.
29
25
  * @param {number} options.authTimeoutMs - Timeout for authentication selector in puppeteer
26
+ * @param {function} options.evalOnNewDoc - function to eval on new doc
30
27
  * @param {object} options.puppeteer - Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/
31
28
  * @param {number} options.qrMaxRetries - How many times should the qrcode be refreshed before giving up
32
- * @param {string} options.restartOnAuthFail - @deprecated This option should be set directly on the LegacySessionAuth.
33
- * @param {object} options.session - @deprecated Only here for backwards-compatibility. You should move to using LocalAuth, or set the authStrategy to LegacySessionAuth explicitly.
34
29
  * @param {number} options.takeoverOnConflict - If another whatsapp web session is detected (another browser), take over the session in the current browser
35
30
  * @param {number} options.takeoverTimeoutMs - How much time to wait before taking over the session
36
31
  * @param {string} options.userAgent - User agent to use in puppeteer
@@ -95,33 +90,41 @@ class Client extends EventEmitter {
95
90
  * Private function
96
91
  */
97
92
  async inject() {
98
- await this.pupPage.waitForFunction('window.Debug?.VERSION != undefined', {timeout: this.options.authTimeoutMs});
93
+ if(this.options.authTimeoutMs === undefined || this.options.authTimeoutMs==0){
94
+ this.options.authTimeoutMs = 30000;
95
+ }
96
+ let start = Date.now();
97
+ let timeout = this.options.authTimeoutMs;
98
+ let res = false;
99
+ while(start > (Date.now() - timeout)){
100
+ res = await this.pupPage.evaluate('window.Debug?.VERSION != undefined');
101
+ if(res){break;}
102
+ await new Promise(r => setTimeout(r, 200));
103
+ }
104
+ if(!res){
105
+ throw 'auth timeout';
106
+ }
99
107
  await this.setDeviceName(this.options.deviceName, this.options.browserName);
100
108
  const pairWithPhoneNumber = this.options.pairWithPhoneNumber;
101
109
  const version = await this.getWWebVersion();
102
- const isCometOrAbove = parseInt(version.split('.')?.[1]) >= 3000;
103
110
 
104
- if (isCometOrAbove) {
105
- await this.pupPage.evaluate(ExposeAuthStore);
106
- } else {
107
- await this.pupPage.evaluate(ExposeLegacyAuthStore, moduleRaid.toString());
108
- }
111
+ await this.pupPage.evaluate(ExposeAuthStore);
109
112
 
110
113
  const needAuthentication = await this.pupPage.evaluate(async () => {
111
- let state = window.AuthStore.AppState.state;
114
+ let state = window.require('WAWebSocketModel').Socket.state;
112
115
 
113
116
  if (state === 'OPENING' || state === 'UNLAUNCHED' || state === 'PAIRING') {
114
117
  // wait till state changes
115
118
  await new Promise(r => {
116
- window.AuthStore.AppState.on('change:state', function waitTillInit(_AppState, state) {
119
+ window.require('WAWebSocketModel').Socket.on('change:state', function waitTillInit(_AppState, state) {
117
120
  if (state !== 'OPENING' && state !== 'UNLAUNCHED' && state !== 'PAIRING') {
118
- window.AuthStore.AppState.off('change:state', waitTillInit);
121
+ window.require('WAWebSocketModel').Socket.off('change:state', waitTillInit);
119
122
  r();
120
123
  }
121
124
  });
122
125
  });
123
126
  }
124
- state = window.AuthStore.AppState.state;
127
+ state = window.require('WAWebSocketModel').Socket.state;
125
128
  return state == 'UNPAIRED' || state == 'UNPAIRED_IDLE';
126
129
  });
127
130
 
@@ -193,7 +196,7 @@ class Client extends EventEmitter {
193
196
  await exposeFunctionIfAbsent(this.pupPage, 'onAuthAppStateChangedEvent', async (state) => {
194
197
  if (state == 'UNPAIRED_IDLE' && !pairWithPhoneNumber.phoneNumber) {
195
198
  // refresh qr code
196
- window.Store.Cmd.refreshQR();
199
+ window.require('WAWebCmd').Cmd.refreshQR();
197
200
  }
198
201
  });
199
202
 
@@ -206,7 +209,7 @@ class Client extends EventEmitter {
206
209
  this.emit(Events.AUTHENTICATED, authEventPayload);
207
210
 
208
211
  const injected = await this.pupPage.evaluate(async () => {
209
- return typeof window.Store !== 'undefined' && typeof window.WWebJS !== 'undefined';
212
+ return typeof window.WWebJS !== 'undefined';
210
213
  });
211
214
 
212
215
  if (!injected) {
@@ -217,31 +220,31 @@ class Client extends EventEmitter {
217
220
  await webCache.persist(this.currentIndexHtml, version);
218
221
  }
219
222
 
220
- if (isCometOrAbove) {
221
- await this.pupPage.evaluate(ExposeStore);
222
- } else {
223
- // make sure all modules are ready before injection
224
- // 2 second delay after authentication makes sense and does not need to be made dyanmic or removed
225
- await new Promise(r => setTimeout(r, 2000));
226
- await this.pupPage.evaluate(ExposeLegacyStore);
223
+ //Load util functions (serializers, helper functions)
224
+ await this.pupPage.evaluate(LoadUtils);
225
+
226
+ let start = Date.now();
227
+ let res = false;
228
+ while(start > (Date.now() - 30000)){
229
+ // Check window.WWebJS Injection
230
+ res = await this.pupPage.evaluate('window.WWebJS != undefined');
231
+ if(res){break;}
232
+ await new Promise(r => setTimeout(r, 200));
233
+ }
234
+ if(!res){
235
+ throw 'ready timeout';
227
236
  }
228
-
229
- // Check window.Store Injection
230
- await this.pupPage.waitForFunction('window.Store != undefined');
231
237
 
232
238
  /**
233
239
  * Current connection information
234
240
  * @type {ClientInfo}
235
241
  */
236
242
  this.info = new ClientInfo(this, await this.pupPage.evaluate(() => {
237
- return { ...window.Store.Conn.serialize(), wid: window.Store.User.getMaybeMePnUser() || window.Store.User.getMaybeMeLidUser() };
243
+ return { ...(window.require('WAWebConnModel').Conn).serialize(), wid: (window.require('WAWebUserPrefsMeUser')).getMaybeMePnUser() || (window.require('WAWebUserPrefsMeUser')).getMaybeMeLidUser() };
238
244
  }));
239
245
 
240
246
  this.interface = new InterfaceController(this);
241
247
 
242
- //Load util functions (serializers, helper functions)
243
- await this.pupPage.evaluate(LoadUtils);
244
-
245
248
  await this.attachEventListeners();
246
249
  }
247
250
  /**
@@ -263,12 +266,16 @@ class Client extends EventEmitter {
263
266
  await this.pupPage.waitForNavigation({waitUntil: 'load', timeout: 5000}).catch((_) => _);
264
267
  });
265
268
  await this.pupPage.evaluate(() => {
266
- window.AuthStore.AppState.on('change:state', (_AppState, state) => { window.onAuthAppStateChangedEvent(state); });
267
- window.AuthStore.AppState.on('change:hasSynced', () => { window.onAppStateHasSyncedEvent(); });
268
- window.AuthStore.Cmd.on('offline_progress_update', () => {
269
+ window.require('WAWebSocketModel').Socket.on('change:state', (_AppState, state) => { window.onAuthAppStateChangedEvent(state); });
270
+ window.require('WAWebSocketModel').Socket.on('change:hasSynced', () => { window.onAppStateHasSyncedEvent(); });
271
+ const Cmd = window.require('WAWebCmd').Cmd;
272
+ Cmd.on('offline_progress_update_from_bridge', () => {
269
273
  window.onOfflineProgressUpdateEvent(window.AuthStore.OfflineMessageHandler.getOfflineDeliveryProgress());
270
274
  });
271
- window.AuthStore.Cmd.on('logout', async () => {
275
+ Cmd.on('logout', async () => {
276
+ await window.onLogoutEvent();
277
+ });
278
+ Cmd.on('logout_from_bridge', async () => {
272
279
  await window.onLogoutEvent();
273
280
  });
274
281
  });
@@ -300,7 +307,7 @@ class Client extends EventEmitter {
300
307
  page = await browser.newPage();
301
308
  } else {
302
309
  const browserArgs = [...(puppeteerOpts.args || [])];
303
- if(!browserArgs.find(arg => arg.includes('--user-agent'))) {
310
+ if(this.options.userAgent !== false && !browserArgs.find(arg => arg.includes('--user-agent'))) {
304
311
  browserArgs.push(`--user-agent=${this.options.userAgent}`);
305
312
  }
306
313
  // navigator.webdriver fix
@@ -313,8 +320,9 @@ class Client extends EventEmitter {
313
320
  if (this.options.proxyAuthentication !== undefined) {
314
321
  await page.authenticate(this.options.proxyAuthentication);
315
322
  }
316
-
317
- await page.setUserAgent(this.options.userAgent);
323
+ if(this.options.userAgent !== false) {
324
+ await page.setUserAgent(this.options.userAgent);
325
+ }
318
326
  if (this.options.bypassCSP) await page.setBypassCSP(true);
319
327
 
320
328
  this.pupBrowser = browser;
@@ -322,20 +330,10 @@ class Client extends EventEmitter {
322
330
 
323
331
  await this.authStrategy.afterBrowserInitialized();
324
332
  await this.initWebVersionCache();
325
-
326
- // ocVersion (isOfficialClient patch)
327
- // remove after 2.3000.x hard release
328
- await page.evaluateOnNewDocument(() => {
329
- const originalError = Error;
330
- window.originalError = originalError;
331
- //eslint-disable-next-line no-global-assign
332
- Error = function (message) {
333
- const error = new originalError(message);
334
- const originalStack = error.stack;
335
- if (error.stack.includes('moduleRaid')) error.stack = originalStack + '\n at https://web.whatsapp.com/vendors~lazy_loaded_low_priority_components.05e98054dbd60f980427.js:2:44';
336
- return error;
337
- };
338
- });
333
+
334
+ if (this.options.evalOnNewDoc !== undefined) {
335
+ await page.evaluateOnNewDocument(this.options.evalOnNewDoc);
336
+ }
339
337
 
340
338
  await page.goto(WhatsWebURL, {
341
339
  waitUntil: 'load',
@@ -378,7 +376,8 @@ class Client extends EventEmitter {
378
376
  clearInterval(window.codeInterval); // remove existing interval
379
377
  }
380
378
  window.codeInterval = setInterval(async () => {
381
- if (window.AuthStore.AppState.state != 'UNPAIRED' && window.AuthStore.AppState.state != 'UNPAIRED_IDLE') {
379
+ const state = window.require('WAWebSocketModel').Socket.state;
380
+ if (state != 'UNPAIRED' && state != 'UNPAIRED_IDLE') {
382
381
  clearInterval(window.codeInterval);
383
382
  return;
384
383
  }
@@ -588,7 +587,7 @@ class Client extends EventEmitter {
588
587
 
589
588
  if (state === WAState.CONFLICT) {
590
589
  setTimeout(() => {
591
- this.pupPage.evaluate(() => window.Store.AppState.takeover());
590
+ this.pupPage.evaluate(() => window.require('WAWebSocketModel').Socket.takeover());
592
591
  }, this.options.takeoverTimeoutMs);
593
592
  }
594
593
  }
@@ -721,18 +720,22 @@ class Client extends EventEmitter {
721
720
  });
722
721
 
723
722
  await this.pupPage.evaluate(() => {
724
- window.Store.Msg.on('change', (msg) => { window.onChangeMessageEvent(window.WWebJS.getMessageModel(msg)); });
725
- window.Store.Msg.on('change:type', (msg) => { window.onChangeMessageTypeEvent(window.WWebJS.getMessageModel(msg)); });
726
- window.Store.Msg.on('change:ack', (msg, ack) => { window.onMessageAckEvent(window.WWebJS.getMessageModel(msg), ack); });
727
- window.Store.Msg.on('change:isUnsentMedia', (msg, unsent) => { if (msg.id.fromMe && !unsent) window.onMessageMediaUploadedEvent(window.WWebJS.getMessageModel(msg)); });
728
- window.Store.Msg.on('remove', (msg) => { if (msg.isNewMsg) window.onRemoveMessageEvent(window.WWebJS.getMessageModel(msg)); });
729
- window.Store.Msg.on('change:body change:caption', (msg, newBody, prevBody) => { window.onEditMessageEvent(window.WWebJS.getMessageModel(msg), newBody, prevBody); });
730
- window.Store.AppState.on('change:state', (_AppState, state) => { window.onAppStateChangedEvent(state); });
731
- window.Store.Conn.on('change:battery', (state) => { window.onBatteryStateChangedEvent(state); });
732
- // window.Store.Call.on('add', (call) => { window.onIncomingCall(call); });
733
- window.Store.Chat.on('remove', async (chat) => { window.onRemoveChatEvent(await window.WWebJS.getChatModel(chat)); });
734
- window.Store.Chat.on('change:archive', async (chat, currState, prevState) => { window.onArchiveChatEvent(await window.WWebJS.getChatModel(chat), currState, prevState); });
735
- window.Store.Msg.on('add', (msg) => {
723
+ const { Msg, Chat, WAWebCallCollection } = window.require('WAWebCollections');
724
+ const AppState = window.require('WAWebSocketModel').Socket;
725
+ Msg.on('change', (msg) => { window.onChangeMessageEvent(window.WWebJS.getMessageModel(msg)); });
726
+ Msg.on('change:type', (msg) => { window.onChangeMessageTypeEvent(window.WWebJS.getMessageModel(msg)); });
727
+ Msg.on('change:ack', (msg, ack) => { window.onMessageAckEvent(window.WWebJS.getMessageModel(msg), ack); });
728
+ Msg.on('change:isUnsentMedia', (msg, unsent) => { if (msg.id.fromMe && !unsent) window.onMessageMediaUploadedEvent(window.WWebJS.getMessageModel(msg)); });
729
+ Msg.on('remove', (msg) => { if (msg.isNewMsg) window.onRemoveMessageEvent(window.WWebJS.getMessageModel(msg)); });
730
+ Msg.on('change:body change:caption', (msg, newBody, prevBody) => { window.onEditMessageEvent(window.WWebJS.getMessageModel(msg), newBody, prevBody); });
731
+ AppState.on('change:state', (_AppState, state) => { window.onAppStateChangedEvent(state); });
732
+ (window.require('WAWebConnModel').Conn).on('change:battery', (state) => { window.onBatteryStateChangedEvent(state); });
733
+ if (WAWebCallCollection && typeof WAWebCallCollection.on === 'function') {
734
+ WAWebCallCollection.on('add', (call) => { window.onIncomingCall(call); });
735
+ }
736
+ Chat.on('remove', async (chat) => { window.onRemoveChatEvent(await window.WWebJS.getChatModel(chat)); });
737
+ Chat.on('change:archive', async (chat, currState, prevState) => { window.onArchiveChatEvent(await window.WWebJS.getChatModel(chat), currState, prevState); });
738
+ Msg.on('add', (msg) => {
736
739
  if (msg.isNewMsg) {
737
740
  if(msg.type === 'ciphertext') {
738
741
  // defer message event until ciphertext is resolved (type changed)
@@ -743,72 +746,51 @@ class Client extends EventEmitter {
743
746
  }
744
747
  }
745
748
  });
746
- window.Store.Chat.on('change:unreadCount', (chat) => {window.onChatUnreadCountEvent(chat);});
747
-
748
- if (window.compareWwebVersions(window.Debug.VERSION, '>=', '2.3000.1014111620')) {
749
- const module = window.Store.AddonReactionTable;
750
- const ogMethod = module.bulkUpsert;
751
- module.bulkUpsert = ((...args) => {
752
- window.onReaction(args[0].map(reaction => {
753
- const msgKey = reaction.id;
754
- const parentMsgKey = reaction.reactionParentKey;
755
- const timestamp = reaction.reactionTimestamp / 1000;
756
- const sender = reaction.author ?? reaction.from;
757
- const senderUserJid = sender._serialized;
758
-
759
- return {...reaction, msgKey, parentMsgKey, senderUserJid, timestamp };
760
- }));
761
-
762
- return ogMethod(...args);
763
- }).bind(module);
764
-
765
- const pollVoteModule = window.Store.AddonPollVoteTable;
766
- const ogPollVoteMethod = pollVoteModule.bulkUpsert;
767
-
768
- pollVoteModule.bulkUpsert = (async (...args) => {
769
- const votes = await Promise.all(args[0].map(async vote => {
770
- const msgKey = vote.id;
771
- const parentMsgKey = vote.pollUpdateParentKey;
772
- const timestamp = vote.t / 1000;
773
- const sender = vote.author ?? vote.from;
774
- const senderUserJid = sender._serialized;
775
-
776
- let parentMessage = window.Store.Msg.get(parentMsgKey._serialized);
777
- if (!parentMessage) {
778
- const fetched = await window.Store.Msg.getMessagesById([parentMsgKey._serialized]);
779
- parentMessage = fetched?.messages?.[0] || null;
780
- }
749
+ Chat.on('change:unreadCount', (chat) => {window.onChatUnreadCountEvent(chat);});
781
750
 
782
- return {
783
- ...vote,
784
- msgKey,
785
- sender,
786
- parentMsgKey,
787
- senderUserJid,
788
- timestamp,
789
- parentMessage
790
- };
791
- }));
792
-
793
- window.onPollVoteEvent(votes);
794
-
795
- return ogPollVoteMethod.apply(pollVoteModule, args);
796
- }).bind(pollVoteModule);
797
- } else {
798
- const module = window.Store.createOrUpdateReactionsModule;
799
- const ogMethod = module.createOrUpdateReactions;
800
- module.createOrUpdateReactions = ((...args) => {
801
- window.onReaction(args[0].map(reaction => {
802
- const msgKey = window.Store.MsgKey.fromString(reaction.msgKey);
803
- const parentMsgKey = window.Store.MsgKey.fromString(reaction.parentMsgKey);
804
- const timestamp = reaction.timestamp / 1000;
805
-
806
- return {...reaction, msgKey, parentMsgKey, timestamp };
807
- }));
808
-
809
- return ogMethod(...args);
810
- }).bind(module);
811
- }
751
+ window.WWebJS.injectToFunction({ module: 'WAWebAddonReactionTableMode', function: 'reactionTableMode.bulkUpsert'}, (module, origFunction, ...args) => {
752
+ window.onReaction(args[0].map(reaction => {
753
+ const msgKey = reaction.id;
754
+ const parentMsgKey = reaction.reactionParentKey;
755
+ const timestamp = reaction.reactionTimestamp / 1000;
756
+ const sender = reaction.author ?? reaction.from;
757
+ const senderUserJid = sender._serialized;
758
+
759
+ return {...reaction, msgKey, parentMsgKey, senderUserJid, timestamp };
760
+ }));
761
+
762
+ return origFunction.apply(module, args);
763
+ });
764
+
765
+ window.WWebJS.injectToFunction({ module: 'WAWebAddonPollVoteTableMode', function: 'pollVoteTableMode.bulkUpsert'}, async (module, origFunction, ...args) => {
766
+ const votes = await Promise.all(args[0].map(async vote => {
767
+ const msgKey = vote.id;
768
+ const parentMsgKey = vote.pollUpdateParentKey;
769
+ const timestamp = vote.t / 1000;
770
+ const sender = vote.author ?? vote.from;
771
+ const senderUserJid = sender._serialized;
772
+
773
+ let parentMessage = Msg.get(parentMsgKey._serialized);
774
+ if (!parentMessage) {
775
+ const fetched = await Msg.getMessagesById([parentMsgKey._serialized]);
776
+ parentMessage = fetched?.messages?.[0] || null;
777
+ }
778
+
779
+ return {
780
+ ...vote,
781
+ msgKey,
782
+ sender,
783
+ parentMsgKey,
784
+ senderUserJid,
785
+ timestamp,
786
+ parentMessage
787
+ };
788
+ }));
789
+
790
+ window.onPollVoteEvent(votes);
791
+
792
+ return origFunction.apply(module, args);
793
+ });
812
794
  });
813
795
  }
814
796
 
@@ -846,7 +828,11 @@ class Client extends EventEmitter {
846
828
  * Closes the client
847
829
  */
848
830
  async destroy() {
849
- await this.pupBrowser.close();
831
+ const browser = this.pupBrowser;
832
+ const isConnected = browser?.isConnected?.();
833
+ if (isConnected) {
834
+ await browser.close();
835
+ }
850
836
  await this.authStrategy.destroy();
851
837
  }
852
838
 
@@ -855,9 +841,7 @@ class Client extends EventEmitter {
855
841
  */
856
842
  async logout() {
857
843
  await this.pupPage.evaluate(() => {
858
- if (window.Store && window.Store.AppState && typeof window.Store.AppState.logout === 'function') {
859
- return window.Store.AppState.logout();
860
- }
844
+ return window.require('WAWebSocketModel').Socket.logout();
861
845
  });
862
846
  await this.pupBrowser.close();
863
847
 
@@ -948,9 +932,10 @@ class Client extends EventEmitter {
948
932
  */
949
933
  async sendMessage(chatId, content, options = {}) {
950
934
  const isChannel = /@\w*newsletter\b/.test(chatId);
935
+ const isStatus = /@\w*broadcast\b/.test(chatId);
951
936
 
952
937
  if (isChannel && [
953
- options.sendMediaAsDocument, options.quotedMessageId,
938
+ options.sendMediaAsDocument, options.quotedMessageId,
954
939
  options.parseVCards, options.isViewOnce,
955
940
  content instanceof Location, content instanceof Contact,
956
941
  content instanceof Buttons, content instanceof List,
@@ -958,6 +943,16 @@ class Client extends EventEmitter {
958
943
  ].includes(true)) {
959
944
  console.warn('The message type is currently not supported for sending in channels,\nthe supported message types are: text, image, sticker, gif, video, voice and poll.');
960
945
  return null;
946
+
947
+ } else if (isStatus && [
948
+ options.sendMediaAsDocument, options.quotedMessageId,
949
+ options.parseVCards, options.isViewOnce, options.sendMediaAsSticker,
950
+ content instanceof Location, content instanceof Contact,
951
+ content instanceof Poll, content instanceof Buttons, content instanceof List,
952
+ Array.isArray(content) && content.length > 0 && content[0] instanceof Contact
953
+ ].includes(true)) {
954
+ console.warn('The message type is currently not supported for sending in status broadcast,\nthe supported message types are: text, image, gif, audio and video.');
955
+ return null;
961
956
  }
962
957
 
963
958
  if (options.mentions) {
@@ -978,6 +973,7 @@ class Client extends EventEmitter {
978
973
  sendMediaAsDocument: options.sendMediaAsDocument,
979
974
  sendMediaAsHd: options.sendMediaAsHd,
980
975
  caption: options.caption,
976
+ isCaptionByUser: options.caption ? true : false,
981
977
  quotedMessageId: options.quotedMessageId,
982
978
  parseVCards: options.parseVCards !== false,
983
979
  mentionedJidList: options.mentions || [],
@@ -1069,15 +1065,16 @@ class Client extends EventEmitter {
1069
1065
  */
1070
1066
  async sendChannelAdminInvite(chatId, channelId, options = {}) {
1071
1067
  const response = await this.pupPage.evaluate(async (chatId, channelId, options) => {
1072
- const channelWid = window.Store.WidFactory.createWid(channelId);
1073
- const chatWid = window.Store.WidFactory.createWid(chatId);
1074
- const chat = window.Store.Chat.get(chatWid) || (await window.Store.Chat.find(chatWid));
1068
+ const { createWid } = window.require('WAWebWidFactory');
1069
+ const channelWid = createWid(channelId);
1070
+ const chatWid = createWid(chatId);
1071
+ const chat = window.require('WAWebCollections').Chat.get(chatWid) || (await (window.require('WAWebCollections')).Chat.find(chatWid));
1075
1072
 
1076
1073
  if (!chatWid.isUser()) {
1077
1074
  return false;
1078
1075
  }
1079
1076
 
1080
- return await window.Store.SendChannelMessage.sendNewsletterAdminInviteMessage(
1077
+ return await (window.require('WAWebNewsletterSendMsgAction')).sendNewsletterAdminInviteMessage(
1081
1078
  chat,
1082
1079
  {
1083
1080
  newsletterWid: channelWid,
@@ -1102,7 +1099,7 @@ class Client extends EventEmitter {
1102
1099
  */
1103
1100
  async searchMessages(query, options = {}) {
1104
1101
  const messages = await this.pupPage.evaluate(async (query, page, count, remote) => {
1105
- const { messages } = await window.Store.Msg.search(query, page, count, remote);
1102
+ const { messages } = await (window.require('WAWebCollections')).Msg.search(query, page, count, remote);
1106
1103
  return messages.map(msg => window.WWebJS.getMessageModel(msg));
1107
1104
  }, query, options.page, options.limit, options.chatId);
1108
1105
 
@@ -1193,16 +1190,21 @@ class Client extends EventEmitter {
1193
1190
 
1194
1191
  return ContactFactory.create(this, contact);
1195
1192
  }
1196
-
1193
+
1194
+ /**
1195
+ * Get message by ID
1196
+ * @param {string} messageId
1197
+ * @returns {Promise<Message>}
1198
+ */
1197
1199
  async getMessageById(messageId) {
1198
1200
  const msg = await this.pupPage.evaluate(async messageId => {
1199
- let msg = window.Store.Msg.get(messageId);
1201
+ let msg = (window.require('WAWebCollections')).Msg.get(messageId);
1200
1202
  if(msg) return window.WWebJS.getMessageModel(msg);
1201
1203
 
1202
1204
  const params = messageId.split('_');
1203
1205
  if (params.length !== 3 && params.length !== 4) throw new Error('Invalid serialized message id specified');
1204
1206
 
1205
- let messagesObject = await window.Store.Msg.getMessagesById([messageId]);
1207
+ let messagesObject = await (window.require('WAWebCollections')).Msg.getMessagesById([messageId]);
1206
1208
  if (messagesObject && messagesObject.messages.length) msg = messagesObject.messages[0];
1207
1209
 
1208
1210
  if(msg) return window.WWebJS.getMessageModel(msg);
@@ -1215,20 +1217,20 @@ class Client extends EventEmitter {
1215
1217
  /**
1216
1218
  * Gets instances of all pinned messages in a chat
1217
1219
  * @param {string} chatId The chat ID
1218
- * @returns {Promise<[Message]|[]>}
1220
+ * @returns {Promise<Array<Message>>}
1219
1221
  */
1220
1222
  async getPinnedMessages(chatId) {
1221
1223
  const pinnedMsgs = await this.pupPage.evaluate(async (chatId) => {
1222
- const chatWid = window.Store.WidFactory.createWid(chatId);
1223
- const chat = window.Store.Chat.get(chatWid) ?? await window.Store.Chat.find(chatWid);
1224
+ const chatWid = window.require('WAWebWidFactory').createWid(chatId);
1225
+ const chat = (window.require('WAWebCollections')).Chat.get(chatWid) ?? await (window.require('WAWebCollections')).Chat.find(chatWid);
1224
1226
  if (!chat) return [];
1225
1227
 
1226
- const msgs = await window.Store.PinnedMsgUtils.getTable().equals(['chatId'], chatWid.toString());
1228
+ const msgs = await (window.require('WAWebPinInChatSchema')).getTable().equals(['chatId'], chatWid.toString());
1227
1229
 
1228
1230
  const pinnedMsgs = (
1229
1231
  await Promise.all(
1230
1232
  msgs.filter(msg => msg.pinType == 1).map(async (msg) => {
1231
- const res = await window.Store.Msg.getMessagesById([msg.parentMsgKey]);
1233
+ const res = await (window.require('WAWebCollections')).Msg.getMessagesById([msg.parentMsgKey]);
1232
1234
  return res?.messages?.[0];
1233
1235
  })
1234
1236
  )
@@ -1249,7 +1251,7 @@ class Client extends EventEmitter {
1249
1251
  */
1250
1252
  async getInviteInfo(inviteCode) {
1251
1253
  return await this.pupPage.evaluate(inviteCode => {
1252
- return window.Store.GroupInvite.queryGroupInvite(inviteCode);
1254
+ return (window.require('WAWebGroupQueryJob')).queryGroupInvite(inviteCode);
1253
1255
  }, inviteCode);
1254
1256
  }
1255
1257
 
@@ -1260,7 +1262,7 @@ class Client extends EventEmitter {
1260
1262
  */
1261
1263
  async acceptInvite(inviteCode) {
1262
1264
  const res = await this.pupPage.evaluate(async inviteCode => {
1263
- return await window.Store.GroupInvite.joinGroupViaInvite(inviteCode);
1265
+ return await (window.require('WAWebGroupQueryJob')).joinGroupViaInvite(inviteCode);
1264
1266
  }, inviteCode);
1265
1267
 
1266
1268
  return res.gid._serialized;
@@ -1274,7 +1276,7 @@ class Client extends EventEmitter {
1274
1276
  async acceptChannelAdminInvite(channelId) {
1275
1277
  return await this.pupPage.evaluate(async (channelId) => {
1276
1278
  try {
1277
- await window.Store.ChannelUtils.acceptNewsletterAdminInvite(channelId);
1279
+ await (window.require('WAWebMexAcceptNewsletterAdminInviteJob')).acceptNewsletterAdminInvite(channelId);
1278
1280
  return true;
1279
1281
  } catch (err) {
1280
1282
  if (err.name === 'ServerStatusCodeError') return false;
@@ -1292,8 +1294,8 @@ class Client extends EventEmitter {
1292
1294
  async revokeChannelAdminInvite(channelId, userId) {
1293
1295
  return await this.pupPage.evaluate(async (channelId, userId) => {
1294
1296
  try {
1295
- const userWid = window.Store.WidFactory.createWid(userId);
1296
- await window.Store.ChannelUtils.revokeNewsletterAdminInvite(channelId, userWid);
1297
+ const userWid = window.require('WAWebWidFactory').createWid(userId);
1298
+ await (window.require('WAWebMexRevokeNewsletterAdminInviteJob')).revokeNewsletterAdminInvite(channelId, userWid);
1297
1299
  return true;
1298
1300
  } catch (err) {
1299
1301
  if (err.name === 'ServerStatusCodeError') return false;
@@ -1311,8 +1313,8 @@ class Client extends EventEmitter {
1311
1313
  async demoteChannelAdmin(channelId, userId) {
1312
1314
  return await this.pupPage.evaluate(async (channelId, userId) => {
1313
1315
  try {
1314
- const userWid = window.Store.WidFactory.createWid(userId);
1315
- await window.Store.ChannelUtils.demoteNewsletterAdmin(channelId, userWid);
1316
+ const userWid = window.require('WAWebWidFactory').createWid(userId);
1317
+ await (window.require('WAWebDemoteNewsletterAdminAction')).demoteNewsletterAdmin(channelId, userWid);
1316
1318
  return true;
1317
1319
  } catch (err) {
1318
1320
  if (err.name === 'ServerStatusCodeError') return false;
@@ -1331,8 +1333,8 @@ class Client extends EventEmitter {
1331
1333
  if (inviteInfo.inviteCodeExp == 0) throw 'Expired invite code';
1332
1334
  return this.pupPage.evaluate(async inviteInfo => {
1333
1335
  let { groupId, fromId, inviteCode, inviteCodeExp } = inviteInfo;
1334
- let userWid = window.Store.WidFactory.createWid(fromId);
1335
- return await window.Store.GroupInviteV4.joinGroupViaInviteV4(inviteCode, String(inviteCodeExp), groupId, userWid);
1336
+ let userWid = window.require('WAWebWidFactory').createWid(fromId);
1337
+ return await (window.require('WAWebGroupInviteV4Job')).joinGroupViaInviteV4(inviteCode, String(inviteCodeExp), groupId, userWid);
1336
1338
  }, inviteInfo);
1337
1339
  }
1338
1340
 
@@ -1342,7 +1344,7 @@ class Client extends EventEmitter {
1342
1344
  */
1343
1345
  async setStatus(status) {
1344
1346
  await this.pupPage.evaluate(async status => {
1345
- return await window.Store.StatusUtils.setMyStatus(status);
1347
+ return await (window.require('WAWebContactStatusBridge')).setMyStatus(status);
1346
1348
  }, status);
1347
1349
  }
1348
1350
 
@@ -1354,8 +1356,8 @@ class Client extends EventEmitter {
1354
1356
  */
1355
1357
  async setDisplayName(displayName) {
1356
1358
  const couldSet = await this.pupPage.evaluate(async displayName => {
1357
- if(!window.Store.Conn.canSetMyPushname()) return false;
1358
- await window.Store.Settings.setPushname(displayName);
1359
+ if(!(window.require('WAWebConnModel').Conn).canSetMyPushname()) return false;
1360
+ await (window.require('WAWebSetPushnameConnAction')).setPushname(displayName);
1359
1361
  return true;
1360
1362
  }, displayName);
1361
1363
 
@@ -1368,8 +1370,7 @@ class Client extends EventEmitter {
1368
1370
  */
1369
1371
  async getState() {
1370
1372
  return await this.pupPage.evaluate(() => {
1371
- if(!window.Store) return null;
1372
- return window.Store.AppState.state;
1373
+ return window.require('WAWebSocketModel').Socket.state ?? null;
1373
1374
  });
1374
1375
  }
1375
1376
 
@@ -1378,7 +1379,7 @@ class Client extends EventEmitter {
1378
1379
  */
1379
1380
  async sendPresenceAvailable() {
1380
1381
  return await this.pupPage.evaluate(() => {
1381
- return window.Store.PresenceUtils.sendPresenceAvailable();
1382
+ return window.require('WAWebPresenceChatAction').sendPresenceAvailable();
1382
1383
  });
1383
1384
  }
1384
1385
 
@@ -1387,7 +1388,7 @@ class Client extends EventEmitter {
1387
1388
  */
1388
1389
  async sendPresenceUnavailable() {
1389
1390
  return await this.pupPage.evaluate(() => {
1390
- return window.Store.PresenceUtils.sendPresenceUnavailable();
1391
+ return window.require('WAWebPresenceChatAction').sendPresenceUnavailable();
1391
1392
  });
1392
1393
  }
1393
1394
 
@@ -1398,7 +1399,7 @@ class Client extends EventEmitter {
1398
1399
  async archiveChat(chatId) {
1399
1400
  return await this.pupPage.evaluate(async chatId => {
1400
1401
  let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
1401
- await window.Store.Cmd.archiveChat(chat, true);
1402
+ await (window.require('WAWebCmd').Cmd).archiveChat(chat, true);
1402
1403
  return true;
1403
1404
  }, chatId);
1404
1405
  }
@@ -1410,7 +1411,7 @@ class Client extends EventEmitter {
1410
1411
  async unarchiveChat(chatId) {
1411
1412
  return await this.pupPage.evaluate(async chatId => {
1412
1413
  let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
1413
- await window.Store.Cmd.archiveChat(chat, false);
1414
+ await (window.require('WAWebCmd').Cmd).archiveChat(chat, false);
1414
1415
  return false;
1415
1416
  }, chatId);
1416
1417
  }
@@ -1426,14 +1427,14 @@ class Client extends EventEmitter {
1426
1427
  return true;
1427
1428
  }
1428
1429
  const MAX_PIN_COUNT = 3;
1429
- const chatModels = window.Store.Chat.getModelsArray();
1430
+ const chatModels = (window.require('WAWebCollections')).Chat.getModelsArray();
1430
1431
  if (chatModels.length > MAX_PIN_COUNT) {
1431
1432
  let maxPinned = chatModels[MAX_PIN_COUNT - 1].pin;
1432
1433
  if (maxPinned) {
1433
1434
  return false;
1434
1435
  }
1435
1436
  }
1436
- await window.Store.Cmd.pinChat(chat, true);
1437
+ await (window.require('WAWebCmd').Cmd).pinChat(chat, true);
1437
1438
  return true;
1438
1439
  }, chatId);
1439
1440
  }
@@ -1448,7 +1449,7 @@ class Client extends EventEmitter {
1448
1449
  if (!chat.pin) {
1449
1450
  return false;
1450
1451
  }
1451
- await window.Store.Cmd.pinChat(chat, false);
1452
+ await (window.require('WAWebCmd').Cmd).pinChat(chat, false);
1452
1453
  return false;
1453
1454
  }, chatId);
1454
1455
  }
@@ -1482,7 +1483,7 @@ class Client extends EventEmitter {
1482
1483
  */
1483
1484
  async _muteUnmuteChat (chatId, action, unmuteDateTs) {
1484
1485
  return this.pupPage.evaluate(async (chatId, action, unmuteDateTs) => {
1485
- const chat = window.Store.Chat.get(chatId) ?? await window.Store.Chat.find(chatId);
1486
+ const chat = (window.require('WAWebCollections')).Chat.get(chatId) ?? await (window.require('WAWebCollections')).Chat.find(chatId);
1486
1487
  action === 'MUTE'
1487
1488
  ? await chat.mute.mute({ expiration: unmuteDateTs, sendDevice: true })
1488
1489
  : await chat.mute.unmute({ sendDevice: true });
@@ -1497,7 +1498,7 @@ class Client extends EventEmitter {
1497
1498
  async markChatUnread(chatId) {
1498
1499
  await this.pupPage.evaluate(async chatId => {
1499
1500
  let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
1500
- await window.Store.Cmd.markChatUnread(chat, true);
1501
+ await (window.require('WAWebCmd').Cmd).markChatUnread(chat, true);
1501
1502
  }, chatId);
1502
1503
  }
1503
1504
 
@@ -1509,10 +1510,10 @@ class Client extends EventEmitter {
1509
1510
  async getProfilePicUrl(contactId) {
1510
1511
  const profilePic = await this.pupPage.evaluate(async contactId => {
1511
1512
  try {
1512
- const chatWid = window.Store.WidFactory.createWid(contactId);
1513
- return window.compareWwebVersions(window.Debug.VERSION, '<', '2.3000.0')
1514
- ? await window.Store.ProfilePic.profilePicFind(chatWid)
1515
- : await window.Store.ProfilePic.requestProfilePicFromServer(chatWid);
1513
+ const chatWid = window.require('WAWebWidFactory').createWid(contactId);
1514
+ return window.WWebJS.compareWwebVersions(window.Debug.VERSION, '<', '2.3000.0')
1515
+ ? await window.require('WAWebContactProfilePicThumbBridge').profilePicFind(chatWid)
1516
+ : await window.require('WAWebContactProfilePicThumbBridge').requestProfilePicFromServer(chatWid);
1516
1517
  } catch (err) {
1517
1518
  if(err.name === 'ServerStatusCodeError') return undefined;
1518
1519
  throw err;
@@ -1529,17 +1530,17 @@ class Client extends EventEmitter {
1529
1530
  */
1530
1531
  async getCommonGroups(contactId) {
1531
1532
  const commonGroups = await this.pupPage.evaluate(async (contactId) => {
1532
- let contact = window.Store.Contact.get(contactId);
1533
+ let contact = (window.require('WAWebCollections')).Contact.get(contactId);
1533
1534
  if (!contact) {
1534
- const wid = window.Store.WidFactory.createWid(contactId);
1535
- const chatConstructor = window.Store.Contact.getModelsArray().find(c=>!c.isGroup).constructor;
1535
+ const wid = window.require('WAWebWidFactory').createWid(contactId);
1536
+ const chatConstructor = (window.require('WAWebCollections')).Contact.getModelsArray().find(c=>!c.isGroup).constructor;
1536
1537
  contact = new chatConstructor({id: wid});
1537
1538
  }
1538
1539
 
1539
1540
  if (contact.commonGroups) {
1540
1541
  return contact.commonGroups.serialize();
1541
1542
  }
1542
- const status = await window.Store.findCommonGroups(contact);
1543
+ const status = await (window.require('WAWebFindCommonGroupsContactAction').findCommonGroups)(contact);
1543
1544
  if (status) {
1544
1545
  return contact.commonGroups.serialize();
1545
1546
  }
@@ -1557,7 +1558,7 @@ class Client extends EventEmitter {
1557
1558
  */
1558
1559
  async resetState() {
1559
1560
  await this.pupPage.evaluate(() => {
1560
- window.Store.AppState.reconnect();
1561
+ window.require('WAWebSocketModel').Socket.reconnect();
1561
1562
  });
1562
1563
  }
1563
1564
 
@@ -1582,8 +1583,8 @@ class Client extends EventEmitter {
1582
1583
  }
1583
1584
 
1584
1585
  return await this.pupPage.evaluate(async number => {
1585
- const wid = window.Store.WidFactory.createWid(number);
1586
- const result = await window.Store.QueryExist(wid);
1586
+ const wid = window.require('WAWebWidFactory').createWid(number);
1587
+ const result = await (window.require('WAWebQueryExistsJob').queryWidExists)(wid);
1587
1588
  if (!result || result.wid === undefined) return null;
1588
1589
  return result.wid;
1589
1590
  }, number);
@@ -1599,7 +1600,7 @@ class Client extends EventEmitter {
1599
1600
  if (!number.includes('@s.whatsapp.net')) number = `${number}@s.whatsapp.net`;
1600
1601
 
1601
1602
  return await this.pupPage.evaluate(async numberId => {
1602
- return window.Store.NumberInfo.formattedPhoneNumber(numberId);
1603
+ return window.require('WAWebPhoneUtils').formattedPhoneNumber(numberId);
1603
1604
  }, number);
1604
1605
  }
1605
1606
 
@@ -1612,7 +1613,7 @@ class Client extends EventEmitter {
1612
1613
  number = number.replace(' ', '').replace('+', '').replace('@c.us', '');
1613
1614
 
1614
1615
  return await this.pupPage.evaluate(async numberId => {
1615
- return window.Store.NumberInfo.findCC(numberId);
1616
+ return window.require('WAPhoneFindCC').findCC(numberId);
1616
1617
  }, number);
1617
1618
  }
1618
1619
 
@@ -1678,17 +1679,17 @@ class Client extends EventEmitter {
1678
1679
  };
1679
1680
 
1680
1681
  for (const participant of participants) {
1681
- const pWid = window.Store.WidFactory.createWid(participant);
1682
- if ((await window.Store.QueryExist(pWid))?.wid) {
1682
+ const pWid = window.require('WAWebWidFactory').createWid(participant);
1683
+ if ((await (window.require('WAWebQueryExistsJob').queryWidExists)(pWid))?.wid) {
1683
1684
  participantWids.push({ phoneNumber: pWid });
1684
1685
  }
1685
1686
  else failedParticipants.push(participant);
1686
1687
  }
1687
1688
 
1688
- parentGroupId && (parentGroupWid = window.Store.WidFactory.createWid(parentGroupId));
1689
+ parentGroupId && (parentGroupWid = window.require('WAWebWidFactory').createWid(parentGroupId));
1689
1690
 
1690
1691
  try {
1691
- createGroupResult = await window.Store.GroupUtils.createGroup(
1692
+ createGroupResult = await (window.require('WAWebGroupCreateJob')).createGroup(
1692
1693
  {
1693
1694
  'addressingModeOverride': 'lid',
1694
1695
  'memberAddMode': options.memberAddMode ?? false,
@@ -1707,14 +1708,14 @@ class Client extends EventEmitter {
1707
1708
 
1708
1709
  for (const participant of createGroupResult.participants) {
1709
1710
  let isInviteV4Sent = false;
1710
- participant.wid.server == 'lid' && (participant.wid = window.Store.LidUtils.getPhoneNumber(participant.wid));
1711
+ participant.wid.server == 'lid' && (participant.wid = window.require('WAWebApiContact').getPhoneNumber(participant.wid));
1711
1712
  const participantId = participant.wid._serialized;
1712
1713
  const statusCode = participant.error || 200;
1713
1714
 
1714
1715
  if (autoSendInviteV4 && statusCode === 403) {
1715
- window.Store.Contact.gadd(participant.wid, { silent: true });
1716
- const addParticipantResult = await window.Store.GroupInviteV4.sendGroupInviteMessage(
1717
- window.Store.Chat.get(participant.wid) || await window.Store.Chat.find(participant.wid),
1716
+ (window.require('WAWebCollections')).Contact.gadd(participant.wid, { silent: true });
1717
+ const addParticipantResult = await (window.require('WAWebChatSendMessages')).sendGroupInviteMessage(
1718
+ (window.require('WAWebCollections')).Chat.get(participant.wid) || await (window.require('WAWebCollections')).Chat.find(participant.wid),
1718
1719
  createGroupResult.wid._serialized,
1719
1720
  createGroupResult.subject,
1720
1721
  participant.invite_code,
@@ -1775,7 +1776,7 @@ class Client extends EventEmitter {
1775
1776
  return await this.pupPage.evaluate(async (title, options) => {
1776
1777
  let response, { description = null, picture = null } = options;
1777
1778
 
1778
- if (!window.Store.ChannelUtils.isNewsletterCreationEnabled()) {
1779
+ if (!(window.require('WAWebNewsletterGatingUtils')).isNewsletterCreationEnabled()) {
1779
1780
  return 'CreateChannelError: A channel creation is not enabled';
1780
1781
  }
1781
1782
 
@@ -1789,7 +1790,7 @@ class Client extends EventEmitter {
1789
1790
  }
1790
1791
 
1791
1792
  try {
1792
- response = await window.Store.ChannelUtils.createNewsletterQuery({
1793
+ response = await (window.require('WAWebNewsletterCreateQueryJob')).createNewsletterQuery({
1793
1794
  name: title,
1794
1795
  description: description,
1795
1796
  picture: picture,
@@ -1803,7 +1804,7 @@ class Client extends EventEmitter {
1803
1804
 
1804
1805
  return {
1805
1806
  title: title,
1806
- nid: window.Store.JidToWid.newsletterJidToWid(response.idJid),
1807
+ nid: window.require('WAWebJidToWid').newsletterJidToWid(response.idJid),
1807
1808
  inviteLink: `https://whatsapp.com/channel/${response.newsletterInviteLinkMetadataMixin.inviteCode}`,
1808
1809
  createdAtTs: response.newsletterCreationTimeMetadataMixin.creationTimeValue
1809
1810
  };
@@ -1856,17 +1857,17 @@ class Client extends EventEmitter {
1856
1857
  async transferChannelOwnership(channelId, newOwnerId, options = {}) {
1857
1858
  return await this.pupPage.evaluate(async (channelId, newOwnerId, options) => {
1858
1859
  const channel = await window.WWebJS.getChat(channelId, { getAsModel: false });
1859
- const newOwner = window.Store.Contact.get(newOwnerId) || (await window.Store.Contact.find(newOwnerId));
1860
+ const newOwner = (window.require('WAWebCollections')).Contact.get(newOwnerId) || (await (window.require('WAWebCollections')).Contact.find(newOwnerId));
1860
1861
  if (!channel.newsletterMetadata) {
1861
- await window.Store.NewsletterMetadataCollection.update(channel.id);
1862
+ await (window.require('WAWebCollections')).NewsletterMetadataCollection.update(channel.id);
1862
1863
  }
1863
1864
 
1864
1865
  try {
1865
- await window.Store.ChannelUtils.changeNewsletterOwnerAction(channel, newOwner);
1866
+ await (window.require('WAWebChangeNewsletterOwnerAction')).changeNewsletterOwnerAction(channel, newOwner);
1866
1867
 
1867
1868
  if (options.shouldDismissSelfAsAdmin) {
1868
- const meContact = window.Store.ContactCollection.getMeContact();
1869
- meContact && (await window.Store.ChannelUtils.demoteNewsletterAdminAction(channel, meContact));
1869
+ const meContact = window.require('WAWebContactCollection').getMeContact();
1870
+ meContact && (await (window.require('WAWebNewsletterDemoteAdminJob')).demoteNewsletterAdminAction(channel, meContact));
1870
1871
  }
1871
1872
  } catch (error) {
1872
1873
  return false;
@@ -1893,23 +1894,26 @@ class Client extends EventEmitter {
1893
1894
  * 2 for POPULAR channels
1894
1895
  * 3 for NEW channels
1895
1896
  * @param {number} [searchOptions.limit = 50] The limit of found channels to be appear in the returnig result
1896
- * @returns {Promise<Array<Channel>|[]>} Returns an array of Channel objects or an empty array if no channels were found
1897
+ * @returns {Promise<Array<Channel>>} Returns an array of Channel objects or an empty array if no channels were found
1897
1898
  */
1898
1899
  async searchChannels(searchOptions = {}) {
1899
1900
  return await this.pupPage.evaluate(async ({
1900
1901
  searchText = '',
1901
- countryCodes = [window.Store.ChannelUtils.currentRegion],
1902
+ countryCodes = [],
1902
1903
  skipSubscribedNewsletters = false,
1903
1904
  view = 0,
1904
1905
  limit = 50
1905
1906
  }) => {
1906
1907
  searchText = searchText.trim();
1907
- const currentRegion = window.Store.ChannelUtils.currentRegion;
1908
+ const currentRegion = window.require('WAWebL10N').getRegion();
1909
+ if (countryCodes.length === 0) countryCodes[0] = currentRegion;
1908
1910
  if (![0, 1, 2, 3].includes(view)) view = 0;
1909
1911
 
1912
+ const { countryCodesIso } = window.require('WAWebCountriesNativeCountryNames');
1913
+
1910
1914
  countryCodes = countryCodes.length === 1 && countryCodes[0] === currentRegion
1911
1915
  ? countryCodes
1912
- : countryCodes.filter((code) => Object.keys(window.Store.ChannelUtils.countryCodesIso).includes(code));
1916
+ : countryCodes.filter((code) => Object.keys(countryCodesIso).includes(code));
1913
1917
 
1914
1918
  const viewTypeMapping = {
1915
1919
  0: 'RECOMMENDED',
@@ -1927,12 +1931,12 @@ class Client extends EventEmitter {
1927
1931
  cursorToken: ''
1928
1932
  };
1929
1933
 
1930
- const originalFunction = window.Store.ChannelUtils.getNewsletterDirectoryPageSize;
1931
- limit !== 50 && (window.Store.ChannelUtils.getNewsletterDirectoryPageSize = () => limit);
1934
+ const originalFunction = window.require('WAWebNewsletterGatingUtils').getNewsletterDirectoryPageSize;
1935
+ limit !== 50 && (window.require('WAWebNewsletterGatingUtils').getNewsletterDirectoryPageSize = () => limit);
1932
1936
 
1933
- const channels = (await window.Store.ChannelUtils.fetchNewsletterDirectories(searchOptions)).newsletters;
1937
+ const channels = (await (window.require('WAWebNewsletterDirectorySearchAction')).fetchNewsletterDirectories(searchOptions)).newsletters;
1934
1938
 
1935
- limit !== 50 && (window.Store.ChannelUtils.getNewsletterDirectoryPageSize = originalFunction);
1939
+ limit !== 50 && (window.require('WAWebNewsletterGatingUtils').getNewsletterDirectoryPageSize = originalFunction);
1936
1940
 
1937
1941
  return channels
1938
1942
  ? await Promise.all(channels.map((channel) => window.WWebJS.getChatModel(channel, { isChannel: true })))
@@ -1946,11 +1950,11 @@ class Client extends EventEmitter {
1946
1950
  * @returns {Promise<boolean>} Returns true if the operation completed successfully, false otherwise
1947
1951
  */
1948
1952
  async deleteChannel(channelId) {
1949
- return await this.client.pupPage.evaluate(async (channelId) => {
1953
+ return await this.pupPage.evaluate(async (channelId) => {
1950
1954
  const channel = await window.WWebJS.getChat(channelId, { getAsModel: false });
1951
1955
  if (!channel) return false;
1952
1956
  try {
1953
- await window.Store.ChannelUtils.deleteNewsletterAction(channel);
1957
+ await (window.require('WAWebNewsletterDeleteAction')).deleteNewsletterAction(channel);
1954
1958
  return true;
1955
1959
  } catch (err) {
1956
1960
  if (err.name === 'ServerStatusCodeError') return false;
@@ -1970,7 +1974,7 @@ class Client extends EventEmitter {
1970
1974
 
1971
1975
  return labels.map(data => new Label(this, data));
1972
1976
  }
1973
-
1977
+
1974
1978
  /**
1975
1979
  * Get all current Broadcast
1976
1980
  * @returns {Promise<Array<Broadcast>>}
@@ -1982,6 +1986,49 @@ class Client extends EventEmitter {
1982
1986
  return broadcasts.map(data => new Broadcast(this, data));
1983
1987
  }
1984
1988
 
1989
+ /**
1990
+ * Get broadcast instance by current user ID
1991
+ * @param {string} contactId
1992
+ * @returns {Promise<Broadcast>}
1993
+ */
1994
+ async getBroadcastById(contactId) {
1995
+ const broadcast = await this.pupPage.evaluate(async (userId) => {
1996
+ let status;
1997
+ try {
1998
+ status = (window.require('WAWebCollections')).Status.get(userId);
1999
+ if (!status) {
2000
+ status = await (window.require('WAWebCollections')).Status.find(userId);
2001
+ }
2002
+ } catch {
2003
+ status = null;
2004
+ }
2005
+
2006
+ if (status) return window.WWebJS.getStatusModel(status);
2007
+ }, contactId);
2008
+ return new Broadcast(this, broadcast);
2009
+ }
2010
+
2011
+ /**
2012
+ * Revoke current own status messages
2013
+ * @param {string} messageId
2014
+ * @returns {Promise<void>}
2015
+ */
2016
+ async revokeStatusMessage(messageId) {
2017
+ return await this.pupPage.evaluate(async (msgId) => {
2018
+ const status = (window.require('WAWebCollections')).Status.getMyStatus();
2019
+ if (!status) return;
2020
+
2021
+ const msg =
2022
+ (window.require('WAWebCollections')).Msg.get(msgId) || (await (window.require('WAWebCollections')).Msg.getMessagesById([msgId]))?.messages?.[0];
2023
+ if (!msg) return;
2024
+
2025
+ if (!msg.id.fromMe || !msg.id.remote.isStatus())
2026
+ throw 'Invalid usage! Can only revoke the message its from own status broadcast';
2027
+
2028
+ return await (window.require('WAWebRevokeStatusAction')).sendStatusRevokeMsgAction(status, msg);
2029
+ }, messageId);
2030
+ }
2031
+
1985
2032
  /**
1986
2033
  * Get Label instance by ID
1987
2034
  * @param {string} labelId
@@ -2015,7 +2062,7 @@ class Client extends EventEmitter {
2015
2062
  */
2016
2063
  async getChatsByLabelId(labelId) {
2017
2064
  const chatIds = await this.pupPage.evaluate(async (labelId) => {
2018
- const label = window.Store.Label.get(labelId);
2065
+ const label = (window.require('WAWebCollections')).Label.get(labelId);
2019
2066
  const labelItems = label.labelItemCollection.getModelsArray();
2020
2067
  return labelItems.reduce((result, item) => {
2021
2068
  if (item.parentType === 'Chat') {
@@ -2034,7 +2081,7 @@ class Client extends EventEmitter {
2034
2081
  */
2035
2082
  async getBlockedContacts() {
2036
2083
  const blockedContacts = await this.pupPage.evaluate(() => {
2037
- let chatIds = window.Store.Blocklist.getModelsArray().map(a => a.id._serialized);
2084
+ let chatIds = (window.require('WAWebCollections')).Blocklist.getModelsArray().map(a => a.id._serialized);
2038
2085
  return Promise.all(chatIds.map(id => window.WWebJS.getContact(id)));
2039
2086
  });
2040
2087
 
@@ -2075,11 +2122,11 @@ class Client extends EventEmitter {
2075
2122
  async addOrRemoveLabels(labelIds, chatIds) {
2076
2123
 
2077
2124
  return this.pupPage.evaluate(async (labelIds, chatIds) => {
2078
- if (['smba', 'smbi'].indexOf(window.Store.Conn.platform) === -1) {
2125
+ if (['smba', 'smbi'].indexOf((window.require('WAWebConnModel').Conn).platform) === -1) {
2079
2126
  throw '[LT01] Only Whatsapp business';
2080
2127
  }
2081
2128
  const labels = window.WWebJS.getLabels().filter(e => labelIds.find(l => l == e.id) !== undefined);
2082
- const chats = window.Store.Chat.filter(e => chatIds.includes(e.id._serialized));
2129
+ const chats = (window.require('WAWebCollections')).Chat.filter(e => chatIds.includes(e.id._serialized));
2083
2130
 
2084
2131
  let actions = labels.map(label => ({id: label.id, type: 'add'}));
2085
2132
 
@@ -2091,7 +2138,7 @@ class Client extends EventEmitter {
2091
2138
  });
2092
2139
  });
2093
2140
 
2094
- return await window.Store.Label.addOrRemoveLabels(actions, chats);
2141
+ return await (window.require('WAWebCollections')).Label.addOrRemoveLabels(actions, chats);
2095
2142
  }, labelIds, chatIds);
2096
2143
  }
2097
2144
 
@@ -2112,8 +2159,8 @@ class Client extends EventEmitter {
2112
2159
  */
2113
2160
  async getGroupMembershipRequests(groupId) {
2114
2161
  return await this.pupPage.evaluate(async (groupId) => {
2115
- const groupWid = window.Store.WidFactory.createWid(groupId);
2116
- return await window.Store.MembershipRequestUtils.getMembershipApprovalRequests(groupWid);
2162
+ const groupWid = window.require('WAWebWidFactory').createWid(groupId);
2163
+ return await (window.require('WAWebApiMembershipApprovalRequestStore')).getMembershipApprovalRequests(groupWid);
2117
2164
  }, groupId);
2118
2165
  }
2119
2166
 
@@ -2165,11 +2212,11 @@ class Client extends EventEmitter {
2165
2212
  */
2166
2213
  async setAutoDownloadAudio(flag) {
2167
2214
  await this.pupPage.evaluate(async flag => {
2168
- const autoDownload = window.Store.Settings.getAutoDownloadAudio();
2215
+ const autoDownload = (window.require('WAWebUserPrefsGeneral')).getAutoDownloadAudio();
2169
2216
  if (autoDownload === flag) {
2170
2217
  return flag;
2171
2218
  }
2172
- await window.Store.Settings.setAutoDownloadAudio(flag);
2219
+ await (window.require('WAWebUserPrefsGeneral')).setAutoDownloadAudio(flag);
2173
2220
  return flag;
2174
2221
  }, flag);
2175
2222
  }
@@ -2180,11 +2227,11 @@ class Client extends EventEmitter {
2180
2227
  */
2181
2228
  async setAutoDownloadDocuments(flag) {
2182
2229
  await this.pupPage.evaluate(async flag => {
2183
- const autoDownload = window.Store.Settings.getAutoDownloadDocuments();
2230
+ const autoDownload = (window.require('WAWebUserPrefsGeneral')).getAutoDownloadDocuments();
2184
2231
  if (autoDownload === flag) {
2185
2232
  return flag;
2186
2233
  }
2187
- await window.Store.Settings.setAutoDownloadDocuments(flag);
2234
+ await (window.require('WAWebUserPrefsGeneral')).setAutoDownloadDocuments(flag);
2188
2235
  return flag;
2189
2236
  }, flag);
2190
2237
  }
@@ -2195,11 +2242,11 @@ class Client extends EventEmitter {
2195
2242
  */
2196
2243
  async setAutoDownloadPhotos(flag) {
2197
2244
  await this.pupPage.evaluate(async flag => {
2198
- const autoDownload = window.Store.Settings.getAutoDownloadPhotos();
2245
+ const autoDownload = (window.require('WAWebUserPrefsGeneral')).getAutoDownloadPhotos();
2199
2246
  if (autoDownload === flag) {
2200
2247
  return flag;
2201
2248
  }
2202
- await window.Store.Settings.setAutoDownloadPhotos(flag);
2249
+ await (window.require('WAWebUserPrefsGeneral')).setAutoDownloadPhotos(flag);
2203
2250
  return flag;
2204
2251
  }, flag);
2205
2252
  }
@@ -2210,11 +2257,11 @@ class Client extends EventEmitter {
2210
2257
  */
2211
2258
  async setAutoDownloadVideos(flag) {
2212
2259
  await this.pupPage.evaluate(async flag => {
2213
- const autoDownload = window.Store.Settings.getAutoDownloadVideos();
2260
+ const autoDownload = (window.require('WAWebUserPrefsGeneral')).getAutoDownloadVideos();
2214
2261
  if (autoDownload === flag) {
2215
2262
  return flag;
2216
2263
  }
2217
- await window.Store.Settings.setAutoDownloadVideos(flag);
2264
+ await (window.require('WAWebUserPrefsGeneral')).setAutoDownloadVideos(flag);
2218
2265
  return flag;
2219
2266
  }, flag);
2220
2267
  }
@@ -2227,11 +2274,11 @@ class Client extends EventEmitter {
2227
2274
  */
2228
2275
  async setBackgroundSync(flag) {
2229
2276
  return await this.pupPage.evaluate(async flag => {
2230
- const backSync = window.Store.Settings.getGlobalOfflineNotifications();
2277
+ const backSync = (window.require('WAWebUserPrefsNotifications')).getGlobalOfflineNotifications();
2231
2278
  if (backSync === flag) {
2232
2279
  return flag;
2233
2280
  }
2234
- await window.Store.Settings.setGlobalOfflineNotifications(flag);
2281
+ await (window.require('WAWebUserPrefsNotifications')).setGlobalOfflineNotifications(flag);
2235
2282
  return flag;
2236
2283
  }, flag);
2237
2284
  }
@@ -2245,7 +2292,7 @@ class Client extends EventEmitter {
2245
2292
  */
2246
2293
  async getContactDeviceCount(userId) {
2247
2294
  return await this.pupPage.evaluate(async (userId) => {
2248
- const devices = await window.Store.DeviceList.getDeviceIds([window.Store.WidFactory.createWid(userId)]);
2295
+ const devices = await (window.require('WAWebApiDeviceList')).getDeviceIds([window.require('WAWebWidFactory').createWid(userId)]);
2249
2296
  if (devices && devices.length && devices[0] != null && typeof devices[0].devices == 'object') {
2250
2297
  return devices[0].devices.length;
2251
2298
  }
@@ -2260,10 +2307,10 @@ class Client extends EventEmitter {
2260
2307
  */
2261
2308
  async syncHistory(chatId) {
2262
2309
  return await this.pupPage.evaluate(async (chatId) => {
2263
- const chatWid = window.Store.WidFactory.createWid(chatId);
2264
- const chat = window.Store.Chat.get(chatWid) ?? (await window.Store.Chat.find(chatWid));
2310
+ const chatWid = window.require('WAWebWidFactory').createWid(chatId);
2311
+ const chat = (window.require('WAWebCollections')).Chat.get(chatWid) ?? (await (window.require('WAWebCollections')).Chat.find(chatWid));
2265
2312
  if (chat?.endOfHistoryTransferType === 0) {
2266
- await window.Store.HistorySync.sendPeerDataOperationRequest(3, {
2313
+ await (window.require('WAWebSendNonMessageDataRequest')).sendPeerDataOperationRequest(3, {
2267
2314
  chatId: chat.id
2268
2315
  });
2269
2316
  return true;
@@ -2288,7 +2335,7 @@ class Client extends EventEmitter {
2288
2335
  startTime = Math.floor(startTime.getTime() / 1000);
2289
2336
 
2290
2337
  return await this.pupPage.evaluate(async (startTimeTs, callType) => {
2291
- const response = await window.Store.ScheduledEventMsgUtils.createEventCallLink(startTimeTs, callType);
2338
+ const response = await (window.require('WAWebGenerateEventCallLink')).createEventCallLink(startTimeTs, callType);
2292
2339
  return response ?? '';
2293
2340
  }, startTime, callType);
2294
2341
  }
@@ -2303,10 +2350,10 @@ class Client extends EventEmitter {
2303
2350
  if (![0, 1, 2, 3].includes(response)) return false;
2304
2351
 
2305
2352
  return await this.pupPage.evaluate(async (response, msgId) => {
2306
- const eventMsg = window.Store.Msg.get(msgId) || (await window.Store.Msg.getMessagesById([msgId]))?.messages?.[0];
2353
+ const eventMsg = (window.require('WAWebCollections')).Msg.get(msgId) || (await (window.require('WAWebCollections')).Msg.getMessagesById([msgId]))?.messages?.[0];
2307
2354
  if (!eventMsg) return false;
2308
2355
 
2309
- await window.Store.ScheduledEventMsgUtils.sendEventResponseMsg(response, eventMsg);
2356
+ await (window.require('WAWebSendEventResponseMsgAction')).sendEventResponseMsg(response, eventMsg);
2310
2357
  return true;
2311
2358
  }, response, eventMessageId);
2312
2359
  }
@@ -2322,15 +2369,14 @@ class Client extends EventEmitter {
2322
2369
  async saveOrEditAddressbookContact(phoneNumber, firstName, lastName, syncToAddressbook = false)
2323
2370
  {
2324
2371
  return await this.pupPage.evaluate(async (phoneNumber, firstName, lastName, syncToAddressbook) => {
2325
- return await window.Store.AddressbookContactUtils.saveContactAction(
2326
- phoneNumber,
2327
- phoneNumber,
2328
- null,
2329
- null,
2330
- firstName,
2331
- lastName,
2332
- syncToAddressbook
2333
- );
2372
+ return await (window.require('WAWebSaveContactAction')).saveContactAction({
2373
+ 'firstName' : firstName,
2374
+ 'lastName' : lastName,
2375
+ 'phoneNumber' : phoneNumber,
2376
+ 'prevPhoneNumber' : phoneNumber,
2377
+ 'syncToAddressbook': syncToAddressbook,
2378
+ 'username' : undefined
2379
+ });
2334
2380
  }, phoneNumber, firstName, lastName, syncToAddressbook);
2335
2381
  }
2336
2382
 
@@ -2342,7 +2388,8 @@ class Client extends EventEmitter {
2342
2388
  async deleteAddressbookContact(phoneNumber)
2343
2389
  {
2344
2390
  return await this.pupPage.evaluate(async (phoneNumber) => {
2345
- return await window.Store.AddressbookContactUtils.deleteContactAction(phoneNumber);
2391
+ const wid = window.require('WAWebWidFactory').createWid(phoneNumber);
2392
+ return await (window.require('WAWebDeleteContactAction')).deleteContactAction({phoneNumber: wid});
2346
2393
  }, phoneNumber);
2347
2394
  }
2348
2395
 
@@ -2375,11 +2422,11 @@ class Client extends EventEmitter {
2375
2422
  */
2376
2423
  async addOrEditCustomerNote(userId, note) {
2377
2424
  return await this.pupPage.evaluate(async (userId, note) => {
2378
- if (!window.Store.BusinessGatingUtils.smbNotesV1Enabled()) return;
2425
+ if (!(window.require('WAWebBizGatingUtils')).smbNotesV1Enabled()) return;
2379
2426
 
2380
- return window.Store.CustomerNoteUtils.noteAddAction(
2427
+ return (window.require('WAWebNoteAction')).noteAddAction(
2381
2428
  'unstructured',
2382
- window.Store.WidToJid.widToUserJid(window.Store.WidFactory.createWid(userId)),
2429
+ window.require('WAWebWidToJid').widToUserJid(window.require('WAWebWidFactory').createWid(userId)),
2383
2430
  note
2384
2431
  );
2385
2432
  }, userId, note);
@@ -2400,17 +2447,17 @@ class Client extends EventEmitter {
2400
2447
  */
2401
2448
  async getCustomerNote(userId) {
2402
2449
  return await this.pupPage.evaluate(async (userId) => {
2403
- if (!window.Store.BusinessGatingUtils.smbNotesV1Enabled()) return null;
2450
+ if (!(window.require('WAWebBizGatingUtils')).smbNotesV1Enabled()) return null;
2404
2451
 
2405
- const note = await window.Store.CustomerNoteUtils.retrieveOnlyNoteForChatJid(
2406
- window.Store.WidToJid.widToUserJid(window.Store.WidFactory.createWid(userId))
2452
+ const note = await (window.require('WAWebNoteAction')).retrieveOnlyNoteForChatJid(
2453
+ window.require('WAWebWidToJid').widToUserJid(window.require('WAWebWidFactory').createWid(userId))
2407
2454
  );
2408
2455
 
2409
2456
  let serialized = note?.serialize();
2410
2457
 
2411
2458
  if (!serialized) return null;
2412
2459
 
2413
- serialized.chatId = window.Store.JidToWid.userJidToUserWid(serialized.chatJid)._serialized;
2460
+ serialized.chatId = window.require('WAWebJidToWid').userJidToUserWid(serialized.chatJid)._serialized;
2414
2461
  delete serialized.chatJid;
2415
2462
 
2416
2463
  return serialized;
@@ -2428,8 +2475,8 @@ class Client extends EventEmitter {
2428
2475
  if (msg.type != MessageTypes.POLL_CREATION) throw 'Invalid usage! Can only be used with a pollCreation message';
2429
2476
 
2430
2477
  const pollVotes = await this.pupPage.evaluate( async (msg) => {
2431
- const msgKey = window.Store.MsgKey.fromString(msg.id._serialized);
2432
- let pollVotes = await window.Store.PollsVotesSchema.getTable().equals(['parentMsgKey'], msgKey.toString());
2478
+ const msgKey = (window.require('WAWebMsgKey')).fromString(msg.id._serialized);
2479
+ let pollVotes = await (window.require('WAWebPollsVotesSchema')).getTable().equals(['parentMsgKey'], msgKey.toString());
2433
2480
 
2434
2481
  return pollVotes.map(item => {
2435
2482
  const typedArray = new Uint8Array(item.selectedOptionLocalIds);