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