@pney/whatsapp-web 1.34.4 → 1.34.6-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,11 @@ 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
+ const chat = await window.WWebJS.getChat(contactId, { getAsModel: false });
1515
+ return window.WWebJS.compareWwebVersions(window.Debug.VERSION, '<', '2.3000.0')
1516
+ ? await window.require('WAWebContactProfilePicThumbBridge').profilePicFind(chatWid)
1517
+ : await window.require('WAWebContactProfilePicThumbBridge').requestProfilePicFromServer(chat);
1516
1518
  } catch (err) {
1517
1519
  if(err.name === 'ServerStatusCodeError') return undefined;
1518
1520
  throw err;
@@ -1529,17 +1531,17 @@ class Client extends EventEmitter {
1529
1531
  */
1530
1532
  async getCommonGroups(contactId) {
1531
1533
  const commonGroups = await this.pupPage.evaluate(async (contactId) => {
1532
- let contact = window.Store.Contact.get(contactId);
1534
+ let contact = (window.require('WAWebCollections')).Contact.get(contactId);
1533
1535
  if (!contact) {
1534
- const wid = window.Store.WidFactory.createWid(contactId);
1535
- const chatConstructor = window.Store.Contact.getModelsArray().find(c=>!c.isGroup).constructor;
1536
+ const wid = window.require('WAWebWidFactory').createWid(contactId);
1537
+ const chatConstructor = (window.require('WAWebCollections')).Contact.getModelsArray().find(c=>!c.isGroup).constructor;
1536
1538
  contact = new chatConstructor({id: wid});
1537
1539
  }
1538
1540
 
1539
1541
  if (contact.commonGroups) {
1540
1542
  return contact.commonGroups.serialize();
1541
1543
  }
1542
- const status = await window.Store.findCommonGroups(contact);
1544
+ const status = await (window.require('WAWebFindCommonGroupsContactAction').findCommonGroups)(contact);
1543
1545
  if (status) {
1544
1546
  return contact.commonGroups.serialize();
1545
1547
  }
@@ -1557,7 +1559,7 @@ class Client extends EventEmitter {
1557
1559
  */
1558
1560
  async resetState() {
1559
1561
  await this.pupPage.evaluate(() => {
1560
- window.Store.AppState.reconnect();
1562
+ window.require('WAWebSocketModel').Socket.reconnect();
1561
1563
  });
1562
1564
  }
1563
1565
 
@@ -1582,8 +1584,8 @@ class Client extends EventEmitter {
1582
1584
  }
1583
1585
 
1584
1586
  return await this.pupPage.evaluate(async number => {
1585
- const wid = window.Store.WidFactory.createWid(number);
1586
- const result = await window.Store.QueryExist(wid);
1587
+ const wid = window.require('WAWebWidFactory').createWid(number);
1588
+ const result = await (window.require('WAWebQueryExistsJob').queryWidExists)(wid);
1587
1589
  if (!result || result.wid === undefined) return null;
1588
1590
  return result.wid;
1589
1591
  }, number);
@@ -1599,7 +1601,7 @@ class Client extends EventEmitter {
1599
1601
  if (!number.includes('@s.whatsapp.net')) number = `${number}@s.whatsapp.net`;
1600
1602
 
1601
1603
  return await this.pupPage.evaluate(async numberId => {
1602
- return window.Store.NumberInfo.formattedPhoneNumber(numberId);
1604
+ return window.require('WAWebPhoneUtils').formattedPhoneNumber(numberId);
1603
1605
  }, number);
1604
1606
  }
1605
1607
 
@@ -1612,7 +1614,7 @@ class Client extends EventEmitter {
1612
1614
  number = number.replace(' ', '').replace('+', '').replace('@c.us', '');
1613
1615
 
1614
1616
  return await this.pupPage.evaluate(async numberId => {
1615
- return window.Store.NumberInfo.findCC(numberId);
1617
+ return window.require('WAPhoneFindCC').findCC(numberId);
1616
1618
  }, number);
1617
1619
  }
1618
1620
 
@@ -1678,17 +1680,17 @@ class Client extends EventEmitter {
1678
1680
  };
1679
1681
 
1680
1682
  for (const participant of participants) {
1681
- const pWid = window.Store.WidFactory.createWid(participant);
1682
- if ((await window.Store.QueryExist(pWid))?.wid) {
1683
+ const pWid = window.require('WAWebWidFactory').createWid(participant);
1684
+ if ((await (window.require('WAWebQueryExistsJob').queryWidExists)(pWid))?.wid) {
1683
1685
  participantWids.push({ phoneNumber: pWid });
1684
1686
  }
1685
1687
  else failedParticipants.push(participant);
1686
1688
  }
1687
1689
 
1688
- parentGroupId && (parentGroupWid = window.Store.WidFactory.createWid(parentGroupId));
1690
+ parentGroupId && (parentGroupWid = window.require('WAWebWidFactory').createWid(parentGroupId));
1689
1691
 
1690
1692
  try {
1691
- createGroupResult = await window.Store.GroupUtils.createGroup(
1693
+ createGroupResult = await (window.require('WAWebGroupCreateJob')).createGroup(
1692
1694
  {
1693
1695
  'addressingModeOverride': 'lid',
1694
1696
  'memberAddMode': options.memberAddMode ?? false,
@@ -1707,14 +1709,14 @@ class Client extends EventEmitter {
1707
1709
 
1708
1710
  for (const participant of createGroupResult.participants) {
1709
1711
  let isInviteV4Sent = false;
1710
- participant.wid.server == 'lid' && (participant.wid = window.Store.LidUtils.getPhoneNumber(participant.wid));
1712
+ participant.wid.server == 'lid' && (participant.wid = window.require('WAWebApiContact').getPhoneNumber(participant.wid));
1711
1713
  const participantId = participant.wid._serialized;
1712
1714
  const statusCode = participant.error || 200;
1713
1715
 
1714
1716
  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),
1717
+ (window.require('WAWebCollections')).Contact.gadd(participant.wid, { silent: true });
1718
+ const addParticipantResult = await (window.require('WAWebChatSendMessages')).sendGroupInviteMessage(
1719
+ (window.require('WAWebCollections')).Chat.get(participant.wid) || await (window.require('WAWebCollections')).Chat.find(participant.wid),
1718
1720
  createGroupResult.wid._serialized,
1719
1721
  createGroupResult.subject,
1720
1722
  participant.invite_code,
@@ -1775,7 +1777,7 @@ class Client extends EventEmitter {
1775
1777
  return await this.pupPage.evaluate(async (title, options) => {
1776
1778
  let response, { description = null, picture = null } = options;
1777
1779
 
1778
- if (!window.Store.ChannelUtils.isNewsletterCreationEnabled()) {
1780
+ if (!(window.require('WAWebNewsletterGatingUtils')).isNewsletterCreationEnabled()) {
1779
1781
  return 'CreateChannelError: A channel creation is not enabled';
1780
1782
  }
1781
1783
 
@@ -1789,7 +1791,7 @@ class Client extends EventEmitter {
1789
1791
  }
1790
1792
 
1791
1793
  try {
1792
- response = await window.Store.ChannelUtils.createNewsletterQuery({
1794
+ response = await (window.require('WAWebNewsletterCreateQueryJob')).createNewsletterQuery({
1793
1795
  name: title,
1794
1796
  description: description,
1795
1797
  picture: picture,
@@ -1803,7 +1805,7 @@ class Client extends EventEmitter {
1803
1805
 
1804
1806
  return {
1805
1807
  title: title,
1806
- nid: window.Store.JidToWid.newsletterJidToWid(response.idJid),
1808
+ nid: window.require('WAWebJidToWid').newsletterJidToWid(response.idJid),
1807
1809
  inviteLink: `https://whatsapp.com/channel/${response.newsletterInviteLinkMetadataMixin.inviteCode}`,
1808
1810
  createdAtTs: response.newsletterCreationTimeMetadataMixin.creationTimeValue
1809
1811
  };
@@ -1856,17 +1858,17 @@ class Client extends EventEmitter {
1856
1858
  async transferChannelOwnership(channelId, newOwnerId, options = {}) {
1857
1859
  return await this.pupPage.evaluate(async (channelId, newOwnerId, options) => {
1858
1860
  const channel = await window.WWebJS.getChat(channelId, { getAsModel: false });
1859
- const newOwner = window.Store.Contact.get(newOwnerId) || (await window.Store.Contact.find(newOwnerId));
1861
+ const newOwner = (window.require('WAWebCollections')).Contact.get(newOwnerId) || (await (window.require('WAWebCollections')).Contact.find(newOwnerId));
1860
1862
  if (!channel.newsletterMetadata) {
1861
- await window.Store.NewsletterMetadataCollection.update(channel.id);
1863
+ await (window.require('WAWebCollections')).NewsletterMetadataCollection.update(channel.id);
1862
1864
  }
1863
1865
 
1864
1866
  try {
1865
- await window.Store.ChannelUtils.changeNewsletterOwnerAction(channel, newOwner);
1867
+ await (window.require('WAWebChangeNewsletterOwnerAction')).changeNewsletterOwnerAction(channel, newOwner);
1866
1868
 
1867
1869
  if (options.shouldDismissSelfAsAdmin) {
1868
- const meContact = window.Store.ContactCollection.getMeContact();
1869
- meContact && (await window.Store.ChannelUtils.demoteNewsletterAdminAction(channel, meContact));
1870
+ const meContact = window.require('WAWebContactCollection').getMeContact();
1871
+ meContact && (await (window.require('WAWebNewsletterDemoteAdminJob')).demoteNewsletterAdminAction(channel, meContact));
1870
1872
  }
1871
1873
  } catch (error) {
1872
1874
  return false;
@@ -1893,23 +1895,26 @@ class Client extends EventEmitter {
1893
1895
  * 2 for POPULAR channels
1894
1896
  * 3 for NEW channels
1895
1897
  * @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
1898
+ * @returns {Promise<Array<Channel>>} Returns an array of Channel objects or an empty array if no channels were found
1897
1899
  */
1898
1900
  async searchChannels(searchOptions = {}) {
1899
1901
  return await this.pupPage.evaluate(async ({
1900
1902
  searchText = '',
1901
- countryCodes = [window.Store.ChannelUtils.currentRegion],
1903
+ countryCodes = [],
1902
1904
  skipSubscribedNewsletters = false,
1903
1905
  view = 0,
1904
1906
  limit = 50
1905
1907
  }) => {
1906
1908
  searchText = searchText.trim();
1907
- const currentRegion = window.Store.ChannelUtils.currentRegion;
1909
+ const currentRegion = window.require('WAWebL10N').getRegion();
1910
+ if (countryCodes.length === 0) countryCodes[0] = currentRegion;
1908
1911
  if (![0, 1, 2, 3].includes(view)) view = 0;
1909
1912
 
1913
+ const { countryCodesIso } = window.require('WAWebCountriesNativeCountryNames');
1914
+
1910
1915
  countryCodes = countryCodes.length === 1 && countryCodes[0] === currentRegion
1911
1916
  ? countryCodes
1912
- : countryCodes.filter((code) => Object.keys(window.Store.ChannelUtils.countryCodesIso).includes(code));
1917
+ : countryCodes.filter((code) => Object.keys(countryCodesIso).includes(code));
1913
1918
 
1914
1919
  const viewTypeMapping = {
1915
1920
  0: 'RECOMMENDED',
@@ -1927,12 +1932,12 @@ class Client extends EventEmitter {
1927
1932
  cursorToken: ''
1928
1933
  };
1929
1934
 
1930
- const originalFunction = window.Store.ChannelUtils.getNewsletterDirectoryPageSize;
1931
- limit !== 50 && (window.Store.ChannelUtils.getNewsletterDirectoryPageSize = () => limit);
1935
+ const originalFunction = window.require('WAWebNewsletterGatingUtils').getNewsletterDirectoryPageSize;
1936
+ limit !== 50 && (window.require('WAWebNewsletterGatingUtils').getNewsletterDirectoryPageSize = () => limit);
1932
1937
 
1933
- const channels = (await window.Store.ChannelUtils.fetchNewsletterDirectories(searchOptions)).newsletters;
1938
+ const channels = (await (window.require('WAWebNewsletterDirectorySearchAction')).fetchNewsletterDirectories(searchOptions)).newsletters;
1934
1939
 
1935
- limit !== 50 && (window.Store.ChannelUtils.getNewsletterDirectoryPageSize = originalFunction);
1940
+ limit !== 50 && (window.require('WAWebNewsletterGatingUtils').getNewsletterDirectoryPageSize = originalFunction);
1936
1941
 
1937
1942
  return channels
1938
1943
  ? await Promise.all(channels.map((channel) => window.WWebJS.getChatModel(channel, { isChannel: true })))
@@ -1946,11 +1951,11 @@ class Client extends EventEmitter {
1946
1951
  * @returns {Promise<boolean>} Returns true if the operation completed successfully, false otherwise
1947
1952
  */
1948
1953
  async deleteChannel(channelId) {
1949
- return await this.client.pupPage.evaluate(async (channelId) => {
1954
+ return await this.pupPage.evaluate(async (channelId) => {
1950
1955
  const channel = await window.WWebJS.getChat(channelId, { getAsModel: false });
1951
1956
  if (!channel) return false;
1952
1957
  try {
1953
- await window.Store.ChannelUtils.deleteNewsletterAction(channel);
1958
+ await (window.require('WAWebNewsletterDeleteAction')).deleteNewsletterAction(channel);
1954
1959
  return true;
1955
1960
  } catch (err) {
1956
1961
  if (err.name === 'ServerStatusCodeError') return false;
@@ -1970,7 +1975,7 @@ class Client extends EventEmitter {
1970
1975
 
1971
1976
  return labels.map(data => new Label(this, data));
1972
1977
  }
1973
-
1978
+
1974
1979
  /**
1975
1980
  * Get all current Broadcast
1976
1981
  * @returns {Promise<Array<Broadcast>>}
@@ -1982,6 +1987,49 @@ class Client extends EventEmitter {
1982
1987
  return broadcasts.map(data => new Broadcast(this, data));
1983
1988
  }
1984
1989
 
1990
+ /**
1991
+ * Get broadcast instance by current user ID
1992
+ * @param {string} contactId
1993
+ * @returns {Promise<Broadcast>}
1994
+ */
1995
+ async getBroadcastById(contactId) {
1996
+ const broadcast = await this.pupPage.evaluate(async (userId) => {
1997
+ let status;
1998
+ try {
1999
+ status = (window.require('WAWebCollections')).Status.get(userId);
2000
+ if (!status) {
2001
+ status = await (window.require('WAWebCollections')).Status.find(userId);
2002
+ }
2003
+ } catch {
2004
+ status = null;
2005
+ }
2006
+
2007
+ if (status) return window.WWebJS.getStatusModel(status);
2008
+ }, contactId);
2009
+ return new Broadcast(this, broadcast);
2010
+ }
2011
+
2012
+ /**
2013
+ * Revoke current own status messages
2014
+ * @param {string} messageId
2015
+ * @returns {Promise<void>}
2016
+ */
2017
+ async revokeStatusMessage(messageId) {
2018
+ return await this.pupPage.evaluate(async (msgId) => {
2019
+ const status = (window.require('WAWebCollections')).Status.getMyStatus();
2020
+ if (!status) return;
2021
+
2022
+ const msg =
2023
+ (window.require('WAWebCollections')).Msg.get(msgId) || (await (window.require('WAWebCollections')).Msg.getMessagesById([msgId]))?.messages?.[0];
2024
+ if (!msg) return;
2025
+
2026
+ if (!msg.id.fromMe || !msg.id.remote.isStatus())
2027
+ throw 'Invalid usage! Can only revoke the message its from own status broadcast';
2028
+
2029
+ return await (window.require('WAWebRevokeStatusAction')).sendStatusRevokeMsgAction(status, msg);
2030
+ }, messageId);
2031
+ }
2032
+
1985
2033
  /**
1986
2034
  * Get Label instance by ID
1987
2035
  * @param {string} labelId
@@ -2015,7 +2063,7 @@ class Client extends EventEmitter {
2015
2063
  */
2016
2064
  async getChatsByLabelId(labelId) {
2017
2065
  const chatIds = await this.pupPage.evaluate(async (labelId) => {
2018
- const label = window.Store.Label.get(labelId);
2066
+ const label = (window.require('WAWebCollections')).Label.get(labelId);
2019
2067
  const labelItems = label.labelItemCollection.getModelsArray();
2020
2068
  return labelItems.reduce((result, item) => {
2021
2069
  if (item.parentType === 'Chat') {
@@ -2034,7 +2082,7 @@ class Client extends EventEmitter {
2034
2082
  */
2035
2083
  async getBlockedContacts() {
2036
2084
  const blockedContacts = await this.pupPage.evaluate(() => {
2037
- let chatIds = window.Store.Blocklist.getModelsArray().map(a => a.id._serialized);
2085
+ let chatIds = (window.require('WAWebCollections')).Blocklist.getModelsArray().map(a => a.id._serialized);
2038
2086
  return Promise.all(chatIds.map(id => window.WWebJS.getContact(id)));
2039
2087
  });
2040
2088
 
@@ -2075,11 +2123,11 @@ class Client extends EventEmitter {
2075
2123
  async addOrRemoveLabels(labelIds, chatIds) {
2076
2124
 
2077
2125
  return this.pupPage.evaluate(async (labelIds, chatIds) => {
2078
- if (['smba', 'smbi'].indexOf(window.Store.Conn.platform) === -1) {
2126
+ if (['smba', 'smbi'].indexOf((window.require('WAWebConnModel').Conn).platform) === -1) {
2079
2127
  throw '[LT01] Only Whatsapp business';
2080
2128
  }
2081
2129
  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));
2130
+ const chats = (window.require('WAWebCollections')).Chat.filter(e => chatIds.includes(e.id._serialized));
2083
2131
 
2084
2132
  let actions = labels.map(label => ({id: label.id, type: 'add'}));
2085
2133
 
@@ -2091,7 +2139,7 @@ class Client extends EventEmitter {
2091
2139
  });
2092
2140
  });
2093
2141
 
2094
- return await window.Store.Label.addOrRemoveLabels(actions, chats);
2142
+ return await (window.require('WAWebCollections')).Label.addOrRemoveLabels(actions, chats);
2095
2143
  }, labelIds, chatIds);
2096
2144
  }
2097
2145
 
@@ -2112,8 +2160,8 @@ class Client extends EventEmitter {
2112
2160
  */
2113
2161
  async getGroupMembershipRequests(groupId) {
2114
2162
  return await this.pupPage.evaluate(async (groupId) => {
2115
- const groupWid = window.Store.WidFactory.createWid(groupId);
2116
- return await window.Store.MembershipRequestUtils.getMembershipApprovalRequests(groupWid);
2163
+ const groupWid = window.require('WAWebWidFactory').createWid(groupId);
2164
+ return await (window.require('WAWebApiMembershipApprovalRequestStore')).getMembershipApprovalRequests(groupWid);
2117
2165
  }, groupId);
2118
2166
  }
2119
2167
 
@@ -2165,11 +2213,11 @@ class Client extends EventEmitter {
2165
2213
  */
2166
2214
  async setAutoDownloadAudio(flag) {
2167
2215
  await this.pupPage.evaluate(async flag => {
2168
- const autoDownload = window.Store.Settings.getAutoDownloadAudio();
2216
+ const autoDownload = (window.require('WAWebUserPrefsGeneral')).getAutoDownloadAudio();
2169
2217
  if (autoDownload === flag) {
2170
2218
  return flag;
2171
2219
  }
2172
- await window.Store.Settings.setAutoDownloadAudio(flag);
2220
+ await (window.require('WAWebUserPrefsGeneral')).setAutoDownloadAudio(flag);
2173
2221
  return flag;
2174
2222
  }, flag);
2175
2223
  }
@@ -2180,11 +2228,11 @@ class Client extends EventEmitter {
2180
2228
  */
2181
2229
  async setAutoDownloadDocuments(flag) {
2182
2230
  await this.pupPage.evaluate(async flag => {
2183
- const autoDownload = window.Store.Settings.getAutoDownloadDocuments();
2231
+ const autoDownload = (window.require('WAWebUserPrefsGeneral')).getAutoDownloadDocuments();
2184
2232
  if (autoDownload === flag) {
2185
2233
  return flag;
2186
2234
  }
2187
- await window.Store.Settings.setAutoDownloadDocuments(flag);
2235
+ await (window.require('WAWebUserPrefsGeneral')).setAutoDownloadDocuments(flag);
2188
2236
  return flag;
2189
2237
  }, flag);
2190
2238
  }
@@ -2195,11 +2243,11 @@ class Client extends EventEmitter {
2195
2243
  */
2196
2244
  async setAutoDownloadPhotos(flag) {
2197
2245
  await this.pupPage.evaluate(async flag => {
2198
- const autoDownload = window.Store.Settings.getAutoDownloadPhotos();
2246
+ const autoDownload = (window.require('WAWebUserPrefsGeneral')).getAutoDownloadPhotos();
2199
2247
  if (autoDownload === flag) {
2200
2248
  return flag;
2201
2249
  }
2202
- await window.Store.Settings.setAutoDownloadPhotos(flag);
2250
+ await (window.require('WAWebUserPrefsGeneral')).setAutoDownloadPhotos(flag);
2203
2251
  return flag;
2204
2252
  }, flag);
2205
2253
  }
@@ -2210,11 +2258,11 @@ class Client extends EventEmitter {
2210
2258
  */
2211
2259
  async setAutoDownloadVideos(flag) {
2212
2260
  await this.pupPage.evaluate(async flag => {
2213
- const autoDownload = window.Store.Settings.getAutoDownloadVideos();
2261
+ const autoDownload = (window.require('WAWebUserPrefsGeneral')).getAutoDownloadVideos();
2214
2262
  if (autoDownload === flag) {
2215
2263
  return flag;
2216
2264
  }
2217
- await window.Store.Settings.setAutoDownloadVideos(flag);
2265
+ await (window.require('WAWebUserPrefsGeneral')).setAutoDownloadVideos(flag);
2218
2266
  return flag;
2219
2267
  }, flag);
2220
2268
  }
@@ -2227,11 +2275,11 @@ class Client extends EventEmitter {
2227
2275
  */
2228
2276
  async setBackgroundSync(flag) {
2229
2277
  return await this.pupPage.evaluate(async flag => {
2230
- const backSync = window.Store.Settings.getGlobalOfflineNotifications();
2278
+ const backSync = (window.require('WAWebUserPrefsNotifications')).getGlobalOfflineNotifications();
2231
2279
  if (backSync === flag) {
2232
2280
  return flag;
2233
2281
  }
2234
- await window.Store.Settings.setGlobalOfflineNotifications(flag);
2282
+ await (window.require('WAWebUserPrefsNotifications')).setGlobalOfflineNotifications(flag);
2235
2283
  return flag;
2236
2284
  }, flag);
2237
2285
  }
@@ -2245,7 +2293,7 @@ class Client extends EventEmitter {
2245
2293
  */
2246
2294
  async getContactDeviceCount(userId) {
2247
2295
  return await this.pupPage.evaluate(async (userId) => {
2248
- const devices = await window.Store.DeviceList.getDeviceIds([window.Store.WidFactory.createWid(userId)]);
2296
+ const devices = await (window.require('WAWebApiDeviceList')).getDeviceIds([window.require('WAWebWidFactory').createWid(userId)]);
2249
2297
  if (devices && devices.length && devices[0] != null && typeof devices[0].devices == 'object') {
2250
2298
  return devices[0].devices.length;
2251
2299
  }
@@ -2260,10 +2308,10 @@ class Client extends EventEmitter {
2260
2308
  */
2261
2309
  async syncHistory(chatId) {
2262
2310
  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));
2311
+ const chatWid = window.require('WAWebWidFactory').createWid(chatId);
2312
+ const chat = (window.require('WAWebCollections')).Chat.get(chatWid) ?? (await (window.require('WAWebCollections')).Chat.find(chatWid));
2265
2313
  if (chat?.endOfHistoryTransferType === 0) {
2266
- await window.Store.HistorySync.sendPeerDataOperationRequest(3, {
2314
+ await (window.require('WAWebSendNonMessageDataRequest')).sendPeerDataOperationRequest(3, {
2267
2315
  chatId: chat.id
2268
2316
  });
2269
2317
  return true;
@@ -2288,7 +2336,7 @@ class Client extends EventEmitter {
2288
2336
  startTime = Math.floor(startTime.getTime() / 1000);
2289
2337
 
2290
2338
  return await this.pupPage.evaluate(async (startTimeTs, callType) => {
2291
- const response = await window.Store.ScheduledEventMsgUtils.createEventCallLink(startTimeTs, callType);
2339
+ const response = await (window.require('WAWebGenerateEventCallLink')).createEventCallLink(startTimeTs, callType);
2292
2340
  return response ?? '';
2293
2341
  }, startTime, callType);
2294
2342
  }
@@ -2303,10 +2351,10 @@ class Client extends EventEmitter {
2303
2351
  if (![0, 1, 2, 3].includes(response)) return false;
2304
2352
 
2305
2353
  return await this.pupPage.evaluate(async (response, msgId) => {
2306
- const eventMsg = window.Store.Msg.get(msgId) || (await window.Store.Msg.getMessagesById([msgId]))?.messages?.[0];
2354
+ const eventMsg = (window.require('WAWebCollections')).Msg.get(msgId) || (await (window.require('WAWebCollections')).Msg.getMessagesById([msgId]))?.messages?.[0];
2307
2355
  if (!eventMsg) return false;
2308
2356
 
2309
- await window.Store.ScheduledEventMsgUtils.sendEventResponseMsg(response, eventMsg);
2357
+ await (window.require('WAWebSendEventResponseMsgAction')).sendEventResponseMsg(response, eventMsg);
2310
2358
  return true;
2311
2359
  }, response, eventMessageId);
2312
2360
  }
@@ -2322,15 +2370,14 @@ class Client extends EventEmitter {
2322
2370
  async saveOrEditAddressbookContact(phoneNumber, firstName, lastName, syncToAddressbook = false)
2323
2371
  {
2324
2372
  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
- );
2373
+ return await (window.require('WAWebSaveContactAction')).saveContactAction({
2374
+ 'firstName' : firstName,
2375
+ 'lastName' : lastName,
2376
+ 'phoneNumber' : phoneNumber,
2377
+ 'prevPhoneNumber' : phoneNumber,
2378
+ 'syncToAddressbook': syncToAddressbook,
2379
+ 'username' : undefined
2380
+ });
2334
2381
  }, phoneNumber, firstName, lastName, syncToAddressbook);
2335
2382
  }
2336
2383
 
@@ -2342,7 +2389,8 @@ class Client extends EventEmitter {
2342
2389
  async deleteAddressbookContact(phoneNumber)
2343
2390
  {
2344
2391
  return await this.pupPage.evaluate(async (phoneNumber) => {
2345
- return await window.Store.AddressbookContactUtils.deleteContactAction(phoneNumber);
2392
+ const wid = window.require('WAWebWidFactory').createWid(phoneNumber);
2393
+ return await (window.require('WAWebDeleteContactAction')).deleteContactAction({phoneNumber: wid});
2346
2394
  }, phoneNumber);
2347
2395
  }
2348
2396
 
@@ -2375,11 +2423,11 @@ class Client extends EventEmitter {
2375
2423
  */
2376
2424
  async addOrEditCustomerNote(userId, note) {
2377
2425
  return await this.pupPage.evaluate(async (userId, note) => {
2378
- if (!window.Store.BusinessGatingUtils.smbNotesV1Enabled()) return;
2426
+ if (!(window.require('WAWebBizGatingUtils')).smbNotesV1Enabled()) return;
2379
2427
 
2380
- return window.Store.CustomerNoteUtils.noteAddAction(
2428
+ return (window.require('WAWebNoteAction')).noteAddAction(
2381
2429
  'unstructured',
2382
- window.Store.WidToJid.widToUserJid(window.Store.WidFactory.createWid(userId)),
2430
+ window.require('WAWebWidToJid').widToUserJid(window.require('WAWebWidFactory').createWid(userId)),
2383
2431
  note
2384
2432
  );
2385
2433
  }, userId, note);
@@ -2400,17 +2448,17 @@ class Client extends EventEmitter {
2400
2448
  */
2401
2449
  async getCustomerNote(userId) {
2402
2450
  return await this.pupPage.evaluate(async (userId) => {
2403
- if (!window.Store.BusinessGatingUtils.smbNotesV1Enabled()) return null;
2451
+ if (!(window.require('WAWebBizGatingUtils')).smbNotesV1Enabled()) return null;
2404
2452
 
2405
- const note = await window.Store.CustomerNoteUtils.retrieveOnlyNoteForChatJid(
2406
- window.Store.WidToJid.widToUserJid(window.Store.WidFactory.createWid(userId))
2453
+ const note = await (window.require('WAWebNoteAction')).retrieveOnlyNoteForChatJid(
2454
+ window.require('WAWebWidToJid').widToUserJid(window.require('WAWebWidFactory').createWid(userId))
2407
2455
  );
2408
2456
 
2409
2457
  let serialized = note?.serialize();
2410
2458
 
2411
2459
  if (!serialized) return null;
2412
2460
 
2413
- serialized.chatId = window.Store.JidToWid.userJidToUserWid(serialized.chatJid)._serialized;
2461
+ serialized.chatId = window.require('WAWebJidToWid').userJidToUserWid(serialized.chatJid)._serialized;
2414
2462
  delete serialized.chatJid;
2415
2463
 
2416
2464
  return serialized;
@@ -2428,8 +2476,8 @@ class Client extends EventEmitter {
2428
2476
  if (msg.type != MessageTypes.POLL_CREATION) throw 'Invalid usage! Can only be used with a pollCreation message';
2429
2477
 
2430
2478
  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());
2479
+ const msgKey = (window.require('WAWebMsgKey')).fromString(msg.id._serialized);
2480
+ let pollVotes = await (window.require('WAWebPollsVotesSchema')).getTable().equals(['parentMsgKey'], msgKey.toString());
2433
2481
 
2434
2482
  return pollVotes.map(item => {
2435
2483
  const typedArray = new Uint8Array(item.selectedOptionLocalIds);