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.
- package/.env.example +3 -0
- package/CODE_OF_CONDUCT.md +133 -0
- package/LICENSE +201 -0
- package/README.md +185 -0
- package/example.js +680 -0
- package/index.d.ts +2069 -0
- package/index.js +34 -0
- package/package.json +55 -0
- package/shell.js +36 -0
- package/src/Client.js +2188 -0
- package/src/authStrategies/BaseAuthStrategy.js +27 -0
- package/src/authStrategies/LocalAuth.js +58 -0
- package/src/authStrategies/NoAuth.js +12 -0
- package/src/authStrategies/RemoteAuth.js +210 -0
- package/src/factories/ChatFactory.js +21 -0
- package/src/factories/ContactFactory.js +16 -0
- package/src/structures/Base.js +22 -0
- package/src/structures/Broadcast.js +69 -0
- package/src/structures/BusinessContact.js +21 -0
- package/src/structures/Buttons.js +82 -0
- package/src/structures/Call.js +76 -0
- package/src/structures/Channel.js +382 -0
- package/src/structures/Chat.js +291 -0
- package/src/structures/ClientInfo.js +71 -0
- package/src/structures/Contact.js +208 -0
- package/src/structures/GroupChat.js +473 -0
- package/src/structures/GroupNotification.js +104 -0
- package/src/structures/Label.js +50 -0
- package/src/structures/List.js +79 -0
- package/src/structures/Location.js +62 -0
- package/src/structures/Message.js +704 -0
- package/src/structures/MessageMedia.js +111 -0
- package/src/structures/Order.js +52 -0
- package/src/structures/Payment.js +79 -0
- package/src/structures/Poll.js +44 -0
- package/src/structures/PollVote.js +61 -0
- package/src/structures/PrivateChat.js +13 -0
- package/src/structures/PrivateContact.js +13 -0
- package/src/structures/Product.js +68 -0
- package/src/structures/ProductMetadata.js +25 -0
- package/src/structures/Reaction.js +69 -0
- package/src/structures/index.js +26 -0
- package/src/util/Constants.js +176 -0
- package/src/util/Injected/AuthStore/AuthStore.js +17 -0
- package/src/util/Injected/AuthStore/LegacyAuthStore.js +22 -0
- package/src/util/Injected/LegacyStore.js +146 -0
- package/src/util/Injected/Store.js +215 -0
- package/src/util/Injected/Utils.js +1139 -0
- package/src/util/InterfaceController.js +126 -0
- package/src/util/Puppeteer.js +23 -0
- package/src/util/Util.js +186 -0
- package/src/webCache/LocalWebCache.js +40 -0
- package/src/webCache/RemoteWebCache.js +40 -0
- package/src/webCache/WebCache.js +14 -0
- 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
|
+
};
|