@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.
@@ -102,24 +102,34 @@ class RemoteAuth extends BaseAuthStrategy {
102
102
  }
103
103
 
104
104
  async storeRemoteSession(options) {
105
- /* Compress & Store Session */
106
105
  const pathExists = await this.isValidPath(this.userDataDir);
107
- if (pathExists) {
108
- await this.compressSession();
109
- await this.store.save({session: this.sessionName});
110
- await fs.promises.unlink(`${this.sessionName}.zip`);
111
- await fs.promises.rm(`${this.tempDir}`, {
112
- recursive: true,
113
- force: true,
114
- maxRetries: this.rmMaxRetries,
115
- }).catch(() => {});
106
+ if (!pathExists) return;
107
+
108
+ let compressedSessionPath;
109
+ try {
110
+ compressedSessionPath = await this.compressSession();
111
+ await this.store.save({ session: path.join(this.dataPath, this.sessionName) });
116
112
  if(options && options.emit) this.client.emit(Events.REMOTE_SESSION_SAVED);
113
+ } finally {
114
+ const paths = [
115
+ this.tempDir,
116
+ ...(compressedSessionPath ? [compressedSessionPath] : [])
117
+ ];
118
+ await Promise.allSettled(
119
+ paths.map((p) =>
120
+ fs.promises.rm(p, {
121
+ recursive: true,
122
+ force: true,
123
+ maxRetries: this.rmMaxRetries,
124
+ })
125
+ )
126
+ );
117
127
  }
118
128
  }
119
129
 
120
130
  async extractRemoteSession() {
121
131
  const pathExists = await this.isValidPath(this.userDataDir);
122
- const compressedSessionPath = `${this.sessionName}.zip`;
132
+ const compressedSessionPath = path.join(this.dataPath, `${this.sessionName}.zip`);
123
133
  const sessionExists = await this.store.sessionExists({session: this.sessionName});
124
134
  if (pathExists) {
125
135
  await fs.promises.rm(this.userDataDir, {
@@ -142,27 +152,34 @@ class RemoteAuth extends BaseAuthStrategy {
142
152
  }
143
153
 
144
154
  async compressSession() {
145
- const archive = archiver('zip');
146
- const stream = fs.createWriteStream(`${this.sessionName}.zip`);
155
+ const stageDefaultPath = path.join(this.tempDir, 'Default');
156
+ const userDataDefaultPath = path.join(this.userDataDir, 'Default');
147
157
 
148
- await fs.copy(this.userDataDir, this.tempDir).catch(() => {});
149
- await this.deleteMetadata();
150
- return new Promise((resolve, reject) => {
151
- archive
152
- .directory(this.tempDir, false)
153
- .on('error', err => reject(err))
154
- .pipe(stream);
158
+ await fs.emptyDir(stageDefaultPath);
159
+ await this.copyByRequiredDirs(userDataDefaultPath, stageDefaultPath);
155
160
 
156
- stream.on('close', () => resolve());
161
+ const archive = archiver('zip');
162
+ const outPath = path.join(this.dataPath, `${this.sessionName}.zip`);
163
+ const out = fs.createWriteStream(outPath);
164
+
165
+ await new Promise((resolve, reject) => {
166
+ out.once('close', resolve);
167
+ out.once('error', reject);
168
+ archive.once('error', reject);
169
+
170
+ archive.pipe(out);
171
+ archive.directory(this.tempDir, false);
157
172
  archive.finalize();
158
173
  });
174
+ return outPath;
159
175
  }
160
176
 
161
177
  async unCompressSession(compressedSessionPath) {
162
178
  var stream = fs.createReadStream(compressedSessionPath);
163
179
  await new Promise((resolve, reject) => {
164
180
  stream.pipe(unzipper.Extract({
165
- path: this.userDataDir
181
+ path: this.userDataDir,
182
+ concurrency: 10
166
183
  }))
167
184
  .on('error', err => reject(err))
168
185
  .on('finish', () => resolve());
@@ -170,25 +187,16 @@ class RemoteAuth extends BaseAuthStrategy {
170
187
  await fs.promises.unlink(compressedSessionPath);
171
188
  }
172
189
 
173
- async deleteMetadata() {
174
- const sessionDirs = [this.tempDir, path.join(this.tempDir, 'Default')];
175
- for (const dir of sessionDirs) {
176
- const sessionFiles = await fs.promises.readdir(dir);
177
- for (const element of sessionFiles) {
178
- if (!this.requiredDirs.includes(element)) {
179
- const dirElement = path.join(dir, element);
180
- const stats = await fs.promises.lstat(dirElement);
181
-
182
- if (stats.isDirectory()) {
183
- await fs.promises.rm(dirElement, {
184
- recursive: true,
185
- force: true,
186
- maxRetries: this.rmMaxRetries,
187
- }).catch(() => {});
188
- } else {
189
- await fs.promises.unlink(dirElement).catch(() => {});
190
- }
191
- }
190
+ async copyByRequiredDirs(from, to) {
191
+ for (const d of this.requiredDirs) {
192
+ const src = path.join(from, d);
193
+ if (await this.isValidPath(src)) {
194
+ const dest = path.join(to, path.basename(src));
195
+ await fs.promises.cp(src, dest, {
196
+ recursive: true,
197
+ force: true,
198
+ errorOnExist: false
199
+ });
192
200
  }
193
201
  }
194
202
  }
@@ -97,15 +97,15 @@ class Channel extends Base {
97
97
  /**
98
98
  * Gets the subscribers of the channel (only those who are in your contact list)
99
99
  * @param {?number} limit Optional parameter to specify the limit of subscribers to retrieve
100
- * @returns {Promise<{contact: Contact, role: string}[]>} Returns an array of objects that handle the subscribed contacts and their roles in the channel
100
+ * @returns {Promise<Array<{contact: Contact, role: string}>>} Returns an array of objects that handle the subscribed contacts and their roles in the channel
101
101
  */
102
102
  async getSubscribers(limit) {
103
103
  return await this.client.pupPage.evaluate(async (channelId, limit) => {
104
104
  const channel = await window.WWebJS.getChat(channelId, { getAsModel: false });
105
105
  if (!channel) return [];
106
- !limit && (limit = window.Store.ChannelUtils.getMaxSubscriberNumber());
107
- const response = await window.Store.ChannelSubscribers.mexFetchNewsletterSubscribers(channelId, limit);
108
- const contacts = window.Store.ChannelSubscribers.getSubscribersInContacts(response.subscribers);
106
+ !limit && (limit = window.require('WAWebNewsletterGatingUtils').getMaxSubscriberNumber());
107
+ const response = await (window.require('WAWebMexFetchNewsletterSubscribersJob')).mexFetchNewsletterSubscribers(channelId, limit);
108
+ const contacts = (window.require('WAWebNewsletterSubscriberListAction')).getSubscribersInContacts(response.subscribers);
109
109
  return Promise.all(contacts.map((obj) => ({
110
110
  ...obj,
111
111
  contact: window.WWebJS.getContactModel(obj.contact)
@@ -303,7 +303,7 @@ class Channel extends Base {
303
303
 
304
304
  if (searchOptions && searchOptions.limit > 0) {
305
305
  while (msgs.length < searchOptions.limit) {
306
- const loadedMessages = await window.Store.ConversationMsgs.loadEarlierMsgs(channel);
306
+ const loadedMessages = await (window.require('WAWebChatLoadMessages')).loadEarlierMsgs(channel);
307
307
  if (!loadedMessages || !loadedMessages.length) break;
308
308
  msgs = [...loadedMessages.filter(msgFilter), ...msgs];
309
309
  }
@@ -350,7 +350,7 @@ class Channel extends Base {
350
350
  : null;
351
351
  }
352
352
  try {
353
- await window.Store.ChannelUtils.editNewsletterMetadataAction(channel, property, value);
353
+ await (window.require('WAWebEditNewsletterMetadataAction')).editNewsletterMetadataAction(channel, property, value);
354
354
  return true;
355
355
  } catch (err) {
356
356
  if (err.name === 'ServerStatusCodeError') return false;
@@ -367,9 +367,11 @@ class Channel extends Base {
367
367
  async _muteUnmuteChannel(action) {
368
368
  return await this.client.pupPage.evaluate(async (channelId, action) => {
369
369
  try {
370
- action === 'MUTE'
371
- ? await window.Store.ChannelUtils.muteNewsletter([channelId])
372
- : await window.Store.ChannelUtils.unmuteNewsletter([channelId]);
370
+ await (window.require('WAWebNewsletterUpdateUserSettingJob')).updateNewsletterUserSetting({
371
+ newsletterJid: window.require('WAJids').toNewsletterJid(channelId),
372
+ type: window.require('WAWebNewsletterModelUtils').ADMIN_NOTIFICATIONS,
373
+ muteExpirationValue: action === 'MUTE' ? window.require('WAWebNewsletterModelUtils').MUTED_STATE : window.require('WAWebNewsletterModelUtils').UNMUTED_STATE
374
+ });
373
375
  return true;
374
376
  } catch (err) {
375
377
  if (err.name === 'ServerStatusCodeError') return false;
@@ -63,6 +63,12 @@ class Chat extends Base {
63
63
  */
64
64
  this.pinned = !!data.pin;
65
65
 
66
+ /**
67
+ * Indicates if the Chat is locked
68
+ * @type {boolean}
69
+ */
70
+ this.isLocked = data.isLocked;
71
+
66
72
  /**
67
73
  * Indicates if the chat is muted or not
68
74
  * @type {boolean}
@@ -206,7 +212,7 @@ class Chat extends Base {
206
212
 
207
213
  if (searchOptions && searchOptions.limit > 0) {
208
214
  while (msgs.length < searchOptions.limit) {
209
- const loadedMessages = await window.Store.ConversationMsgs.loadEarlierMsgs(chat);
215
+ const loadedMessages = await (window.require('WAWebChatLoadMessages')).loadEarlierMsgs(chat,chat.msgs);
210
216
  if (!loadedMessages || !loadedMessages.length) break;
211
217
  msgs = [...loadedMessages.filter(msgFilter), ...msgs];
212
218
  }
@@ -281,7 +287,7 @@ class Chat extends Base {
281
287
 
282
288
  /**
283
289
  * Gets instances of all pinned messages in a chat
284
- * @returns {Promise<[Message]|[]>}
290
+ * @returns {Promise<Array<Message>>}
285
291
  */
286
292
  async getPinnedMessages() {
287
293
  return this.client.getPinnedMessages(this.id._serialized);
@@ -62,7 +62,7 @@ class ClientInfo extends Base {
62
62
  */
63
63
  async getBatteryStatus() {
64
64
  return await this.client.pupPage.evaluate(() => {
65
- const { battery, plugged } = window.Store.Conn;
65
+ const { battery, plugged } = window.require('WAWebConnModel').Conn;
66
66
  return { battery, plugged };
67
67
  });
68
68
  }
@@ -155,8 +155,8 @@ class Contact extends Base {
155
155
  if(this.isGroup) return false;
156
156
 
157
157
  await this.client.pupPage.evaluate(async (contactId) => {
158
- const contact = window.Store.Contact.get(contactId);
159
- await window.Store.BlockContact.blockContact({contact});
158
+ const contact = (window.require('WAWebCollections')).Contact.get(contactId);
159
+ await (window.require('WAWebBlockContactAction')).blockContact({contact});
160
160
  }, this.id._serialized);
161
161
 
162
162
  this.isBlocked = true;
@@ -171,8 +171,8 @@ class Contact extends Base {
171
171
  if(this.isGroup) return false;
172
172
 
173
173
  await this.client.pupPage.evaluate(async (contactId) => {
174
- const contact = window.Store.Contact.get(contactId);
175
- await window.Store.BlockContact.unblockContact(contact);
174
+ const contact = (window.require('WAWebCollections')).Contact.get(contactId);
175
+ await (window.require('WAWebBlockContactAction')).unblockContact(contact);
176
176
  }, this.id._serialized);
177
177
 
178
178
  this.isBlocked = false;
@@ -185,8 +185,8 @@ class Contact extends Base {
185
185
  */
186
186
  async getAbout() {
187
187
  const about = await this.client.pupPage.evaluate(async (contactId) => {
188
- const wid = window.Store.WidFactory.createWid(contactId);
189
- return window.Store.StatusUtils.getStatus({'token':'', 'wid': wid});
188
+ const wid = window.require('WAWebWidFactory').createWid(contactId);
189
+ return (window.require('WAWebContactStatusBridge')).getStatus({'token':'', 'wid': wid});
190
190
  }, this.id._serialized);
191
191
 
192
192
  if (typeof about.status !== 'string')
@@ -202,7 +202,14 @@ class Contact extends Base {
202
202
  async getCommonGroups() {
203
203
  return await this.client.getCommonGroups(this.id._serialized);
204
204
  }
205
-
205
+
206
+ /**
207
+ * Gets the Contact's current status broadcast.
208
+ * @returns {Promise<Broadcast>}
209
+ */
210
+ async getBroadcast() {
211
+ return await this.client.getBroadcastById(this.id._serialized);
212
+ }
206
213
  }
207
214
 
208
215
  module.exports = Contact;
@@ -81,9 +81,9 @@ class GroupChat extends Chat {
81
81
  const participantData = {};
82
82
 
83
83
  !Array.isArray(participantIds) && (participantIds = [participantIds]);
84
- const groupWid = window.Store.WidFactory.createWid(groupId);
85
- const group = window.Store.Chat.get(groupWid) || (await window.Store.Chat.find(groupWid));
86
- const participantWids = participantIds.map((p) => window.Store.WidFactory.createWid(p));
84
+ const groupWid = window.require('WAWebWidFactory').createWid(groupId);
85
+ const group = (window.require('WAWebCollections')).Chat.get(groupWid) || (await (window.require('WAWebCollections')).Chat.find(groupWid));
86
+ const participantWids = participantIds.map((p) => window.require('WAWebWidFactory').createWid(p));
87
87
 
88
88
  const errorCodes = {
89
89
  default: 'An unknown error occupied while adding a participant',
@@ -98,7 +98,7 @@ class GroupChat extends Chat {
98
98
  419: 'The participant can\'t be added because the group is full'
99
99
  };
100
100
 
101
- await window.Store.GroupQueryAndUpdate({ id: groupId });
101
+ await (window.require('WAWebGroupQueryJob')).queryAndUpdateGroupMetadataById({ id: groupId });
102
102
 
103
103
  let groupParticipants = group.groupMetadata?.participants.serialize();
104
104
 
@@ -111,7 +111,7 @@ class GroupChat extends Chat {
111
111
  }
112
112
 
113
113
  groupParticipants.map(({ id }) => {
114
- return id.server === 'lid' ? window.Store.LidUtils.getPhoneNumber(id) : id;
114
+ return id.server === 'lid' ? window.require('WAWebApiContact').getPhoneNumber(id) : id;
115
115
  });
116
116
 
117
117
  const _getSleepTime = (sleep) => {
@@ -127,7 +127,7 @@ class GroupChat extends Chat {
127
127
 
128
128
  for (let pWid of participantWids) {
129
129
  const pId = pWid._serialized;
130
- pWid = pWid.server === 'lid' ? window.Store.LidUtils.getPhoneNumber(pWid) : pWid;
130
+ pWid = pWid.server === 'lid' ? window.require('WAWebApiContact').getPhoneNumber(pWid) : pWid;
131
131
 
132
132
  participantData[pId] = {
133
133
  code: undefined,
@@ -141,7 +141,7 @@ class GroupChat extends Chat {
141
141
  continue;
142
142
  }
143
143
 
144
- if (!(await window.Store.QueryExist(pWid))?.wid) {
144
+ if (!(await (window.require('WAWebQueryExistsJob').queryWidExists)(pWid))?.wid) {
145
145
  participantData[pId].code = 404;
146
146
  participantData[pId].message = errorCodes[404];
147
147
  continue;
@@ -157,12 +157,12 @@ class GroupChat extends Chat {
157
157
 
158
158
  if (autoSendInviteV4 && rpcResultCode === 403) {
159
159
  let userChat, isInviteV4Sent = false;
160
- window.Store.Contact.gadd(pWid, { silent: true });
160
+ (window.require('WAWebCollections')).Contact.gadd(pWid, { silent: true });
161
161
 
162
162
  if (rpcResult.name === 'ParticipantRequestCodeCanBeSent' &&
163
- (userChat = window.Store.Chat.get(pWid) || (await window.Store.Chat.find(pWid)))) {
163
+ (userChat = (window.require('WAWebCollections')).Chat.get(pWid) || (await (window.require('WAWebCollections')).Chat.find(pWid)))) {
164
164
  const groupName = group.formattedTitle || group.name;
165
- const res = await window.Store.GroupInviteV4.sendGroupInviteMessage(
165
+ const res = await (window.require('WAWebChatSendMessages')).sendGroupInviteMessage(
166
166
  userChat,
167
167
  group.id._serialized,
168
168
  groupName,
@@ -201,7 +201,7 @@ class GroupChat extends Chat {
201
201
  return chat.groupMetadata.participants.get(lid?._serialized) ||
202
202
  chat.groupMetadata.participants.get(phone?._serialized);
203
203
  }))).filter(Boolean);
204
- await window.Store.GroupParticipants.removeParticipants(chat, participants);
204
+ await (window.require('WAWebModifyParticipantsGroupAction')).removeParticipants(chat, participants);
205
205
  return { status: 200 };
206
206
  }, this.id._serialized, participantIds);
207
207
  }
@@ -220,7 +220,7 @@ class GroupChat extends Chat {
220
220
  return chat.groupMetadata.participants.get(lid?._serialized) ||
221
221
  chat.groupMetadata.participants.get(phone?._serialized);
222
222
  }))).filter(Boolean);
223
- await window.Store.GroupParticipants.promoteParticipants(chat, participants);
223
+ await (window.require('WAWebModifyParticipantsGroupAction')).promoteParticipants(chat, participants);
224
224
  return { status: 200 };
225
225
  }, this.id._serialized, participantIds);
226
226
  }
@@ -239,7 +239,7 @@ class GroupChat extends Chat {
239
239
  return chat.groupMetadata.participants.get(lid?._serialized) ||
240
240
  chat.groupMetadata.participants.get(phone?._serialized);
241
241
  }))).filter(Boolean);
242
- await window.Store.GroupParticipants.demoteParticipants(chat, participants);
242
+ await (window.require('WAWebModifyParticipantsGroupAction')).demoteParticipants(chat, participants);
243
243
  return { status: 200 };
244
244
  }, this.id._serialized, participantIds);
245
245
  }
@@ -251,9 +251,9 @@ class GroupChat extends Chat {
251
251
  */
252
252
  async setSubject(subject) {
253
253
  const success = await this.client.pupPage.evaluate(async (chatId, subject) => {
254
- const chatWid = window.Store.WidFactory.createWid(chatId);
254
+ const chatWid = window.require('WAWebWidFactory').createWid(chatId);
255
255
  try {
256
- await window.Store.GroupUtils.setGroupSubject(chatWid, subject);
256
+ await (window.require('WAWebGroupModifyInfoJob')).setGroupSubject(chatWid, subject);
257
257
  return true;
258
258
  } catch (err) {
259
259
  if(err.name === 'ServerStatusCodeError') return false;
@@ -273,11 +273,12 @@ class GroupChat extends Chat {
273
273
  */
274
274
  async setDescription(description) {
275
275
  const success = await this.client.pupPage.evaluate(async (chatId, description) => {
276
- const chatWid = window.Store.WidFactory.createWid(chatId);
277
- let descId = window.Store.GroupMetadata.get(chatWid).descId;
278
- let newId = await window.Store.MsgKey.newId();
276
+ const chatWid = window.require('WAWebWidFactory').createWid(chatId);
277
+ const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
278
+ let descId = chat.groupMetadata.descId;
279
+ let newId = await (window.require('WAWebMsgKey')).newId();
279
280
  try {
280
- await window.Store.GroupUtils.setGroupDescription(chatWid, description, newId, descId);
281
+ await (window.require('WAWebGroupModifyInfoJob')).setGroupDescription(chatWid, description, newId, descId);
281
282
  return true;
282
283
  } catch (err) {
283
284
  if(err.name === 'ServerStatusCodeError') return false;
@@ -299,7 +300,7 @@ class GroupChat extends Chat {
299
300
  const success = await this.client.pupPage.evaluate(async (groupId, adminsOnly) => {
300
301
  const chat = await window.WWebJS.getChat(groupId, { getAsModel: false });
301
302
  try {
302
- await window.Store.GroupUtils.setGroupProperty(chat, 'member_add_mode', adminsOnly ? 0 : 1);
303
+ await (window.require('WAWebSetPropertyGroupAction')).setGroupProperty(chat, 'member_add_mode', adminsOnly ? 0 : 1);
303
304
  return true;
304
305
  } catch (err) {
305
306
  if(err.name === 'ServerStatusCodeError') return false;
@@ -320,7 +321,7 @@ class GroupChat extends Chat {
320
321
  const success = await this.client.pupPage.evaluate(async (chatId, adminsOnly) => {
321
322
  const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
322
323
  try {
323
- await window.Store.GroupUtils.setGroupProperty(chat, 'announcement', adminsOnly ? 1 : 0);
324
+ await (window.require('WAWebSetPropertyGroupAction')).setGroupProperty(chat, 'announcement', adminsOnly ? 1 : 0);
324
325
  return true;
325
326
  } catch (err) {
326
327
  if(err.name === 'ServerStatusCodeError') return false;
@@ -343,7 +344,7 @@ class GroupChat extends Chat {
343
344
  const success = await this.client.pupPage.evaluate(async (chatId, adminsOnly) => {
344
345
  const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
345
346
  try {
346
- await window.Store.GroupUtils.setGroupProperty(chat, 'restrict', adminsOnly ? 1 : 0);
347
+ await (window.require('WAWebSetPropertyGroupAction')).setGroupProperty(chat, 'restrict', adminsOnly ? 1 : 0);
347
348
  return true;
348
349
  } catch (err) {
349
350
  if(err.name === 'ServerStatusCodeError') return false;
@@ -388,11 +389,8 @@ class GroupChat extends Chat {
388
389
  */
389
390
  async getInviteCode() {
390
391
  const codeRes = await this.client.pupPage.evaluate(async chatId => {
391
- const chatWid = window.Store.WidFactory.createWid(chatId);
392
392
  try {
393
- return window.compareWwebVersions(window.Debug.VERSION, '>=', '2.3000.1020730154')
394
- ? await window.Store.GroupInvite.fetchMexGroupInviteCode(chatId)
395
- : await window.Store.GroupInvite.queryGroupInviteCode(chatWid, true);
393
+ return await (window.require('WAWebMexFetchGroupInviteCodeJob')).fetchMexGroupInviteCode(chatId);
396
394
  }
397
395
  catch (err) {
398
396
  if(err.name === 'ServerStatusCodeError') return undefined;
@@ -411,8 +409,8 @@ class GroupChat extends Chat {
411
409
  */
412
410
  async revokeInvite() {
413
411
  const codeRes = await this.client.pupPage.evaluate(chatId => {
414
- const chatWid = window.Store.WidFactory.createWid(chatId);
415
- return window.Store.GroupInvite.resetGroupInviteCode(chatWid);
412
+ const chatWid = window.require('WAWebWidFactory').createWid(chatId);
413
+ return (window.require('WAWebGroupQueryJob')).resetGroupInviteCode(chatWid);
416
414
  }, this.id._serialized);
417
415
 
418
416
  return codeRes.code;
@@ -476,7 +474,7 @@ class GroupChat extends Chat {
476
474
  async leave() {
477
475
  await this.client.pupPage.evaluate(async chatId => {
478
476
  const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
479
- return window.Store.GroupUtils.sendExitGroup(chat);
477
+ return (window.require('WAWebExitGroupAction')).sendExitGroup(chat);
480
478
  }, this.id._serialized);
481
479
  }
482
480