whatsapp-web.js 1.28.1-alpha.0 → 1.30.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.
@@ -5,7 +5,7 @@ exports.LoadUtils = () => {
5
5
 
6
6
  window.WWebJS.forwardMessage = async (chatId, msgId) => {
7
7
  const msg = window.Store.Msg.get(msgId) || (await window.Store.Msg.getMessagesById([msgId]))?.messages?.[0];
8
- let chat = window.Store.Chat.get(chatId);
8
+ const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
9
9
 
10
10
  if (window.compareWwebVersions(window.Debug.VERSION, '>', '2.3000.0')) {
11
11
  return window.Store.ForwardUtils.forwardMessagesToChats([msg], [chat], true);
@@ -15,50 +15,51 @@ exports.LoadUtils = () => {
15
15
  };
16
16
 
17
17
  window.WWebJS.sendSeen = async (chatId) => {
18
- let chat = window.Store.Chat.get(chatId);
19
- if (chat !== undefined) {
20
- await window.Store.SendSeen.sendSeen(chat, false);
18
+ const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
19
+ if (chat) {
20
+ await window.Store.SendSeen.sendSeen(chat);
21
21
  return true;
22
22
  }
23
23
  return false;
24
-
25
24
  };
26
25
 
27
26
  window.WWebJS.sendMessage = async (chat, content, options = {}) => {
28
- let attOptions = {};
29
- if (options.attachment) {
30
- attOptions = options.sendMediaAsSticker
31
- ? await window.WWebJS.processStickerData(options.attachment)
32
- : await window.WWebJS.processMediaData(options.attachment, {
27
+ const isChannel = window.Store.ChatGetters.getIsNewsletter(chat);
28
+
29
+ let mediaOptions = {};
30
+ if (options.media) {
31
+ mediaOptions = await window.WWebJS.processMediaData(
32
+ options.media, {
33
+ forceSticker: options.sendMediaAsSticker,
34
+ forceGif: options.sendVideoAsGif,
33
35
  forceVoice: options.sendAudioAsVoice,
34
36
  forceDocument: options.sendMediaAsDocument,
35
- forceGif: options.sendVideoAsGif
37
+ sendToChannel: isChannel
36
38
  });
37
-
38
- attOptions.caption = options.caption;
39
- content = options.sendMediaAsSticker ? undefined : attOptions.preview;
40
- attOptions.isViewOnce = options.isViewOnce;
41
-
42
- delete options.attachment;
39
+ mediaOptions.caption = options.caption;
40
+ content = options.sendMediaAsSticker ? undefined : mediaOptions.preview;
41
+ mediaOptions.isViewOnce = options.isViewOnce;
42
+ delete options.media;
43
43
  delete options.sendMediaAsSticker;
44
44
  }
45
+
45
46
  let quotedMsgOptions = {};
46
47
  if (options.quotedMessageId) {
47
- let quotedMessage = await window.Store.Msg.getMessagesById([options.quotedMessageId]);
48
+ let quotedMessage = window.Store.Msg.get(options.quotedMessageId);
49
+ !quotedMessage && (quotedMessage = (await window.Store.Msg.getMessagesById([options.quotedMessageId]))?.messages?.[0]);
48
50
 
49
- if (quotedMessage['messages'].length == 1) {
51
+ if (quotedMessage['messages']?.length == 1) {
50
52
  quotedMessage = quotedMessage['messages'][0];
51
53
 
52
- // TODO remove .canReply() once all clients are updated to >= v2.2241.6
53
- const canReply = window.Store.ReplyUtils ?
54
- window.Store.ReplyUtils.canReplyMsg(quotedMessage.unsafe()) :
55
- quotedMessage.canReply();
54
+ const canReply = window.Store.ReplyUtils
55
+ ? window.Store.ReplyUtils.canReplyMsg(quotedMessage.unsafe())
56
+ : quotedMessage.canReply();
56
57
 
57
58
  if (canReply) {
58
59
  quotedMsgOptions = quotedMessage.msgContextInfo(chat);
59
60
  }
60
- }else{
61
- if(!options.ignoreQuoteErrors) {
61
+ } else {
62
+ if (!options.ignoreQuoteErrors) {
62
63
  throw new Error('Could not get the quoted message.');
63
64
  }
64
65
  }
@@ -106,14 +107,15 @@ exports.LoadUtils = () => {
106
107
  const { pollName, pollOptions } = options.poll;
107
108
  const { allowMultipleAnswers, messageSecret } = options.poll.options;
108
109
  _pollOptions = {
110
+ kind: 'pollCreation',
109
111
  type: 'poll_creation',
110
112
  pollName: pollName,
111
113
  pollOptions: pollOptions,
112
114
  pollSelectableOptionsCount: allowMultipleAnswers ? 0 : 1,
113
115
  messageSecret:
114
- Array.isArray(messageSecret) && messageSecret.length === 32
115
- ? new Uint8Array(messageSecret)
116
- : window.crypto.getRandomValues(new Uint8Array(32))
116
+ Array.isArray(messageSecret) && messageSecret.length === 32
117
+ ? new Uint8Array(messageSecret)
118
+ : window.crypto.getRandomValues(new Uint8Array(32))
117
119
  };
118
120
  delete options.poll;
119
121
  }
@@ -164,9 +166,9 @@ exports.LoadUtils = () => {
164
166
  }
165
167
  }
166
168
  }
167
-
169
+
168
170
  let buttonOptions = {};
169
- if(options.buttons){
171
+ if (options.buttons) {
170
172
  let caption;
171
173
  if (options.buttons.type === 'chat') {
172
174
  content = options.buttons.body;
@@ -214,18 +216,22 @@ exports.LoadUtils = () => {
214
216
  delete options.invokedBotWid;
215
217
  }
216
218
 
217
- let meUser = window.Store.User.getMaybeMeUser();
219
+ const lidUser = window.Store.User.getMaybeMeLidUser();
220
+ const meUser = window.Store.User.getMaybeMeUser();
218
221
  const newId = await window.Store.MsgKey.newId();
222
+ let from = chat.id.isLid() ? lidUser : meUser;
223
+ let participant;
219
224
 
220
- if (chat.id.isGroup() && chat.groupMetadata.isLidAddressingMode) {
221
- meUser = window.Store.User.getMaybeMeLidUser();
225
+ if (chat.isGroup) {
226
+ from = chat.groupMetadata && chat.groupMetadata.isLidAddressingMode ? lidUser : meUser;
227
+ participant = window.Store.WidFactory.toUserWid(from);
222
228
  }
223
-
224
- const newMsgId = new window.Store.MsgKey({
225
- from: meUser,
229
+
230
+ const newMsgKey = new window.Store.MsgKey({
231
+ from: from,
226
232
  to: chat.id,
227
233
  id: newId,
228
- participant: chat.id.isGroup() ? meUser : undefined,
234
+ participant: participant,
229
235
  selfDir: 'out',
230
236
  });
231
237
 
@@ -236,7 +242,7 @@ exports.LoadUtils = () => {
236
242
 
237
243
  const message = {
238
244
  ...options,
239
- id: newMsgId,
245
+ id: newMsgKey,
240
246
  ack: 0,
241
247
  body: content,
242
248
  from: meUser,
@@ -247,11 +253,11 @@ exports.LoadUtils = () => {
247
253
  isNewMsg: true,
248
254
  type: 'chat',
249
255
  ...ephemeralFields,
256
+ ...mediaOptions,
257
+ ...(mediaOptions.toJSON ? mediaOptions.toJSON() : {}),
258
+ ...quotedMsgOptions,
250
259
  ...locationOptions,
251
260
  ..._pollOptions,
252
- ...attOptions,
253
- ...(attOptions.toJSON ? attOptions.toJSON() : {}),
254
- ...quotedMsgOptions,
255
261
  ...vcardOptions,
256
262
  ...buttonOptions,
257
263
  ...listOptions,
@@ -264,12 +270,41 @@ exports.LoadUtils = () => {
264
270
  delete message.canonicalUrl;
265
271
  }
266
272
 
273
+ if (isChannel) {
274
+ const msg = new window.Store.Msg.modelClass(message);
275
+ const msgDataFromMsgModel = window.Store.SendChannelMessage.msgDataFromMsgModel(msg);
276
+ const isMedia = Object.keys(mediaOptions).length > 0;
277
+ await window.Store.SendChannelMessage.addNewsletterMsgsRecords([msgDataFromMsgModel]);
278
+ chat.msgs.add(msg);
279
+ chat.t = msg.t;
280
+
281
+ const sendChannelMsgResponse = await window.Store.SendChannelMessage.sendNewsletterMessageJob({
282
+ msg: msg,
283
+ type: message.type === 'chat' ? 'text' : isMedia ? 'media' : 'pollCreation',
284
+ newsletterJid: chat.id.toJid(),
285
+ ...(isMedia
286
+ ? {
287
+ mediaMetadata: msg.avParams(),
288
+ mediaHandle: isMedia ? mediaOptions.mediaHandle : null,
289
+ }
290
+ : {}
291
+ )
292
+ });
293
+
294
+ if (sendChannelMsgResponse.success) {
295
+ msg.t = sendChannelMsgResponse.ack.t;
296
+ msg.serverId = sendChannelMsgResponse.serverId;
297
+ }
298
+ msg.updateAck(1, true);
299
+ await window.Store.SendChannelMessage.updateNewsletterMsgRecord(msg);
300
+ return msg;
301
+ }
302
+
267
303
  await window.Store.SendMessage.addAndSendMsgToChat(chat, message);
268
- return window.Store.Msg.get(newMsgId._serialized);
304
+ return window.Store.Msg.get(newMsgKey._serialized);
269
305
  };
270
306
 
271
307
  window.WWebJS.editMessage = async (msg, content, options = {}) => {
272
-
273
308
  const extraOptions = options.extraOptions || {};
274
309
  delete options.extraOptions;
275
310
 
@@ -327,74 +362,51 @@ exports.LoadUtils = () => {
327
362
  };
328
363
  };
329
364
 
330
- window.WWebJS.processStickerData = async (mediaInfo) => {
331
- if (mediaInfo.mimetype !== 'image/webp') throw new Error('Invalid media type');
332
-
365
+ window.WWebJS.processMediaData = async (mediaInfo, { forceSticker, forceGif, forceVoice, forceDocument, sendToChannel }) => {
333
366
  const file = window.WWebJS.mediaInfoToFile(mediaInfo);
334
- let filehash = await window.WWebJS.getFileHash(file);
335
- let mediaKey = await window.WWebJS.generateHash(32);
336
-
337
- const controller = new AbortController();
338
- const uploadedInfo = await window.Store.UploadUtils.encryptAndUpload({
339
- blob: file,
340
- type: 'sticker',
341
- signal: controller.signal,
342
- mediaKey
343
- });
344
-
345
- const stickerInfo = {
346
- ...uploadedInfo,
347
- clientUrl: uploadedInfo.url,
348
- deprecatedMms3Url: uploadedInfo.url,
349
- uploadhash: uploadedInfo.encFilehash,
350
- size: file.size,
351
- type: 'sticker',
352
- filehash
353
- };
354
-
355
- return stickerInfo;
356
- };
357
-
358
- window.WWebJS.processMediaData = async (mediaInfo, { forceVoice, forceDocument, forceGif }) => {
359
- const file = window.WWebJS.mediaInfoToFile(mediaInfo);
360
- const mData = await window.Store.OpaqueData.createFromData(file, file.type);
361
- const mediaPrep = window.Store.MediaPrep.prepRawMedia(mData, { asDocument: forceDocument });
367
+ const opaqueData = await window.Store.OpaqueData.createFromData(file, file.type);
368
+ const mediaPrep = window.Store.MediaPrep.prepRawMedia(
369
+ opaqueData, {
370
+ asSticker: forceSticker,
371
+ asGif: forceGif,
372
+ isPtt: forceVoice,
373
+ asDocument: forceDocument
374
+ });
362
375
  const mediaData = await mediaPrep.waitForPrep();
363
376
  const mediaObject = window.Store.MediaObject.getOrCreateMediaObject(mediaData.filehash);
364
-
365
377
  const mediaType = window.Store.MediaTypes.msgToMediaType({
366
378
  type: mediaData.type,
367
- isGif: mediaData.isGif
379
+ isGif: mediaData.isGif,
380
+ isNewsletter: sendToChannel,
368
381
  });
369
382
 
370
- if (forceVoice && mediaData.type === 'audio') {
371
- mediaData.type = 'ptt';
383
+ if (forceVoice && mediaData.type === 'ptt') {
372
384
  const waveform = mediaObject.contentInfo.waveform;
373
385
  mediaData.waveform =
374
- waveform ?? await window.WWebJS.generateWaveform(file);
375
- }
376
-
377
- if (forceGif && mediaData.type === 'video') {
378
- mediaData.isGif = true;
379
- }
380
-
381
- if (forceDocument) {
382
- mediaData.type = 'document';
386
+ waveform || await window.WWebJS.generateWaveform(file);
383
387
  }
384
388
 
385
389
  if (!(mediaData.mediaBlob instanceof window.Store.OpaqueData)) {
386
- mediaData.mediaBlob = await window.Store.OpaqueData.createFromData(mediaData.mediaBlob, mediaData.mediaBlob.type);
390
+ mediaData.mediaBlob = await window.Store.OpaqueData.createFromData(
391
+ mediaData.mediaBlob,
392
+ mediaData.mediaBlob.type
393
+ );
387
394
  }
388
395
 
389
396
  mediaData.renderableUrl = mediaData.mediaBlob.url();
390
397
  mediaObject.consolidate(mediaData.toJSON());
391
398
  mediaData.mediaBlob.autorelease();
392
399
 
393
- const uploadedMedia = await window.Store.MediaUpload.uploadMedia({
400
+ const dataToUpload = {
394
401
  mimetype: mediaData.mimetype,
395
402
  mediaObject,
396
- mediaType
397
- });
403
+ mediaType,
404
+ ...(sendToChannel ? { calculateToken: window.Store.SendChannelMessage.getRandomFilehash } : {})
405
+ };
406
+
407
+ const uploadedMedia = !sendToChannel
408
+ ? await window.Store.MediaUpload.uploadMedia(dataToUpload)
409
+ : await window.Store.MediaUpload.uploadUnencryptedMedia(dataToUpload);
398
410
 
399
411
  const mediaEntry = uploadedMedia.mediaEntry;
400
412
  if (!mediaEntry) {
@@ -412,13 +424,14 @@ exports.LoadUtils = () => {
412
424
  uploadhash: mediaEntry.uploadHash,
413
425
  size: mediaObject.size,
414
426
  streamingSidecar: mediaEntry.sidecar,
415
- firstFrameSidecar: mediaEntry.firstFrameSidecar
427
+ firstFrameSidecar: mediaEntry.firstFrameSidecar,
428
+ mediaHandle: sendToChannel ? mediaEntry.handle : null,
416
429
  });
417
430
 
418
431
  return mediaData;
419
432
  };
420
433
 
421
- window.WWebJS.getMessageModel = message => {
434
+ window.WWebJS.getMessageModel = (message) => {
422
435
  const msg = message.serialize();
423
436
 
424
437
  msg.isEphemeral = message.isEphemeral;
@@ -456,51 +469,115 @@ exports.LoadUtils = () => {
456
469
  return _vote;
457
470
  };
458
471
 
459
- window.WWebJS.getChatModel = async chat => {
460
-
461
- let res = chat.serialize();
462
- res.isGroup = false;
463
- res.formattedTitle = chat.formattedTitle;
464
- res.isMuted = chat.mute?.expiration !== 0;
472
+ window.WWebJS.getChat = async (chatId, { getAsModel = true } = {}) => {
473
+ const isChannel = /@\w*newsletter\b/.test(chatId);
474
+ const chatWid = window.Store.WidFactory.createWid(chatId);
475
+ let chat;
465
476
 
466
- if (chat.groupMetadata) {
467
- res.isGroup = true;
468
- const chatWid = window.Store.WidFactory.createWid((chat.id._serialized));
469
- await window.Store.GroupMetadata.update(chatWid);
470
- res.groupMetadata = chat.groupMetadata.serialize();
471
- res.isReadOnly = chat.groupMetadata.announce;
472
- }
473
-
474
- res.lastMessage = null;
475
- if (res.msgs && res.msgs.length) {
476
- const lastMessage = chat.lastReceivedKey
477
- ? window.Store.Msg.get(chat.lastReceivedKey._serialized) || (await window.Store.Msg.getMessagesById([chat.lastReceivedKey._serialized]))?.messages?.[0]
478
- : null;
479
- if (lastMessage) {
480
- res.lastMessage = window.WWebJS.getMessageModel(lastMessage);
477
+ if (isChannel) {
478
+ try {
479
+ chat = window.Store.NewsletterCollection.get(chatId);
480
+ if (!chat) {
481
+ await window.Store.ChannelUtils.loadNewsletterPreviewChat(chatId);
482
+ chat = await window.Store.NewsletterCollection.find(chatWid);
483
+ }
484
+ } catch (err) {
485
+ chat = null;
481
486
  }
487
+ } else {
488
+ chat = window.Store.Chat.get(chatWid) || (await window.Store.Chat.find(chatWid));
482
489
  }
483
-
484
- delete res.msgs;
485
- delete res.msgUnsyncedButtonReplyMsgs;
486
- delete res.unsyncedButtonReplies;
487
490
 
488
- return res;
491
+ return getAsModel && chat
492
+ ? await window.WWebJS.getChatModel(chat, { isChannel: isChannel })
493
+ : chat;
489
494
  };
490
495
 
491
- window.WWebJS.getChat = async chatId => {
492
- const chatWid = window.Store.WidFactory.createWid(chatId);
493
- const chat = await window.Store.Chat.find(chatWid);
494
- return await window.WWebJS.getChatModel(chat);
496
+ window.WWebJS.getChannelMetadata = async (inviteCode) => {
497
+ const response =
498
+ await window.Store.ChannelUtils.queryNewsletterMetadataByInviteCode(
499
+ inviteCode,
500
+ window.Store.ChannelUtils.getRoleByIdentifier(inviteCode)
501
+ );
502
+
503
+ const picUrl = response.newsletterPictureMetadataMixin?.picture[0]?.queryPictureDirectPathOrEmptyResponseMixinGroup.value.directPath;
504
+
505
+ return {
506
+ id: response.idJid,
507
+ createdAtTs: response.newsletterCreationTimeMetadataMixin.creationTimeValue,
508
+ titleMetadata: {
509
+ title: response.newsletterNameMetadataMixin.nameElementValue,
510
+ updatedAtTs: response.newsletterNameMetadataMixin.nameUpdateTime
511
+ },
512
+ descriptionMetadata: {
513
+ description: response.newsletterDescriptionMetadataMixin.descriptionQueryDescriptionResponseMixin.elementValue,
514
+ updatedAtTs: response.newsletterDescriptionMetadataMixin.descriptionQueryDescriptionResponseMixin.updateTime
515
+ },
516
+ inviteLink: `https://whatsapp.com/channel/${response.newsletterInviteLinkMetadataMixin.inviteCode}`,
517
+ membershipType: window.Store.ChannelUtils.getRoleByIdentifier(inviteCode),
518
+ stateType: response.newsletterStateMetadataMixin.stateType,
519
+ pictureUrl: picUrl ? `https://pps.whatsapp.net${picUrl}` : null,
520
+ subscribersCount: response.newsletterSubscribersMetadataMixin.subscribersCount,
521
+ isVerified: response.newsletterVerificationMetadataMixin.verificationState === 'verified'
522
+ };
495
523
  };
496
524
 
497
525
  window.WWebJS.getChats = async () => {
498
526
  const chats = window.Store.Chat.getModelsArray();
499
-
500
527
  const chatPromises = chats.map(chat => window.WWebJS.getChatModel(chat));
501
528
  return await Promise.all(chatPromises);
502
529
  };
503
530
 
531
+ window.WWebJS.getChannels = async () => {
532
+ const channels = window.Store.NewsletterCollection.getModelsArray();
533
+ const channelPromises = channels?.map((channel) => window.WWebJS.getChatModel(channel, { isChannel: true }));
534
+ return await Promise.all(channelPromises);
535
+ };
536
+
537
+ window.WWebJS.getChatModel = async (chat, { isChannel = false } = {}) => {
538
+ if (!chat) return null;
539
+
540
+ const model = chat.serialize();
541
+ model.isGroup = false;
542
+ model.isMuted = chat.mute?.expiration !== 0;
543
+ if (isChannel) {
544
+ model.isChannel = window.Store.ChatGetters.getIsNewsletter(chat);
545
+ } else {
546
+ model.formattedTitle = chat.formattedTitle;
547
+ }
548
+
549
+ if (chat.groupMetadata) {
550
+ model.isGroup = true;
551
+ const chatWid = window.Store.WidFactory.createWid(chat.id._serialized);
552
+ await window.Store.GroupMetadata.update(chatWid);
553
+ chat.groupMetadata.participants._models
554
+ .filter(x => x.id._serialized.endsWith('@lid'))
555
+ .forEach(x => { x.id = x.contact.phoneNumber; });
556
+ model.groupMetadata = chat.groupMetadata.serialize();
557
+ model.isReadOnly = chat.groupMetadata.announce;
558
+ }
559
+
560
+ if (chat.newsletterMetadata) {
561
+ await window.Store.NewsletterMetadataCollection.update(chat.id);
562
+ model.channelMetadata = chat.newsletterMetadata.serialize();
563
+ model.channelMetadata.createdAtTs = chat.newsletterMetadata.creationTime;
564
+ }
565
+
566
+ model.lastMessage = null;
567
+ if (model.msgs && model.msgs.length) {
568
+ const lastMessage = chat.lastReceivedKey
569
+ ? window.Store.Msg.get(chat.lastReceivedKey._serialized) || (await window.Store.Msg.getMessagesById([chat.lastReceivedKey._serialized]))?.messages?.[0]
570
+ : null;
571
+ lastMessage && (model.lastMessage = window.WWebJS.getMessageModel(lastMessage));
572
+ }
573
+
574
+ delete model.msgs;
575
+ delete model.msgUnsyncedButtonReplyMsgs;
576
+ delete model.unsyncedButtonReplies;
577
+
578
+ return model;
579
+ };
580
+
504
581
  window.WWebJS.getContactModel = contact => {
505
582
  let res = contact.serialize();
506
583
  res.isBusiness = contact.isBusiness === undefined ? false : contact.isBusiness;
@@ -509,57 +586,30 @@ exports.LoadUtils = () => {
509
586
  res.businessProfile = contact.businessProfile.serialize();
510
587
  }
511
588
 
512
- // TODO: remove useOldImplementation and its checks once all clients are updated to >= v2.2327.4
513
- const useOldImplementation
514
- = window.compareWwebVersions(window.Debug.VERSION, '<', '2.2327.4');
515
-
516
- res.isMe = useOldImplementation
517
- ? contact.isMe
518
- : window.Store.ContactMethods.getIsMe(contact);
519
- res.isUser = useOldImplementation
520
- ? contact.isUser
521
- : window.Store.ContactMethods.getIsUser(contact);
522
- res.isGroup = useOldImplementation
523
- ? contact.isGroup
524
- : window.Store.ContactMethods.getIsGroup(contact);
525
- res.isWAContact = useOldImplementation
526
- ? contact.isWAContact
527
- : window.Store.ContactMethods.getIsWAContact(contact);
528
- res.isMyContact = useOldImplementation
529
- ? contact.isMyContact
530
- : window.Store.ContactMethods.getIsMyContact(contact);
589
+ res.isMe = window.Store.ContactMethods.getIsMe(contact);
590
+ res.isUser = window.Store.ContactMethods.getIsUser(contact);
591
+ res.isGroup = window.Store.ContactMethods.getIsGroup(contact);
592
+ res.isWAContact = window.Store.ContactMethods.getIsWAContact(contact);
593
+ res.isMyContact = window.Store.ContactMethods.getIsMyContact(contact);
531
594
  res.isBlocked = contact.isContactBlocked;
532
- res.userid = useOldImplementation
533
- ? contact.userid
534
- : window.Store.ContactMethods.getUserid(contact);
535
- res.isEnterprise = useOldImplementation
536
- ? contact.isEnterprise
537
- : window.Store.ContactMethods.getIsEnterprise(contact);
538
- res.verifiedName = useOldImplementation
539
- ? contact.verifiedName
540
- : window.Store.ContactMethods.getVerifiedName(contact);
541
- res.verifiedLevel = useOldImplementation
542
- ? contact.verifiedLevel
543
- : window.Store.ContactMethods.getVerifiedLevel(contact);
544
- res.statusMute = useOldImplementation
545
- ? contact.statusMute
546
- : window.Store.ContactMethods.getStatusMute(contact);
547
- res.name = useOldImplementation
548
- ? contact.name
549
- : window.Store.ContactMethods.getName(contact);
550
- res.shortName = useOldImplementation
551
- ? contact.shortName
552
- : window.Store.ContactMethods.getShortName(contact);
553
- res.pushname = useOldImplementation
554
- ? contact.pushname
555
- : window.Store.ContactMethods.getPushname(contact);
595
+ res.userid = window.Store.ContactMethods.getUserid(contact);
596
+ res.isEnterprise = window.Store.ContactMethods.getIsEnterprise(contact);
597
+ res.verifiedName = window.Store.ContactMethods.getVerifiedName(contact);
598
+ res.verifiedLevel = window.Store.ContactMethods.getVerifiedLevel(contact);
599
+ res.statusMute = window.Store.ContactMethods.getStatusMute(contact);
600
+ res.name = window.Store.ContactMethods.getName(contact);
601
+ res.shortName = window.Store.ContactMethods.getShortName(contact);
602
+ res.pushname = window.Store.ContactMethods.getPushname(contact);
556
603
 
557
604
  return res;
558
605
  };
559
606
 
560
607
  window.WWebJS.getContact = async contactId => {
561
608
  const wid = window.Store.WidFactory.createWid(contactId);
562
- const contact = await window.Store.Contact.find(wid);
609
+ let contact = await window.Store.Contact.find(wid);
610
+ if (contact.id._serialized.endsWith('@lid')) {
611
+ contact.id = contact.phoneNumber;
612
+ }
563
613
  const bizProfile = await window.Store.BusinessProfile.fetchBizProfile(wid);
564
614
  bizProfile.profileOptions && (contact.businessProfile = bizProfile);
565
615
  return window.WWebJS.getContactModel(contact);
@@ -626,10 +676,6 @@ exports.LoadUtils = () => {
626
676
  return result;
627
677
  };
628
678
 
629
- /**
630
- * Referenced from and modified:
631
- * @see https://github.com/wppconnect-team/wa-js/commit/290ebfefe6021b3d17f7fdfdda5545bb0473b26f
632
- */
633
679
  window.WWebJS.generateWaveform = async (audioFile) => {
634
680
  try {
635
681
  const audioData = await audioFile.arrayBuffer();
@@ -663,7 +709,7 @@ exports.LoadUtils = () => {
663
709
  };
664
710
 
665
711
  window.WWebJS.sendClearChat = async (chatId) => {
666
- let chat = window.Store.Chat.get(chatId);
712
+ let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
667
713
  if (chat !== undefined) {
668
714
  await window.Store.SendClear.sendClear(chat, false);
669
715
  return true;
@@ -672,7 +718,7 @@ exports.LoadUtils = () => {
672
718
  };
673
719
 
674
720
  window.WWebJS.sendDeleteChat = async (chatId) => {
675
- let chat = window.Store.Chat.get(chatId);
721
+ let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
676
722
  if (chat !== undefined) {
677
723
  await window.Store.SendDelete.sendDelete(chat);
678
724
  return true;
@@ -902,7 +948,7 @@ exports.LoadUtils = () => {
902
948
  }
903
949
 
904
950
  if (rpcResult.name === 'AddParticipantsResponseSuccess') {
905
- const code = resultArgs?.value.error ?? '200';
951
+ const code = resultArgs?.value.error || '200';
906
952
  data.name = resultArgs?.name;
907
953
  data.code = +code;
908
954
  data.inviteV4Code = resultArgs?.value.addRequestCode;
@@ -1017,6 +1063,25 @@ exports.LoadUtils = () => {
1017
1063
  }
1018
1064
  };
1019
1065
 
1066
+ window.WWebJS.subscribeToUnsubscribeFromChannel = async (channelId, action, options = {}) => {
1067
+ const channel = await window.WWebJS.getChat(channelId, { getAsModel: false });
1068
+
1069
+ if (!channel || channel.newsletterMetadata.membershipType === 'owner') return false;
1070
+ options = { eventSurface: 3, deleteLocalModels: options.deleteLocalModels ?? true };
1071
+
1072
+ try {
1073
+ if (action === 'Subscribe') {
1074
+ await window.Store.ChannelUtils.subscribeToNewsletterAction(channel, options);
1075
+ } else if (action === 'Unsubscribe') {
1076
+ await window.Store.ChannelUtils.unsubscribeFromNewsletterAction(channel, options);
1077
+ } else return false;
1078
+ return true;
1079
+ } catch (err) {
1080
+ if (err.name === 'ServerStatusCodeError') return false;
1081
+ throw err;
1082
+ }
1083
+ };
1084
+
1020
1085
  window.WWebJS.pinUnpinMsgAction = async (msgId, action, duration) => {
1021
1086
  const message = window.Store.Msg.get(msgId) || (await window.Store.Msg.getMessagesById([msgId]))?.messages?.[0];
1022
1087
  if (!message) return false;
@@ -14,9 +14,8 @@ class InterfaceController {
14
14
  * @param {string} chatId ID of the chat window that will be opened
15
15
  */
16
16
  async openChatWindow(chatId) {
17
- await this.pupPage.evaluate(async chatId => {
18
- const chatWid = window.Store.WidFactory.createWid(chatId);
19
- const chat = window.Store.Chat.get(chatWid) || await window.Store.Chat.find(chatWid);
17
+ await this.pupPage.evaluate(async (chatId) => {
18
+ const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
20
19
  await window.Store.Cmd.openChatBottom(chat);
21
20
  }, chatId);
22
21
  }
@@ -27,7 +26,7 @@ class InterfaceController {
27
26
  */
28
27
  async openChatDrawer(chatId) {
29
28
  await this.pupPage.evaluate(async chatId => {
30
- let chat = await window.Store.Chat.get(chatId);
29
+ let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
31
30
  await window.Store.Cmd.openDrawerMid(chat);
32
31
  }, chatId);
33
32
  }
@@ -38,7 +37,7 @@ class InterfaceController {
38
37
  */
39
38
  async openChatSearch(chatId) {
40
39
  await this.pupPage.evaluate(async chatId => {
41
- let chat = await window.Store.Chat.get(chatId);
40
+ let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
42
41
  await window.Store.Cmd.chatSearch(chat);
43
42
  }, chatId);
44
43
  }