whatsapp-web-jf.js 1.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/.env.example +3 -0
  2. package/CODE_OF_CONDUCT.md +133 -0
  3. package/LICENSE +201 -0
  4. package/README.md +185 -0
  5. package/example.js +680 -0
  6. package/index.d.ts +2069 -0
  7. package/index.js +34 -0
  8. package/package.json +55 -0
  9. package/shell.js +36 -0
  10. package/src/Client.js +2188 -0
  11. package/src/authStrategies/BaseAuthStrategy.js +27 -0
  12. package/src/authStrategies/LocalAuth.js +58 -0
  13. package/src/authStrategies/NoAuth.js +12 -0
  14. package/src/authStrategies/RemoteAuth.js +210 -0
  15. package/src/factories/ChatFactory.js +21 -0
  16. package/src/factories/ContactFactory.js +16 -0
  17. package/src/structures/Base.js +22 -0
  18. package/src/structures/Broadcast.js +69 -0
  19. package/src/structures/BusinessContact.js +21 -0
  20. package/src/structures/Buttons.js +82 -0
  21. package/src/structures/Call.js +76 -0
  22. package/src/structures/Channel.js +382 -0
  23. package/src/structures/Chat.js +291 -0
  24. package/src/structures/ClientInfo.js +71 -0
  25. package/src/structures/Contact.js +208 -0
  26. package/src/structures/GroupChat.js +473 -0
  27. package/src/structures/GroupNotification.js +104 -0
  28. package/src/structures/Label.js +50 -0
  29. package/src/structures/List.js +79 -0
  30. package/src/structures/Location.js +62 -0
  31. package/src/structures/Message.js +704 -0
  32. package/src/structures/MessageMedia.js +111 -0
  33. package/src/structures/Order.js +52 -0
  34. package/src/structures/Payment.js +79 -0
  35. package/src/structures/Poll.js +44 -0
  36. package/src/structures/PollVote.js +61 -0
  37. package/src/structures/PrivateChat.js +13 -0
  38. package/src/structures/PrivateContact.js +13 -0
  39. package/src/structures/Product.js +68 -0
  40. package/src/structures/ProductMetadata.js +25 -0
  41. package/src/structures/Reaction.js +69 -0
  42. package/src/structures/index.js +26 -0
  43. package/src/util/Constants.js +176 -0
  44. package/src/util/Injected/AuthStore/AuthStore.js +17 -0
  45. package/src/util/Injected/AuthStore/LegacyAuthStore.js +22 -0
  46. package/src/util/Injected/LegacyStore.js +146 -0
  47. package/src/util/Injected/Store.js +215 -0
  48. package/src/util/Injected/Utils.js +1139 -0
  49. package/src/util/InterfaceController.js +126 -0
  50. package/src/util/Puppeteer.js +23 -0
  51. package/src/util/Util.js +186 -0
  52. package/src/webCache/LocalWebCache.js +40 -0
  53. package/src/webCache/RemoteWebCache.js +40 -0
  54. package/src/webCache/WebCache.js +14 -0
  55. package/src/webCache/WebCacheFactory.js +20 -0
@@ -0,0 +1,1139 @@
1
+ 'use strict';
2
+
3
+ exports.LoadUtils = () => {
4
+ window.WWebJS = {};
5
+
6
+ window.WWebJS.forwardMessage = async (chatId, msgId) => {
7
+ const msg = window.Store.Msg.get(msgId) || (await window.Store.Msg.getMessagesById([msgId]))?.messages?.[0];
8
+ const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
9
+
10
+ if (window.compareWwebVersions(window.Debug.VERSION, '>', '2.3000.0')) {
11
+ return window.Store.ForwardUtils.forwardMessagesToChats([msg], [chat], true);
12
+ } else {
13
+ return chat.forwardMessages([msg]);
14
+ }
15
+ };
16
+
17
+ window.WWebJS.sendSeen = async (chatId) => {
18
+ const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
19
+ if (chat) {
20
+ await window.Store.SendSeen.sendSeen(chat);
21
+ return true;
22
+ }
23
+ return false;
24
+ };
25
+
26
+ window.WWebJS.sendMessage = async (chat, content, options = {}) => {
27
+ const isChannel = window.Store.ChatGetters.getIsNewsletter(chat);
28
+
29
+ let mediaOptions = {};
30
+ if (options.media) {
31
+ mediaOptions = options.sendMediaAsSticker && !isChannel
32
+ ? await window.WWebJS.processStickerData(options.media)
33
+ : await window.WWebJS.processMediaData(options.media, {
34
+ forceSticker: options.sendMediaAsSticker,
35
+ forceGif: options.sendVideoAsGif,
36
+ forceVoice: options.sendAudioAsVoice,
37
+ forceDocument: options.sendMediaAsDocument,
38
+ forceMediaHd: options.sendMediaAsHd,
39
+ sendToChannel: isChannel
40
+ });
41
+ mediaOptions.caption = options.caption;
42
+ content = options.sendMediaAsSticker ? undefined : mediaOptions.preview;
43
+ mediaOptions.isViewOnce = options.isViewOnce;
44
+ delete options.media;
45
+ delete options.sendMediaAsSticker;
46
+ }
47
+
48
+ let quotedMsgOptions = {};
49
+ if (options.quotedMessageId) {
50
+ let quotedMessage = window.Store.Msg.get(options.quotedMessageId);
51
+ !quotedMessage && (quotedMessage = (await window.Store.Msg.getMessagesById([options.quotedMessageId]))?.messages?.[0]);
52
+ if (quotedMessage) {
53
+
54
+ const canReply = window.Store.ReplyUtils
55
+ ? window.Store.ReplyUtils.canReplyMsg(quotedMessage.unsafe())
56
+ : quotedMessage.canReply();
57
+
58
+ if (canReply) {
59
+ quotedMsgOptions = quotedMessage.msgContextInfo(chat);
60
+ }
61
+ } else {
62
+ if (!options.ignoreQuoteErrors) {
63
+ throw new Error('Could not get the quoted message.');
64
+ }
65
+ }
66
+
67
+ delete options.ignoreQuoteErrors;
68
+ delete options.quotedMessageId;
69
+ }
70
+
71
+ if (options.mentionedJidList) {
72
+ options.mentionedJidList = await Promise.all(
73
+ options.mentionedJidList.map(async (id) => {
74
+ const wid = window.Store.WidFactory.createWid(id);
75
+ if (await window.Store.QueryExist(wid)) {
76
+ return wid;
77
+ }
78
+ })
79
+ );
80
+ options.mentionedJidList = options.mentionedJidList.filter(Boolean);
81
+ }
82
+
83
+ if (options.groupMentions) {
84
+ options.groupMentions = options.groupMentions.map((e) => ({
85
+ groupSubject: e.subject,
86
+ groupJid: window.Store.WidFactory.createWid(e.id)
87
+ }));
88
+ }
89
+
90
+ let locationOptions = {};
91
+ if (options.location) {
92
+ let { latitude, longitude, description, url } = options.location;
93
+ url = window.Store.Validators.findLink(url)?.href;
94
+ url && !description && (description = url);
95
+ locationOptions = {
96
+ type: 'location',
97
+ loc: description,
98
+ lat: latitude,
99
+ lng: longitude,
100
+ clientUrl: url
101
+ };
102
+ delete options.location;
103
+ }
104
+
105
+ let _pollOptions = {};
106
+ if (options.poll) {
107
+ const { pollName, pollOptions } = options.poll;
108
+ const { allowMultipleAnswers, messageSecret } = options.poll.options;
109
+ _pollOptions = {
110
+ kind: 'pollCreation',
111
+ type: 'poll_creation',
112
+ pollName: pollName,
113
+ pollOptions: pollOptions,
114
+ pollSelectableOptionsCount: allowMultipleAnswers ? 0 : 1,
115
+ messageSecret:
116
+ Array.isArray(messageSecret) && messageSecret.length === 32
117
+ ? new Uint8Array(messageSecret)
118
+ : window.crypto.getRandomValues(new Uint8Array(32))
119
+ };
120
+ delete options.poll;
121
+ }
122
+
123
+ let vcardOptions = {};
124
+ if (options.contactCard) {
125
+ let contact = window.Store.Contact.get(options.contactCard);
126
+ vcardOptions = {
127
+ body: window.Store.VCard.vcardFromContactModel(contact).vcard,
128
+ type: 'vcard',
129
+ vcardFormattedName: contact.formattedName
130
+ };
131
+ delete options.contactCard;
132
+ } else if (options.contactCardList) {
133
+ let contacts = options.contactCardList.map(c => window.Store.Contact.get(c));
134
+ let vcards = contacts.map(c => window.Store.VCard.vcardFromContactModel(c));
135
+ vcardOptions = {
136
+ type: 'multi_vcard',
137
+ vcardList: vcards,
138
+ body: null
139
+ };
140
+ delete options.contactCardList;
141
+ } else if (options.parseVCards && typeof (content) === 'string' && content.startsWith('BEGIN:VCARD')) {
142
+ delete options.parseVCards;
143
+ delete options.linkPreview;
144
+ try {
145
+ const parsed = window.Store.VCard.parseVcard(content);
146
+ if (parsed) {
147
+ vcardOptions = {
148
+ type: 'vcard',
149
+ vcardFormattedName: window.Store.VCard.vcardGetNameFromParsed(parsed)
150
+ };
151
+ }
152
+ } catch (_) {
153
+ // not a vcard
154
+ }
155
+ }
156
+
157
+ if (options.linkPreview) {
158
+ delete options.linkPreview;
159
+ const link = window.Store.Validators.findLink(content);
160
+ if (link) {
161
+ let preview = await window.Store.LinkPreview.getLinkPreview(link);
162
+ if (preview && preview.data) {
163
+ preview = preview.data;
164
+ preview.preview = true;
165
+ preview.subtype = 'url';
166
+ options = {...options, ...preview};
167
+ }
168
+ }
169
+ }
170
+
171
+ let buttonOptions = {};
172
+ if (options.buttons) {
173
+ let caption;
174
+ if (options.buttons.type === 'chat') {
175
+ content = options.buttons.body;
176
+ caption = content;
177
+ } else {
178
+ caption = options.caption ? options.caption : ' '; //Caption can't be empty
179
+ }
180
+ buttonOptions = {
181
+ productHeaderImageRejected: false,
182
+ isFromTemplate: false,
183
+ isDynamicReplyButtonsMsg: true,
184
+ title: options.buttons.title ? options.buttons.title : undefined,
185
+ footer: options.buttons.footer ? options.buttons.footer : undefined,
186
+ dynamicReplyButtons: options.buttons.buttons,
187
+ replyButtons: options.buttons.buttons,
188
+ caption: caption
189
+ };
190
+ delete options.buttons;
191
+ }
192
+
193
+ let listOptions = {};
194
+ if (options.list) {
195
+ if (window.Store.Conn.platform === 'smba' || window.Store.Conn.platform === 'smbi') {
196
+ throw '[LT01] Whatsapp business can\'t send this yet';
197
+ }
198
+ listOptions = {
199
+ type: 'list',
200
+ footer: options.list.footer,
201
+ list: {
202
+ ...options.list,
203
+ listType: 1
204
+ },
205
+ body: options.list.description
206
+ };
207
+ delete options.list;
208
+ delete listOptions.list.footer;
209
+ }
210
+
211
+ const botOptions = {};
212
+ if (options.invokedBotWid) {
213
+ botOptions.messageSecret = window.crypto.getRandomValues(new Uint8Array(32));
214
+ botOptions.botMessageSecret = await window.Store.BotSecret.genBotMsgSecretFromMsgSecret(botOptions.messageSecret);
215
+ botOptions.invokedBotWid = window.Store.WidFactory.createWid(options.invokedBotWid);
216
+ botOptions.botPersonaId = window.Store.BotProfiles.BotProfileCollection.get(options.invokedBotWid).personaId;
217
+ delete options.invokedBotWid;
218
+ }
219
+
220
+ const lidUser = window.Store.User.getMaybeMeLidUser();
221
+ const meUser = window.Store.User.getMaybeMeUser();
222
+ const newId = await window.Store.MsgKey.newId();
223
+ let from = chat.id.isLid() ? lidUser : meUser;
224
+ let participant;
225
+
226
+ if (chat.isGroup) {
227
+ from = chat.groupMetadata && chat.groupMetadata.isLidAddressingMode ? lidUser : meUser;
228
+ participant = window.Store.WidFactory.toUserWid(from);
229
+ }
230
+
231
+ const newMsgKey = new window.Store.MsgKey({
232
+ from: from,
233
+ to: chat.id,
234
+ id: newId,
235
+ participant: participant,
236
+ selfDir: 'out',
237
+ });
238
+
239
+ const extraOptions = options.extraOptions || {};
240
+ delete options.extraOptions;
241
+
242
+ const ephemeralFields = window.Store.EphemeralFields.getEphemeralFields(chat);
243
+
244
+ const message = {
245
+ ...options,
246
+ id: newMsgKey,
247
+ ack: 0,
248
+ body: content,
249
+ from: meUser,
250
+ to: chat.id,
251
+ local: true,
252
+ self: 'out',
253
+ t: parseInt(new Date().getTime() / 1000),
254
+ isNewMsg: true,
255
+ type: 'chat',
256
+ ...ephemeralFields,
257
+ ...mediaOptions,
258
+ ...(mediaOptions.toJSON ? mediaOptions.toJSON() : {}),
259
+ ...quotedMsgOptions,
260
+ ...locationOptions,
261
+ ..._pollOptions,
262
+ ...vcardOptions,
263
+ ...buttonOptions,
264
+ ...listOptions,
265
+ ...botOptions,
266
+ ...extraOptions
267
+ };
268
+
269
+ // Bot's won't reply if canonicalUrl is set (linking)
270
+ if (botOptions) {
271
+ delete message.canonicalUrl;
272
+ }
273
+
274
+ if (isChannel) {
275
+ const msg = new window.Store.Msg.modelClass(message);
276
+ const msgDataFromMsgModel = window.Store.SendChannelMessage.msgDataFromMsgModel(msg);
277
+ const isMedia = Object.keys(mediaOptions).length > 0;
278
+ await window.Store.SendChannelMessage.addNewsletterMsgsRecords([msgDataFromMsgModel]);
279
+ chat.msgs.add(msg);
280
+ chat.t = msg.t;
281
+
282
+ const sendChannelMsgResponse = await window.Store.SendChannelMessage.sendNewsletterMessageJob({
283
+ msg: msg,
284
+ type: message.type === 'chat' ? 'text' : isMedia ? 'media' : 'pollCreation',
285
+ newsletterJid: chat.id.toJid(),
286
+ ...(isMedia
287
+ ? {
288
+ mediaMetadata: msg.avParams(),
289
+ mediaHandle: isMedia ? mediaOptions.mediaHandle : null,
290
+ }
291
+ : {}
292
+ )
293
+ });
294
+
295
+ if (sendChannelMsgResponse.success) {
296
+ msg.t = sendChannelMsgResponse.ack.t;
297
+ msg.serverId = sendChannelMsgResponse.serverId;
298
+ }
299
+ msg.updateAck(1, true);
300
+ await window.Store.SendChannelMessage.updateNewsletterMsgRecord(msg);
301
+ return msg;
302
+ }
303
+
304
+ await window.Store.SendMessage.addAndSendMsgToChat(chat, message);
305
+ await window.Store.HistorySync.sendPeerDataOperationRequest(3, {
306
+ chatId: chat.id
307
+ });
308
+ return window.Store.Msg.get(newMsgKey._serialized);
309
+ };
310
+
311
+ window.WWebJS.editMessage = async (msg, content, options = {}) => {
312
+ const extraOptions = options.extraOptions || {};
313
+ delete options.extraOptions;
314
+
315
+ if (options.mentionedJidList) {
316
+ options.mentionedJidList = await Promise.all(
317
+ options.mentionedJidList.map(async (id) => {
318
+ const wid = window.Store.WidFactory.createWid(id);
319
+ if (await window.Store.QueryExist(wid)) {
320
+ return wid;
321
+ }
322
+ })
323
+ );
324
+ options.mentionedJidList = options.mentionedJidList.filter(Boolean);
325
+ }
326
+
327
+ if (options.groupMentions) {
328
+ options.groupMentions = options.groupMentions.map((e) => ({
329
+ groupSubject: e.subject,
330
+ groupJid: window.Store.WidFactory.createWid(e.id)
331
+ }));
332
+ }
333
+
334
+ if (options.linkPreview) {
335
+ delete options.linkPreview;
336
+ const link = window.Store.Validators.findLink(content);
337
+ if (link) {
338
+ const preview = await window.Store.LinkPreview.getLinkPreview(link);
339
+ preview.preview = true;
340
+ preview.subtype = 'url';
341
+ options = { ...options, ...preview };
342
+ }
343
+ }
344
+
345
+
346
+ const internalOptions = {
347
+ ...options,
348
+ ...extraOptions
349
+ };
350
+
351
+ await window.Store.EditMessage.sendMessageEdit(msg, content, internalOptions);
352
+ return window.Store.Msg.get(msg.id._serialized);
353
+ };
354
+
355
+ window.WWebJS.toStickerData = async (mediaInfo) => {
356
+ if (mediaInfo.mimetype == 'image/webp') return mediaInfo;
357
+
358
+ const file = window.WWebJS.mediaInfoToFile(mediaInfo);
359
+ const webpSticker = await window.Store.StickerTools.toWebpSticker(file);
360
+ const webpBuffer = await webpSticker.arrayBuffer();
361
+ const data = window.WWebJS.arrayBufferToBase64(webpBuffer);
362
+
363
+ return {
364
+ mimetype: 'image/webp',
365
+ data
366
+ };
367
+ };
368
+
369
+ window.WWebJS.processStickerData = async (mediaInfo) => {
370
+ if (mediaInfo.mimetype !== 'image/webp') throw new Error('Invalid media type');
371
+
372
+ const file = window.WWebJS.mediaInfoToFile(mediaInfo);
373
+ let filehash = await window.WWebJS.getFileHash(file);
374
+ let mediaKey = await window.WWebJS.generateHash(32);
375
+
376
+ const controller = new AbortController();
377
+ const uploadedInfo = await window.Store.UploadUtils.encryptAndUpload({
378
+ blob: file,
379
+ type: 'sticker',
380
+ signal: controller.signal,
381
+ mediaKey
382
+ });
383
+
384
+ const stickerInfo = {
385
+ ...uploadedInfo,
386
+ clientUrl: uploadedInfo.url,
387
+ deprecatedMms3Url: uploadedInfo.url,
388
+ uploadhash: uploadedInfo.encFilehash,
389
+ size: file.size,
390
+ type: 'sticker',
391
+ filehash
392
+ };
393
+
394
+ return stickerInfo;
395
+ };
396
+
397
+ window.WWebJS.processMediaData = async (mediaInfo, { forceSticker, forceGif, forceVoice, forceDocument, forceMediaHd, sendToChannel }) => {
398
+ const file = window.WWebJS.mediaInfoToFile(mediaInfo);
399
+ const opaqueData = await window.Store.OpaqueData.createFromData(file, file.type);
400
+ const mediaParams = {
401
+ asSticker: forceSticker,
402
+ asGif: forceGif,
403
+ isPtt: forceVoice,
404
+ asDocument: forceDocument
405
+ };
406
+
407
+ if (forceMediaHd && file.type.indexOf('image/') === 0) {
408
+ mediaParams.maxDimension = 2560;
409
+ }
410
+
411
+ const mediaPrep = window.Store.MediaPrep.prepRawMedia(opaqueData, mediaParams);
412
+ const mediaData = await mediaPrep.waitForPrep();
413
+ const mediaObject = window.Store.MediaObject.getOrCreateMediaObject(mediaData.filehash);
414
+ const mediaType = window.Store.MediaTypes.msgToMediaType({
415
+ type: mediaData.type,
416
+ isGif: mediaData.isGif,
417
+ isNewsletter: sendToChannel,
418
+ });
419
+
420
+ if (forceVoice && mediaData.type === 'ptt') {
421
+ const waveform = mediaObject.contentInfo.waveform;
422
+ mediaData.waveform =
423
+ waveform || await window.WWebJS.generateWaveform(file);
424
+ }
425
+
426
+ if (!(mediaData.mediaBlob instanceof window.Store.OpaqueData)) {
427
+ mediaData.mediaBlob = await window.Store.OpaqueData.createFromData(
428
+ mediaData.mediaBlob,
429
+ mediaData.mediaBlob.type
430
+ );
431
+ }
432
+
433
+ mediaData.renderableUrl = mediaData.mediaBlob.url();
434
+ mediaObject.consolidate(mediaData.toJSON());
435
+ mediaData.mediaBlob.autorelease();
436
+
437
+ const dataToUpload = {
438
+ mimetype: mediaData.mimetype,
439
+ mediaObject,
440
+ mediaType,
441
+ ...(sendToChannel ? { calculateToken: window.Store.SendChannelMessage.getRandomFilehash } : {})
442
+ };
443
+
444
+ const uploadedMedia = !sendToChannel
445
+ ? await window.Store.MediaUpload.uploadMedia(dataToUpload)
446
+ : await window.Store.MediaUpload.uploadUnencryptedMedia(dataToUpload);
447
+
448
+ const mediaEntry = uploadedMedia.mediaEntry;
449
+ if (!mediaEntry) {
450
+ throw new Error('upload failed: media entry was not created');
451
+ }
452
+
453
+ mediaData.set({
454
+ clientUrl: mediaEntry.mmsUrl,
455
+ deprecatedMms3Url: mediaEntry.deprecatedMms3Url,
456
+ directPath: mediaEntry.directPath,
457
+ mediaKey: mediaEntry.mediaKey,
458
+ mediaKeyTimestamp: mediaEntry.mediaKeyTimestamp,
459
+ filehash: mediaObject.filehash,
460
+ encFilehash: mediaEntry.encFilehash,
461
+ uploadhash: mediaEntry.uploadHash,
462
+ size: mediaObject.size,
463
+ streamingSidecar: mediaEntry.sidecar,
464
+ firstFrameSidecar: mediaEntry.firstFrameSidecar,
465
+ mediaHandle: sendToChannel ? mediaEntry.handle : null,
466
+ });
467
+
468
+ return mediaData;
469
+ };
470
+
471
+ window.WWebJS.getMessageModel = (message) => {
472
+ const msg = message.serialize();
473
+
474
+ msg.isEphemeral = message.isEphemeral;
475
+ msg.isStatusV3 = message.isStatusV3;
476
+ msg.links = (window.Store.Validators.findLinks(message.mediaObject ? message.caption : message.body)).map((link) => ({
477
+ link: link.href,
478
+ isSuspicious: Boolean(link.suspiciousCharacters && link.suspiciousCharacters.size)
479
+ }));
480
+
481
+ if (msg.buttons) {
482
+ msg.buttons = msg.buttons.serialize();
483
+ }
484
+ if (msg.dynamicReplyButtons) {
485
+ msg.dynamicReplyButtons = JSON.parse(JSON.stringify(msg.dynamicReplyButtons));
486
+ }
487
+ if (msg.replyButtons) {
488
+ msg.replyButtons = JSON.parse(JSON.stringify(msg.replyButtons));
489
+ }
490
+
491
+ if (typeof msg.id.remote === 'object') {
492
+ msg.id = Object.assign({}, msg.id, { remote: msg.id.remote._serialized });
493
+ }
494
+
495
+ delete msg.pendingAckUpdate;
496
+
497
+ return msg;
498
+ };
499
+
500
+ window.WWebJS.getPollVoteModel = async (vote) => {
501
+ const _vote = vote.serialize();
502
+ if (!vote.parentMsgKey) return null;
503
+ const msg =
504
+ window.Store.Msg.get(vote.parentMsgKey) || (await window.Store.Msg.getMessagesById([vote.parentMsgKey]))?.messages?.[0];
505
+ msg && (_vote.parentMessage = window.WWebJS.getMessageModel(msg));
506
+ return _vote;
507
+ };
508
+
509
+ window.WWebJS.getChat = async (chatId, { getAsModel = true } = {}) => {
510
+ const isChannel = /@\w*newsletter\b/.test(chatId);
511
+ const chatWid = window.Store.WidFactory.createWid(chatId);
512
+ let chat;
513
+
514
+ if (isChannel) {
515
+ try {
516
+ chat = window.Store.NewsletterCollection.get(chatId);
517
+ if (!chat) {
518
+ await window.Store.ChannelUtils.loadNewsletterPreviewChat(chatId);
519
+ chat = await window.Store.NewsletterCollection.find(chatWid);
520
+ }
521
+ } catch (err) {
522
+ chat = null;
523
+ }
524
+ } else {
525
+ chat = window.Store.Chat.get(chatWid) || (await window.Store.Chat.find(chatWid));
526
+ }
527
+
528
+ return getAsModel && chat
529
+ ? await window.WWebJS.getChatModel(chat, { isChannel: isChannel })
530
+ : chat;
531
+ };
532
+
533
+ window.WWebJS.getChannelMetadata = async (inviteCode) => {
534
+ const response =
535
+ await window.Store.ChannelUtils.queryNewsletterMetadataByInviteCode(
536
+ inviteCode,
537
+ window.Store.ChannelUtils.getRoleByIdentifier(inviteCode)
538
+ );
539
+
540
+ const picUrl = response.newsletterPictureMetadataMixin?.picture[0]?.queryPictureDirectPathOrEmptyResponseMixinGroup.value.directPath;
541
+
542
+ return {
543
+ id: response.idJid,
544
+ createdAtTs: response.newsletterCreationTimeMetadataMixin.creationTimeValue,
545
+ titleMetadata: {
546
+ title: response.newsletterNameMetadataMixin.nameElementValue,
547
+ updatedAtTs: response.newsletterNameMetadataMixin.nameUpdateTime
548
+ },
549
+ descriptionMetadata: {
550
+ description: response.newsletterDescriptionMetadataMixin.descriptionQueryDescriptionResponseMixin.elementValue,
551
+ updatedAtTs: response.newsletterDescriptionMetadataMixin.descriptionQueryDescriptionResponseMixin.updateTime
552
+ },
553
+ inviteLink: `https://whatsapp.com/channel/${response.newsletterInviteLinkMetadataMixin.inviteCode}`,
554
+ membershipType: window.Store.ChannelUtils.getRoleByIdentifier(inviteCode),
555
+ stateType: response.newsletterStateMetadataMixin.stateType,
556
+ pictureUrl: picUrl ? `https://pps.whatsapp.net${picUrl}` : null,
557
+ subscribersCount: response.newsletterSubscribersMetadataMixin.subscribersCount,
558
+ isVerified: response.newsletterVerificationMetadataMixin.verificationState === 'verified'
559
+ };
560
+ };
561
+
562
+ window.WWebJS.getChats = async () => {
563
+ const chats = window.Store.Chat.getModelsArray();
564
+ const chatPromises = chats.map(chat => window.WWebJS.getChatModel(chat));
565
+ return await Promise.all(chatPromises);
566
+ };
567
+
568
+ window.WWebJS.getChannels = async () => {
569
+ const channels = window.Store.NewsletterCollection.getModelsArray();
570
+ const channelPromises = channels?.map((channel) => window.WWebJS.getChatModel(channel, { isChannel: true }));
571
+ return await Promise.all(channelPromises);
572
+ };
573
+
574
+ window.WWebJS.getChatModel = async (chat, { isChannel = false } = {}) => {
575
+ if (!chat) return null;
576
+
577
+ const model = chat.serialize();
578
+ model.isGroup = false;
579
+ model.isMuted = chat.mute?.expiration !== 0;
580
+ if (isChannel) {
581
+ model.isChannel = window.Store.ChatGetters.getIsNewsletter(chat);
582
+ } else {
583
+ model.formattedTitle = chat.formattedTitle;
584
+ }
585
+
586
+ if (chat.groupMetadata) {
587
+ model.isGroup = true;
588
+ const chatWid = window.Store.WidFactory.createWid(chat.id._serialized);
589
+ await window.Store.GroupMetadata.update(chatWid);
590
+ chat.groupMetadata.participants._models
591
+ .filter(x => x.id?._serialized?.endsWith('@lid'))
592
+ .forEach(x => x.contact?.phoneNumber && (x.id = x.contact.phoneNumber));
593
+ model.groupMetadata = chat.groupMetadata.serialize();
594
+ model.isReadOnly = chat.groupMetadata.announce;
595
+ }
596
+
597
+ if (chat.newsletterMetadata) {
598
+ await window.Store.NewsletterMetadataCollection.update(chat.id);
599
+ model.channelMetadata = chat.newsletterMetadata.serialize();
600
+ model.channelMetadata.createdAtTs = chat.newsletterMetadata.creationTime;
601
+ }
602
+
603
+ model.lastMessage = null;
604
+ if (model.msgs && model.msgs.length) {
605
+ const lastMessage = chat.lastReceivedKey
606
+ ? window.Store.Msg.get(chat.lastReceivedKey._serialized) || (await window.Store.Msg.getMessagesById([chat.lastReceivedKey._serialized]))?.messages?.[0]
607
+ : null;
608
+ lastMessage && (model.lastMessage = window.WWebJS.getMessageModel(lastMessage));
609
+ }
610
+
611
+ delete model.msgs;
612
+ delete model.msgUnsyncedButtonReplyMsgs;
613
+ delete model.unsyncedButtonReplies;
614
+
615
+ return model;
616
+ };
617
+
618
+ window.WWebJS.getContactModel = contact => {
619
+ let res = contact.serialize();
620
+ res.isBusiness = contact.isBusiness === undefined ? false : contact.isBusiness;
621
+
622
+ if (contact.businessProfile) {
623
+ res.businessProfile = contact.businessProfile.serialize();
624
+ }
625
+
626
+ res.isMe = window.Store.ContactMethods.getIsMe(contact);
627
+ res.isUser = window.Store.ContactMethods.getIsUser(contact);
628
+ res.isGroup = window.Store.ContactMethods.getIsGroup(contact);
629
+ res.isWAContact = window.Store.ContactMethods.getIsWAContact(contact);
630
+ res.isMyContact = window.Store.ContactMethods.getIsMyContact(contact);
631
+ res.isBlocked = contact.isContactBlocked;
632
+ res.userid = window.Store.ContactMethods.getUserid(contact);
633
+ res.isEnterprise = window.Store.ContactMethods.getIsEnterprise(contact);
634
+ res.verifiedName = window.Store.ContactMethods.getVerifiedName(contact);
635
+ res.verifiedLevel = window.Store.ContactMethods.getVerifiedLevel(contact);
636
+ res.statusMute = window.Store.ContactMethods.getStatusMute(contact);
637
+ res.name = window.Store.ContactMethods.getName(contact);
638
+ res.shortName = window.Store.ContactMethods.getShortName(contact);
639
+ res.pushname = window.Store.ContactMethods.getPushname(contact);
640
+
641
+ return res;
642
+ };
643
+
644
+ window.WWebJS.getContact = async contactId => {
645
+ const wid = window.Store.WidFactory.createWid(contactId);
646
+ let contact = await window.Store.Contact.find(wid);
647
+ if (contact.id._serialized.endsWith('@lid')) {
648
+ contact.id = contact.phoneNumber;
649
+ }
650
+ const bizProfile = await window.Store.BusinessProfile.fetchBizProfile(wid);
651
+ bizProfile.profileOptions && (contact.businessProfile = bizProfile);
652
+ return window.WWebJS.getContactModel(contact);
653
+ };
654
+
655
+ window.WWebJS.getContacts = () => {
656
+ const contacts = window.Store.Contact.getModelsArray();
657
+ return contacts.map(contact => window.WWebJS.getContactModel(contact));
658
+ };
659
+
660
+ window.WWebJS.mediaInfoToFile = ({ data, mimetype, filename }) => {
661
+ const binaryData = window.atob(data);
662
+
663
+ const buffer = new ArrayBuffer(binaryData.length);
664
+ const view = new Uint8Array(buffer);
665
+ for (let i = 0; i < binaryData.length; i++) {
666
+ view[i] = binaryData.charCodeAt(i);
667
+ }
668
+
669
+ const blob = new Blob([buffer], { type: mimetype });
670
+ return new File([blob], filename, {
671
+ type: mimetype,
672
+ lastModified: Date.now()
673
+ });
674
+ };
675
+
676
+ window.WWebJS.arrayBufferToBase64 = (arrayBuffer) => {
677
+ let binary = '';
678
+ const bytes = new Uint8Array(arrayBuffer);
679
+ const len = bytes.byteLength;
680
+ for (let i = 0; i < len; i++) {
681
+ binary += String.fromCharCode(bytes[i]);
682
+ }
683
+ return window.btoa(binary);
684
+ };
685
+
686
+ window.WWebJS.arrayBufferToBase64Async = (arrayBuffer) =>
687
+ new Promise((resolve, reject) => {
688
+ const blob = new Blob([arrayBuffer], {
689
+ type: 'application/octet-stream',
690
+ });
691
+ const fileReader = new FileReader();
692
+ fileReader.onload = () => {
693
+ const [, data] = fileReader.result.split(',');
694
+ resolve(data);
695
+ };
696
+ fileReader.onerror = (e) => reject(e);
697
+ fileReader.readAsDataURL(blob);
698
+ });
699
+
700
+ window.WWebJS.getFileHash = async (data) => {
701
+ let buffer = await data.arrayBuffer();
702
+ const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
703
+ return btoa(String.fromCharCode(...new Uint8Array(hashBuffer)));
704
+ };
705
+
706
+ window.WWebJS.generateHash = async (length) => {
707
+ var result = '';
708
+ var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
709
+ var charactersLength = characters.length;
710
+ for (var i = 0; i < length; i++) {
711
+ result += characters.charAt(Math.floor(Math.random() * charactersLength));
712
+ }
713
+ return result;
714
+ };
715
+
716
+ window.WWebJS.generateWaveform = async (audioFile) => {
717
+ try {
718
+ const audioData = await audioFile.arrayBuffer();
719
+ const audioContext = new AudioContext();
720
+ const audioBuffer = await audioContext.decodeAudioData(audioData);
721
+
722
+ const rawData = audioBuffer.getChannelData(0);
723
+ const samples = 64;
724
+ const blockSize = Math.floor(rawData.length / samples);
725
+ const filteredData = [];
726
+ for (let i = 0; i < samples; i++) {
727
+ const blockStart = blockSize * i;
728
+ let sum = 0;
729
+ for (let j = 0; j < blockSize; j++) {
730
+ sum = sum + Math.abs(rawData[blockStart + j]);
731
+ }
732
+ filteredData.push(sum / blockSize);
733
+ }
734
+
735
+ const multiplier = Math.pow(Math.max(...filteredData), -1);
736
+ const normalizedData = filteredData.map((n) => n * multiplier);
737
+
738
+ const waveform = new Uint8Array(
739
+ normalizedData.map((n) => Math.floor(100 * n))
740
+ );
741
+
742
+ return waveform;
743
+ } catch (e) {
744
+ return undefined;
745
+ }
746
+ };
747
+
748
+ window.WWebJS.sendClearChat = async (chatId) => {
749
+ let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
750
+ if (chat !== undefined) {
751
+ await window.Store.SendClear.sendClear(chat, false);
752
+ return true;
753
+ }
754
+ return false;
755
+ };
756
+
757
+ window.WWebJS.sendDeleteChat = async (chatId) => {
758
+ let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
759
+ if (chat !== undefined) {
760
+ await window.Store.SendDelete.sendDelete(chat);
761
+ return true;
762
+ }
763
+ return false;
764
+ };
765
+
766
+ window.WWebJS.sendChatstate = async (state, chatId) => {
767
+ chatId = window.Store.WidFactory.createWid(chatId);
768
+
769
+ switch (state) {
770
+ case 'typing':
771
+ await window.Store.ChatState.sendChatStateComposing(chatId);
772
+ break;
773
+ case 'recording':
774
+ await window.Store.ChatState.sendChatStateRecording(chatId);
775
+ break;
776
+ case 'stop':
777
+ await window.Store.ChatState.sendChatStatePaused(chatId);
778
+ break;
779
+ default:
780
+ throw 'Invalid chatstate';
781
+ }
782
+
783
+ return true;
784
+ };
785
+
786
+ window.WWebJS.getLabelModel = label => {
787
+ let res = label.serialize();
788
+ res.hexColor = label.hexColor;
789
+
790
+ return res;
791
+ };
792
+
793
+ window.WWebJS.getLabels = () => {
794
+ const labels = window.Store.Label.getModelsArray();
795
+ return labels.map(label => window.WWebJS.getLabelModel(label));
796
+ };
797
+
798
+ window.WWebJS.getLabel = (labelId) => {
799
+ const label = window.Store.Label.get(labelId);
800
+ return window.WWebJS.getLabelModel(label);
801
+ };
802
+
803
+ window.WWebJS.getChatLabels = async (chatId) => {
804
+ const chat = await window.WWebJS.getChat(chatId);
805
+ return (chat.labels || []).map(id => window.WWebJS.getLabel(id));
806
+ };
807
+
808
+ window.WWebJS.getOrderDetail = async (orderId, token, chatId) => {
809
+ const chatWid = window.Store.WidFactory.createWid(chatId);
810
+ return window.Store.QueryOrder.queryOrder(chatWid, orderId, 80, 80, token);
811
+ };
812
+
813
+ window.WWebJS.getProductMetadata = async (productId) => {
814
+ let sellerId = window.Store.Conn.wid;
815
+ let product = await window.Store.QueryProduct.queryProduct(sellerId, productId);
816
+ if (product && product.data) {
817
+ return product.data;
818
+ }
819
+
820
+ return undefined;
821
+ };
822
+
823
+ window.WWebJS.rejectCall = async (peerJid, id) => {
824
+ peerJid = peerJid.split('@')[0] + '@s.whatsapp.net';
825
+ let userId = window.Store.User.getMaybeMeUser().user + '@s.whatsapp.net';
826
+ const stanza = window.Store.SocketWap.wap('call', {
827
+ id: window.Store.SocketWap.generateId(),
828
+ from: window.Store.SocketWap.USER_JID(userId),
829
+ to: window.Store.SocketWap.USER_JID(peerJid),
830
+ }, [
831
+ window.Store.SocketWap.wap('reject', {
832
+ 'call-id': id,
833
+ 'call-creator': window.Store.SocketWap.USER_JID(peerJid),
834
+ count: '0',
835
+ })
836
+ ]);
837
+ await window.Store.Socket.deprecatedCastStanza(stanza);
838
+ };
839
+
840
+ window.WWebJS.cropAndResizeImage = async (media, options = {}) => {
841
+ if (!media.mimetype.includes('image'))
842
+ throw new Error('Media is not an image');
843
+
844
+ if (options.mimetype && !options.mimetype.includes('image'))
845
+ delete options.mimetype;
846
+
847
+ options = Object.assign({ size: 640, mimetype: media.mimetype, quality: .75, asDataUrl: false }, options);
848
+
849
+ const img = await new Promise ((resolve, reject) => {
850
+ const img = new Image();
851
+ img.onload = () => resolve(img);
852
+ img.onerror = reject;
853
+ img.src = `data:${media.mimetype};base64,${media.data}`;
854
+ });
855
+
856
+ const sl = Math.min(img.width, img.height);
857
+ const sx = Math.floor((img.width - sl) / 2);
858
+ const sy = Math.floor((img.height - sl) / 2);
859
+
860
+ const canvas = document.createElement('canvas');
861
+ canvas.width = options.size;
862
+ canvas.height = options.size;
863
+
864
+ const ctx = canvas.getContext('2d');
865
+ ctx.drawImage(img, sx, sy, sl, sl, 0, 0, options.size, options.size);
866
+
867
+ const dataUrl = canvas.toDataURL(options.mimetype, options.quality);
868
+
869
+ if (options.asDataUrl)
870
+ return dataUrl;
871
+
872
+ return Object.assign(media, {
873
+ mimetype: options.mimeType,
874
+ data: dataUrl.replace(`data:${options.mimeType};base64,`, '')
875
+ });
876
+ };
877
+
878
+ window.WWebJS.setPicture = async (chatId, media) => {
879
+ const thumbnail = await window.WWebJS.cropAndResizeImage(media, { asDataUrl: true, mimetype: 'image/jpeg', size: 96 });
880
+ const profilePic = await window.WWebJS.cropAndResizeImage(media, { asDataUrl: true, mimetype: 'image/jpeg', size: 640 });
881
+
882
+ const chatWid = window.Store.WidFactory.createWid(chatId);
883
+ try {
884
+ const collection = window.Store.ProfilePicThumb.get(chatId) || await window.Store.ProfilePicThumb.find(chatId);
885
+ if (!collection?.canSet()) return false;
886
+
887
+ const res = await window.Store.GroupUtils.sendSetPicture(chatWid, thumbnail, profilePic);
888
+ return res ? res.status === 200 : false;
889
+ } catch (err) {
890
+ if (err.name === 'ServerStatusCodeError') return false;
891
+ throw err;
892
+ }
893
+ };
894
+
895
+ window.WWebJS.deletePicture = async (chatid) => {
896
+ const chatWid = window.Store.WidFactory.createWid(chatid);
897
+ try {
898
+ const collection = window.Store.ProfilePicThumb.get(chatid);
899
+ if (!collection.canDelete()) return;
900
+
901
+ const res = await window.Store.GroupUtils.requestDeletePicture(chatWid);
902
+ return res ? res.status === 200 : false;
903
+ } catch (err) {
904
+ if(err.name === 'ServerStatusCodeError') return false;
905
+ throw err;
906
+ }
907
+ };
908
+
909
+ window.WWebJS.getProfilePicThumbToBase64 = async (chatWid) => {
910
+ const profilePicCollection = await window.Store.ProfilePicThumb.find(chatWid);
911
+
912
+ const _readImageAsBase64 = (imageBlob) => {
913
+ return new Promise((resolve) => {
914
+ const reader = new FileReader();
915
+ reader.onloadend = function () {
916
+ const base64Image = reader.result;
917
+ if (base64Image == null) {
918
+ resolve(undefined);
919
+ } else {
920
+ const base64Data = base64Image.toString().split(',')[1];
921
+ resolve(base64Data);
922
+ }
923
+ };
924
+ reader.readAsDataURL(imageBlob);
925
+ });
926
+ };
927
+
928
+ if (profilePicCollection?.img) {
929
+ try {
930
+ const response = await fetch(profilePicCollection.img);
931
+ if (response.ok) {
932
+ const imageBlob = await response.blob();
933
+ if (imageBlob) {
934
+ const base64Image = await _readImageAsBase64(imageBlob);
935
+ return base64Image;
936
+ }
937
+ }
938
+ } catch (error) { /* empty */ }
939
+ }
940
+ return undefined;
941
+ };
942
+
943
+ window.WWebJS.getAddParticipantsRpcResult = async (groupMetadata, groupWid, participantWid) => {
944
+ const participantLidArgs = groupMetadata?.isLidAddressingMode
945
+ ? {
946
+ phoneNumber: participantWid,
947
+ lid: window.Store.LidUtils.getCurrentLid(participantWid)
948
+ }
949
+ : { phoneNumber: participantWid };
950
+
951
+ const iqTo = window.Store.WidToJid.widToGroupJid(groupWid);
952
+
953
+ const participantArgs =
954
+ participantLidArgs.lid
955
+ ? [{
956
+ participantJid: window.Store.WidToJid.widToUserJid(participantLidArgs.lid),
957
+ phoneNumberMixinArgs: {
958
+ anyPhoneNumber: window.Store.WidToJid.widToUserJid(participantLidArgs.phoneNumber)
959
+ }
960
+ }]
961
+ : [{
962
+ participantJid: window.Store.WidToJid.widToUserJid(participantLidArgs.phoneNumber)
963
+ }];
964
+
965
+ let rpcResult, resultArgs;
966
+ const isOldImpl = window.compareWwebVersions(window.Debug.VERSION, '<=', '2.2335.9');
967
+ const data = {
968
+ name: undefined,
969
+ code: undefined,
970
+ inviteV4Code: undefined,
971
+ inviteV4CodeExp: undefined
972
+ };
973
+
974
+ try {
975
+ rpcResult = await window.Store.GroupParticipants.sendAddParticipantsRPC({ participantArgs, iqTo });
976
+ resultArgs = isOldImpl
977
+ ? rpcResult.value.addParticipant[0].addParticipantsParticipantMixins
978
+ : rpcResult.value.addParticipant[0]
979
+ .addParticipantsParticipantAddedOrNonRegisteredWaUserParticipantErrorLidResponseMixinGroup
980
+ .value
981
+ .addParticipantsParticipantMixins;
982
+ } catch (err) {
983
+ data.code = 400;
984
+ return data;
985
+ }
986
+
987
+ if (rpcResult.name === 'AddParticipantsResponseSuccess') {
988
+ const code = resultArgs?.value.error || '200';
989
+ data.name = resultArgs?.name;
990
+ data.code = +code;
991
+ data.inviteV4Code = resultArgs?.value.addRequestCode;
992
+ data.inviteV4CodeExp = resultArgs?.value.addRequestExpiration?.toString();
993
+ }
994
+
995
+ else if (rpcResult.name === 'AddParticipantsResponseClientError') {
996
+ const { code: code } = rpcResult.value.errorAddParticipantsClientErrors.value;
997
+ data.code = +code;
998
+ }
999
+
1000
+ else if (rpcResult.name === 'AddParticipantsResponseServerError') {
1001
+ const { code: code } = rpcResult.value.errorServerErrors.value;
1002
+ data.code = +code;
1003
+ }
1004
+
1005
+ return data;
1006
+ };
1007
+
1008
+ window.WWebJS.membershipRequestAction = async (groupId, action, requesterIds, sleep) => {
1009
+ const groupWid = window.Store.WidFactory.createWid(groupId);
1010
+ const group = await window.Store.Chat.find(groupWid);
1011
+ const toApprove = action === 'Approve';
1012
+ let membershipRequests;
1013
+ let response;
1014
+ let result = [];
1015
+
1016
+ await window.Store.GroupQueryAndUpdate({ id: groupId });
1017
+
1018
+ if (!requesterIds?.length) {
1019
+ membershipRequests = group.groupMetadata.membershipApprovalRequests._models.map(({ id }) => id);
1020
+ } else {
1021
+ !Array.isArray(requesterIds) && (requesterIds = [requesterIds]);
1022
+ membershipRequests = requesterIds.map(r => window.Store.WidFactory.createWid(r));
1023
+ }
1024
+
1025
+ if (!membershipRequests.length) return [];
1026
+
1027
+ const participantArgs = membershipRequests.map(m => ({
1028
+ participantArgs: [
1029
+ {
1030
+ participantJid: window.Store.WidToJid.widToUserJid(m)
1031
+ }
1032
+ ]
1033
+ }));
1034
+
1035
+ const groupJid = window.Store.WidToJid.widToGroupJid(groupWid);
1036
+
1037
+ const _getSleepTime = (sleep) => {
1038
+ if (!Array.isArray(sleep) || (sleep.length === 2 && sleep[0] === sleep[1])) {
1039
+ return sleep;
1040
+ }
1041
+ if (sleep.length === 1) {
1042
+ return sleep[0];
1043
+ }
1044
+ sleep[1] - sleep[0] < 100 && (sleep[0] = sleep[1]) && (sleep[1] += 100);
1045
+ return Math.floor(Math.random() * (sleep[1] - sleep[0] + 1)) + sleep[0];
1046
+ };
1047
+
1048
+ const membReqResCodes = {
1049
+ default: `An unknown error occupied while ${toApprove ? 'approving' : 'rejecting'} the participant membership request`,
1050
+ 400: 'ParticipantNotFoundError',
1051
+ 401: 'ParticipantNotAuthorizedError',
1052
+ 403: 'ParticipantForbiddenError',
1053
+ 404: 'ParticipantRequestNotFoundError',
1054
+ 408: 'ParticipantTemporarilyBlockedError',
1055
+ 409: 'ParticipantConflictError',
1056
+ 412: 'ParticipantParentLinkedGroupsResourceConstraintError',
1057
+ 500: 'ParticipantResourceConstraintError'
1058
+ };
1059
+
1060
+ try {
1061
+ for (const participant of participantArgs) {
1062
+ response = await window.Store.MembershipRequestUtils.sendMembershipRequestsActionRPC({
1063
+ iqTo: groupJid,
1064
+ [toApprove ? 'approveArgs' : 'rejectArgs']: participant
1065
+ });
1066
+
1067
+ if (response.name === 'MembershipRequestsActionResponseSuccess') {
1068
+ const value = toApprove
1069
+ ? response.value.membershipRequestsActionApprove
1070
+ : response.value.membershipRequestsActionReject;
1071
+ if (value?.participant) {
1072
+ const [_] = value.participant.map(p => {
1073
+ const error = toApprove
1074
+ ? value.participant[0].membershipRequestsActionAcceptParticipantMixins?.value.error
1075
+ : value.participant[0].membershipRequestsActionRejectParticipantMixins?.value.error;
1076
+ return {
1077
+ requesterId: window.Store.WidFactory.createWid(p.jid)._serialized,
1078
+ ...(error
1079
+ ? { error: +error, message: membReqResCodes[error] || membReqResCodes.default }
1080
+ : { message: `${toApprove ? 'Approved' : 'Rejected'} successfully` })
1081
+ };
1082
+ });
1083
+ _ && result.push(_);
1084
+ }
1085
+ } else {
1086
+ result.push({
1087
+ requesterId: window.Store.JidToWid.userJidToUserWid(participant.participantArgs[0].participantJid)._serialized,
1088
+ message: 'ServerStatusCodeError'
1089
+ });
1090
+ }
1091
+
1092
+ sleep &&
1093
+ participantArgs.length > 1 &&
1094
+ participantArgs.indexOf(participant) !== participantArgs.length - 1 &&
1095
+ (await new Promise((resolve) => setTimeout(resolve, _getSleepTime(sleep))));
1096
+ }
1097
+ return result;
1098
+ } catch (err) {
1099
+ return [];
1100
+ }
1101
+ };
1102
+
1103
+ window.WWebJS.subscribeToUnsubscribeFromChannel = async (channelId, action, options = {}) => {
1104
+ const channel = await window.WWebJS.getChat(channelId, { getAsModel: false });
1105
+
1106
+ if (!channel || channel.newsletterMetadata.membershipType === 'owner') return false;
1107
+ options = { eventSurface: 3, deleteLocalModels: options.deleteLocalModels ?? true };
1108
+
1109
+ try {
1110
+ if (action === 'Subscribe') {
1111
+ await window.Store.ChannelUtils.subscribeToNewsletterAction(channel, options);
1112
+ } else if (action === 'Unsubscribe') {
1113
+ await window.Store.ChannelUtils.unsubscribeFromNewsletterAction(channel, options);
1114
+ } else return false;
1115
+ return true;
1116
+ } catch (err) {
1117
+ if (err.name === 'ServerStatusCodeError') return false;
1118
+ throw err;
1119
+ }
1120
+ };
1121
+
1122
+ window.WWebJS.pinUnpinMsgAction = async (msgId, action, duration) => {
1123
+ const message = window.Store.Msg.get(msgId) || (await window.Store.Msg.getMessagesById([msgId]))?.messages?.[0];
1124
+ if (!message) return false;
1125
+ const response = await window.Store.pinUnpinMsg(message, action, duration);
1126
+ return response.messageSendResult === 'OK';
1127
+ };
1128
+
1129
+ window.WWebJS.getStatusModel = status => {
1130
+ const res = status.serialize();
1131
+ delete res._msgs;
1132
+ return res;
1133
+ };
1134
+
1135
+ window.WWebJS.getAllStatuses = () => {
1136
+ const statuses = window.Store.Status.getModelsArray();
1137
+ return statuses.map(status => window.WWebJS.getStatusModel(status));
1138
+ };
1139
+ };