@queenanya/baileys 7.4.14 → 7.5.1
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/README.md +26 -26
- package/lib/Defaults/baileys-version.json +1 -1
- package/lib/Defaults/index.d.ts +1 -231
- package/lib/Defaults/index.js +11 -23
- package/lib/Socket/Client/index.d.ts +2 -3
- package/lib/Socket/Client/index.js +2 -3
- package/lib/Socket/Client/{web-socket-client.d.ts → websocket.d.ts} +1 -1
- package/lib/Socket/Client/{web-socket-client.js → websocket.js} +2 -2
- package/lib/Socket/business.d.ts +31 -28
- package/lib/Socket/chats.d.ts +17 -9
- package/lib/Socket/chats.js +115 -116
- package/lib/Socket/{registration.d.ts → communities.d.ts} +94 -145
- package/lib/Socket/communities.js +354 -0
- package/lib/Socket/groups.d.ts +23 -10
- package/lib/Socket/groups.js +12 -1
- package/lib/Socket/index.d.ts +69 -38
- package/lib/Socket/index.js +2 -2
- package/lib/Socket/messages-recv.d.ts +30 -28
- package/lib/Socket/messages-recv.js +291 -180
- package/lib/Socket/messages-send.d.ts +25 -19
- package/lib/Socket/messages-send.js +110 -76
- package/lib/Socket/newsletter.d.ts +19 -13
- package/lib/Socket/newsletter.js +67 -54
- package/lib/Socket/socket.d.ts +3 -1
- package/lib/Socket/socket.js +15 -17
- package/lib/Socket/usync.d.ts +38 -0
- package/lib/Socket/usync.js +70 -0
- package/lib/Store/make-cache-manager-store.d.ts +2 -1
- package/lib/Store/make-in-memory-store.js +13 -11
- package/lib/Store/make-ordered-dictionary.js +2 -2
- package/lib/Types/Auth.d.ts +1 -6
- package/lib/Types/Call.d.ts +1 -1
- package/lib/Types/Chat.d.ts +15 -7
- package/lib/Types/Contact.d.ts +6 -1
- package/lib/Types/Events.d.ts +44 -2
- package/lib/Types/GroupMetadata.d.ts +3 -1
- package/lib/Types/Label.d.ts +11 -0
- package/lib/Types/Message.d.ts +37 -30
- package/lib/Types/Newsletter.d.ts +0 -13
- package/lib/Types/Newsletter.js +1 -15
- package/lib/Types/Socket.d.ts +10 -3
- package/lib/Types/USync.d.ts +25 -0
- package/lib/Types/USync.js +2 -0
- package/lib/Types/index.d.ts +8 -0
- package/lib/Utils/auth-utils.js +1 -7
- package/lib/Utils/chat-utils.d.ts +5 -4
- package/lib/Utils/chat-utils.js +52 -20
- package/lib/Utils/crypto.d.ts +2 -1
- package/lib/Utils/crypto.js +4 -2
- package/lib/Utils/decode-wa-message.d.ts +1 -0
- package/lib/Utils/decode-wa-message.js +34 -14
- package/lib/Utils/event-buffer.js +14 -8
- package/lib/Utils/generics.d.ts +37 -13
- package/lib/Utils/generics.js +103 -18
- package/lib/Utils/history.d.ts +6 -2
- package/lib/Utils/history.js +3 -0
- package/lib/Utils/index.d.ts +1 -0
- package/lib/Utils/index.js +1 -0
- package/lib/Utils/link-preview.js +24 -1
- package/lib/Utils/logger.d.ts +1 -3
- package/lib/Utils/make-mutex.js +1 -0
- package/lib/Utils/messages-media.d.ts +3 -2
- package/lib/Utils/messages-media.js +17 -32
- package/lib/Utils/messages.d.ts +1 -0
- package/lib/Utils/messages.js +67 -72
- package/lib/Utils/noise-handler.d.ts +3 -3
- package/lib/Utils/noise-handler.js +7 -12
- package/lib/Utils/process-message.d.ts +3 -2
- package/lib/Utils/process-message.js +55 -21
- package/lib/Utils/signal.js +23 -16
- package/lib/Utils/use-multi-file-auth-state.js +17 -3
- package/lib/Utils/validate-connection.d.ts +0 -1
- package/lib/Utils/validate-connection.js +10 -44
- package/lib/WABinary/constants.js +5 -5
- package/lib/WABinary/decode.d.ts +3 -2
- package/lib/WABinary/decode.js +6 -4
- package/lib/WABinary/encode.d.ts +1 -2
- package/lib/WABinary/encode.js +8 -6
- package/lib/WABinary/generic-utils.d.ts +1 -0
- package/lib/WABinary/jid-utils.d.ts +3 -3
- package/lib/WABinary/jid-utils.js +5 -5
- package/lib/WAM/BinaryInfo.d.ts +3 -2
- package/lib/WAM/constants.d.ts +3 -2
- package/lib/WAM/encode.d.ts +1 -0
- package/lib/WAM/encode.js +2 -2
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +32 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
- package/lib/WAUSync/Protocols/index.d.ts +4 -0
- package/lib/WAUSync/Protocols/index.js +20 -0
- package/lib/WAUSync/USyncQuery.d.ts +26 -0
- package/lib/WAUSync/USyncQuery.js +79 -0
- package/lib/WAUSync/USyncUser.d.ts +10 -0
- package/lib/WAUSync/USyncUser.js +22 -0
- package/lib/WAUSync/index.d.ts +3 -0
- package/lib/WAUSync/index.js +19 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/package.json +36 -34
- package/lib/Defaults/phonenumber-mcc.json +0 -223
- package/lib/Socket/Client/mobile-socket-client.d.ts +0 -13
- package/lib/Socket/Client/mobile-socket-client.js +0 -65
- package/lib/Socket/registration.js +0 -166
- /package/lib/Socket/Client/{abstract-socket-client.d.ts → types.d.ts} +0 -0
- /package/lib/Socket/Client/{abstract-socket-client.js → types.js} +0 -0
|
@@ -22,9 +22,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
25
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
29
|
exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.extensionForMediaMessage = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = exports.prepareStream = exports.getHttpStream = exports.generateThumbnail = exports.getStream = exports.toBuffer = exports.toReadable = exports.getAudioWaveform = exports.getAudioDuration = exports.mediaMessageSHA256B64 = exports.changeprofileFull = exports.generatePP = exports.generateProfilePictureFP = exports.generateProfilePictureFull = exports.generateProfilePicture = exports.encodeBase64EncodedStringForUpload = exports.extractImageThumb = exports.getMediaKeys = exports.hkdfInfoKey = void 0;
|
|
27
30
|
const boom_1 = require("@hapi/boom");
|
|
31
|
+
const axios_1 = __importDefault(require("axios"));
|
|
28
32
|
const child_process_1 = require("child_process");
|
|
29
33
|
const Crypto = __importStar(require("crypto"));
|
|
30
34
|
const events_1 = require("events");
|
|
@@ -41,13 +45,11 @@ const getTmpFilesDirectory = () => (0, os_1.tmpdir)();
|
|
|
41
45
|
const getImageProcessingLibrary = async () => {
|
|
42
46
|
const [_jimp, sharp] = await Promise.all([
|
|
43
47
|
(async () => {
|
|
44
|
-
const jimp = await (
|
|
45
|
-
.catch(() => { }));
|
|
48
|
+
const jimp = await (Promise.resolve().then(() => __importStar(require('jimp'))).catch(() => { }));
|
|
46
49
|
return jimp;
|
|
47
50
|
})(),
|
|
48
51
|
(async () => {
|
|
49
|
-
const sharp = await (
|
|
50
|
-
.catch(() => { }));
|
|
52
|
+
const sharp = await (Promise.resolve().then(() => __importStar(require('sharp'))).catch(() => { }));
|
|
51
53
|
return sharp;
|
|
52
54
|
})()
|
|
53
55
|
]);
|
|
@@ -258,7 +260,7 @@ const mediaMessageSHA256B64 = (message) => {
|
|
|
258
260
|
};
|
|
259
261
|
exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
|
|
260
262
|
async function getAudioDuration(buffer) {
|
|
261
|
-
const musicMetadata = await
|
|
263
|
+
const musicMetadata = await Promise.resolve().then(() => __importStar(require('music-metadata')));
|
|
262
264
|
let metadata;
|
|
263
265
|
if (Buffer.isBuffer(buffer)) {
|
|
264
266
|
metadata = await musicMetadata.parseBuffer(buffer, undefined, { duration: true });
|
|
@@ -283,7 +285,7 @@ exports.getAudioDuration = getAudioDuration;
|
|
|
283
285
|
*/
|
|
284
286
|
async function getAudioWaveform(buffer, logger) {
|
|
285
287
|
try {
|
|
286
|
-
const audioDecode = (buffer) =>
|
|
288
|
+
const audioDecode = (buffer) => Promise.resolve().then(() => __importStar(require('audio-decode'))).then(({ default: audioDecode }) => audioDecode(buffer));
|
|
287
289
|
let audioData;
|
|
288
290
|
if (Buffer.isBuffer(buffer)) {
|
|
289
291
|
audioData = buffer;
|
|
@@ -383,8 +385,7 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
383
385
|
}
|
|
384
386
|
exports.generateThumbnail = generateThumbnail;
|
|
385
387
|
const getHttpStream = async (url, options = {}) => {
|
|
386
|
-
const
|
|
387
|
-
const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' });
|
|
388
|
+
const fetched = await axios_1.default.get(url.toString(), { ...options, responseType: 'stream' });
|
|
388
389
|
return fetched.data;
|
|
389
390
|
};
|
|
390
391
|
exports.getHttpStream = getHttpStream;
|
|
@@ -442,7 +443,7 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
442
443
|
let writeStream;
|
|
443
444
|
let didSaveToTmpPath = false;
|
|
444
445
|
if (type === 'file') {
|
|
445
|
-
bodyPath = media.url;
|
|
446
|
+
bodyPath = media.url.toString();
|
|
446
447
|
}
|
|
447
448
|
else if (saveOriginalFileIfRequired) {
|
|
448
449
|
bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageID)());
|
|
@@ -465,10 +466,8 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
465
466
|
});
|
|
466
467
|
}
|
|
467
468
|
sha256Plain = sha256Plain.update(data);
|
|
468
|
-
if (writeStream) {
|
|
469
|
-
|
|
470
|
-
await (0, events_1.once)(writeStream, 'drain');
|
|
471
|
-
}
|
|
469
|
+
if (writeStream && !writeStream.write(data)) {
|
|
470
|
+
await (0, events_1.once)(writeStream, 'drain');
|
|
472
471
|
}
|
|
473
472
|
onChunk(aes.update(data));
|
|
474
473
|
}
|
|
@@ -639,33 +638,23 @@ exports.extensionForMediaMessage = extensionForMediaMessage;
|
|
|
639
638
|
const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
640
639
|
return async (stream, { mediaType, fileEncSha256B64, newsletter, timeoutMs }) => {
|
|
641
640
|
var _a, _b;
|
|
642
|
-
const { default: axios } = await import('axios');
|
|
643
641
|
// send a query JSON to obtain the url & auth token to upload our media
|
|
644
642
|
let uploadInfo = await refreshMediaConn(false);
|
|
645
643
|
let urls;
|
|
646
644
|
const hosts = [...customUploadHosts, ...uploadInfo.hosts];
|
|
647
|
-
const chunks = [];
|
|
648
|
-
if (!Buffer.isBuffer(stream)) {
|
|
649
|
-
for await (const chunk of stream) {
|
|
650
|
-
chunks.push(chunk);
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
const reqBody = Buffer.isBuffer(stream) ? stream : Buffer.concat(chunks);
|
|
654
645
|
fileEncSha256B64 = (0, exports.encodeBase64EncodedStringForUpload)(fileEncSha256B64);
|
|
655
646
|
let media = Defaults_1.MEDIA_PATH_MAP[mediaType];
|
|
656
647
|
if (newsletter) {
|
|
657
648
|
media = media === null || media === void 0 ? void 0 : media.replace('/mms/', '/newsletter/newsletter-');
|
|
658
649
|
}
|
|
659
|
-
for (const { hostname
|
|
650
|
+
for (const { hostname } of hosts) {
|
|
660
651
|
logger.debug(`uploading to "${hostname}"`);
|
|
661
652
|
const auth = encodeURIComponent(uploadInfo.auth); // the auth token
|
|
662
|
-
const url = `https://${hostname}${
|
|
653
|
+
const url = `https://${hostname}${Defaults_1.MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
|
|
654
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
663
655
|
let result;
|
|
664
656
|
try {
|
|
665
|
-
|
|
666
|
-
throw new boom_1.Boom(`Body too large for "${hostname}"`, { statusCode: 413 });
|
|
667
|
-
}
|
|
668
|
-
const body = await axios.post(url, reqBody, {
|
|
657
|
+
const body = await axios_1.default.post(url, stream, {
|
|
669
658
|
...options,
|
|
670
659
|
headers: {
|
|
671
660
|
...options.headers || {},
|
|
@@ -693,7 +682,7 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
693
682
|
}
|
|
694
683
|
}
|
|
695
684
|
catch (error) {
|
|
696
|
-
if (
|
|
685
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
697
686
|
result = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data;
|
|
698
687
|
}
|
|
699
688
|
const isLast = hostname === ((_b = hosts[uploadInfo.hosts.length - 1]) === null || _b === void 0 ? void 0 : _b.hostname);
|
|
@@ -795,7 +784,3 @@ const MEDIA_RETRY_STATUS_MAP = {
|
|
|
795
784
|
[WAProto_1.proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
|
|
796
785
|
[WAProto_1.proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418,
|
|
797
786
|
};
|
|
798
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
799
|
-
function __importStar(arg0) {
|
|
800
|
-
throw new Error('Function not implemented.');
|
|
801
|
-
}
|
package/lib/Utils/messages.d.ts
CHANGED
package/lib/Utils/messages.js
CHANGED
|
@@ -30,7 +30,6 @@ const MessageTypeProto = {
|
|
|
30
30
|
'sticker': Types_1.WAProto.Message.StickerMessage,
|
|
31
31
|
'document': Types_1.WAProto.Message.DocumentMessage,
|
|
32
32
|
};
|
|
33
|
-
const ButtonType = WAProto_1.proto.Message.ButtonsMessage.HeaderType;
|
|
34
33
|
/**
|
|
35
34
|
* Uses a regex to test whether the string contains a URL, and returns the URL if it does.
|
|
36
35
|
* @param text eg. hello https://google.com
|
|
@@ -240,7 +239,7 @@ const generateForwardMessageContent = (message, forceForward) => {
|
|
|
240
239
|
exports.generateForwardMessageContent = generateForwardMessageContent;
|
|
241
240
|
const generateWAMessageContent = async (message, options) => {
|
|
242
241
|
var _a;
|
|
243
|
-
var _b;
|
|
242
|
+
var _b, _c;
|
|
244
243
|
let m = {};
|
|
245
244
|
if ('text' in message) {
|
|
246
245
|
const extContent = { text: message.text };
|
|
@@ -310,6 +309,41 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
310
309
|
message.disappearingMessagesInChat;
|
|
311
310
|
m = (0, exports.prepareDisappearingMessageSettingContent)(exp);
|
|
312
311
|
}
|
|
312
|
+
else if ('groupInvite' in message) {
|
|
313
|
+
m.groupInviteMessage = {};
|
|
314
|
+
m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode;
|
|
315
|
+
m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration;
|
|
316
|
+
m.groupInviteMessage.caption = message.groupInvite.text;
|
|
317
|
+
m.groupInviteMessage.groupJid = message.groupInvite.jid;
|
|
318
|
+
m.groupInviteMessage.groupName = message.groupInvite.subject;
|
|
319
|
+
//TODO: use built-in interface and get disappearing mode info etc.
|
|
320
|
+
//TODO: cache / use store!?
|
|
321
|
+
if (options.getProfilePicUrl) {
|
|
322
|
+
const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
|
|
323
|
+
if (pfpUrl) {
|
|
324
|
+
const resp = await axios_1.default.get(pfpUrl, { responseType: 'arraybuffer' });
|
|
325
|
+
if (resp.status === 200) {
|
|
326
|
+
m.groupInviteMessage.jpegThumbnail = resp.data;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
else if ('pin' in message) {
|
|
332
|
+
m.pinInChatMessage = {};
|
|
333
|
+
m.messageContextInfo = {};
|
|
334
|
+
m.pinInChatMessage.key = message.pin;
|
|
335
|
+
m.pinInChatMessage.type = 1;
|
|
336
|
+
m.pinInChatMessage.senderTimestampMs = Date.now();
|
|
337
|
+
m.messageContextInfo.messageAddOnDurationInSecs = message.time || 86400;
|
|
338
|
+
}
|
|
339
|
+
else if ('unpin' in message) {
|
|
340
|
+
m.pinInChatMessage = {};
|
|
341
|
+
m.messageContextInfo = {};
|
|
342
|
+
m.pinInChatMessage.key = message.unpin;
|
|
343
|
+
m.pinInChatMessage.type = 2;
|
|
344
|
+
m.pinInChatMessage.senderTimestampMs = Date.now();
|
|
345
|
+
m.messageContextInfo.messageAddOnDurationInSecs = 0;
|
|
346
|
+
}
|
|
313
347
|
else if ('buttonReply' in message) {
|
|
314
348
|
switch (message.type) {
|
|
315
349
|
case 'template':
|
|
@@ -328,6 +362,10 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
328
362
|
break;
|
|
329
363
|
}
|
|
330
364
|
}
|
|
365
|
+
else if ('ptv' in message && message.ptv) {
|
|
366
|
+
const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options);
|
|
367
|
+
m.ptvMessage = videoMessage;
|
|
368
|
+
}
|
|
331
369
|
else if ('product' in message) {
|
|
332
370
|
const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
|
|
333
371
|
m.productMessage = Types_1.WAProto.Message.ProductMessage.fromObject({
|
|
@@ -343,6 +381,7 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
343
381
|
}
|
|
344
382
|
else if ('poll' in message) {
|
|
345
383
|
(_b = message.poll).selectableCount || (_b.selectableCount = 0);
|
|
384
|
+
(_c = message.poll).toAnnouncementGroup || (_c.toAnnouncementGroup = false);
|
|
346
385
|
if (!Array.isArray(message.poll.values)) {
|
|
347
386
|
throw new boom_1.Boom('Invalid poll values', { statusCode: 400 });
|
|
348
387
|
}
|
|
@@ -354,11 +393,25 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
354
393
|
// encKey
|
|
355
394
|
messageSecret: message.poll.messageSecret || (0, crypto_1.randomBytes)(32),
|
|
356
395
|
};
|
|
357
|
-
|
|
396
|
+
const pollCreationMessage = {
|
|
358
397
|
name: message.poll.name,
|
|
359
398
|
selectableOptionsCount: message.poll.selectableCount,
|
|
360
399
|
options: message.poll.values.map(optionName => ({ optionName })),
|
|
361
400
|
};
|
|
401
|
+
if (message.poll.toAnnouncementGroup) {
|
|
402
|
+
// poll v2 is for community announcement groups (single select and multiple)
|
|
403
|
+
m.pollCreationMessageV2 = pollCreationMessage;
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
if (message.poll.selectableCount > 0) {
|
|
407
|
+
//poll v3 is for single select polls
|
|
408
|
+
m.pollCreationMessageV3 = pollCreationMessage;
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
// poll v3 for multiple choice polls
|
|
412
|
+
m.pollCreationMessage = pollCreationMessage;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
362
415
|
}
|
|
363
416
|
else if ('sharePhoneNumber' in message) {
|
|
364
417
|
m.protocolMessage = {
|
|
@@ -371,61 +424,6 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
371
424
|
else {
|
|
372
425
|
m = await (0, exports.prepareWAMessageMedia)(message, options);
|
|
373
426
|
}
|
|
374
|
-
if ('buttons' in message && !!message.buttons) {
|
|
375
|
-
const buttonsMessage = {
|
|
376
|
-
buttons: message.buttons.map(b => ({ ...b, type: WAProto_1.proto.Message.ButtonsMessage.Button.Type.RESPONSE }))
|
|
377
|
-
};
|
|
378
|
-
if ('text' in message) {
|
|
379
|
-
buttonsMessage.contentText = message.text;
|
|
380
|
-
buttonsMessage.headerType = ButtonType.EMPTY;
|
|
381
|
-
}
|
|
382
|
-
else {
|
|
383
|
-
if ('caption' in message) {
|
|
384
|
-
buttonsMessage.contentText = message.caption;
|
|
385
|
-
}
|
|
386
|
-
const type = Object.keys(m)[0].replace('Message', '').toUpperCase();
|
|
387
|
-
buttonsMessage.headerType = ButtonType[type];
|
|
388
|
-
Object.assign(buttonsMessage, m);
|
|
389
|
-
}
|
|
390
|
-
if ('footer' in message && !!message.footer) {
|
|
391
|
-
buttonsMessage.footerText = message.footer;
|
|
392
|
-
}
|
|
393
|
-
m = { buttonsMessage };
|
|
394
|
-
}
|
|
395
|
-
else if ('templateButtons' in message && !!message.templateButtons) {
|
|
396
|
-
const msg = {
|
|
397
|
-
hydratedButtons: message.templateButtons
|
|
398
|
-
};
|
|
399
|
-
if ('text' in message) {
|
|
400
|
-
msg.hydratedContentText = message.text;
|
|
401
|
-
}
|
|
402
|
-
else {
|
|
403
|
-
if ('caption' in message) {
|
|
404
|
-
msg.hydratedContentText = message.caption;
|
|
405
|
-
}
|
|
406
|
-
Object.assign(msg, m);
|
|
407
|
-
}
|
|
408
|
-
if ('footer' in message && !!message.footer) {
|
|
409
|
-
msg.hydratedFooterText = message.footer;
|
|
410
|
-
}
|
|
411
|
-
m = {
|
|
412
|
-
templateMessage: {
|
|
413
|
-
fourRowTemplate: msg,
|
|
414
|
-
hydratedTemplate: msg
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
if ('sections' in message && !!message.sections) {
|
|
419
|
-
const listMessage = {
|
|
420
|
-
sections: message.sections,
|
|
421
|
-
buttonText: message.buttonText,
|
|
422
|
-
title: message.title,
|
|
423
|
-
footerText: message.footer,
|
|
424
|
-
description: message.text,
|
|
425
|
-
listType: WAProto_1.proto.Message.ListMessage.ListType.SINGLE_SELECT
|
|
426
|
-
};
|
|
427
|
-
m = { listMessage };
|
|
428
|
-
}
|
|
429
427
|
if ('viewOnce' in message && !!message.viewOnce) {
|
|
430
428
|
m = { viewOnceMessage: { message: m } };
|
|
431
429
|
}
|
|
@@ -462,7 +460,8 @@ const generateWAMessageFromContent = (jid, message, options) => {
|
|
|
462
460
|
const key = (0, exports.getContentType)(innerMessage);
|
|
463
461
|
const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp);
|
|
464
462
|
const { quoted, userJid } = options;
|
|
465
|
-
|
|
463
|
+
// only set quoted if isn't a newsletter message
|
|
464
|
+
if (quoted && !(0, WABinary_1.isJidNewsletter)(jid)) {
|
|
466
465
|
const participant = quoted.key.fromMe ? userJid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid);
|
|
467
466
|
let quotedMsg = (0, exports.normalizeMessageContent)(quoted.message);
|
|
468
467
|
const msgType = (0, exports.getContentType)(quotedMsg);
|
|
@@ -491,7 +490,7 @@ const generateWAMessageFromContent = (jid, message, options) => {
|
|
|
491
490
|
// already not converted to disappearing message
|
|
492
491
|
key !== 'ephemeralMessage' &&
|
|
493
492
|
// newsletter not accept disappearing messages
|
|
494
|
-
!(0, WABinary_1.
|
|
493
|
+
!(0, WABinary_1.isJidNewsletter)(jid)) {
|
|
495
494
|
innerMessage[key].contextInfo = {
|
|
496
495
|
...(innerMessage[key].contextInfo || {}),
|
|
497
496
|
expiration: options.ephemeralExpiration || Defaults_1.WA_DEFAULT_EPHEMERAL,
|
|
@@ -518,7 +517,7 @@ const generateWAMessage = async (jid, content, options) => {
|
|
|
518
517
|
var _a;
|
|
519
518
|
// ensure msg ID is with every log
|
|
520
519
|
options.logger = (_a = options === null || options === void 0 ? void 0 : options.logger) === null || _a === void 0 ? void 0 : _a.child({ msgId: options.messageId });
|
|
521
|
-
return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.
|
|
520
|
+
return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsletter)(jid), ...options }), options);
|
|
522
521
|
};
|
|
523
522
|
exports.generateWAMessage = generateWAMessage;
|
|
524
523
|
/** Get the key to access the true type of content */
|
|
@@ -707,17 +706,13 @@ const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
|
707
706
|
const result = await downloadMsg()
|
|
708
707
|
.catch(async (error) => {
|
|
709
708
|
var _a;
|
|
710
|
-
if (ctx)
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
const result = await downloadMsg();
|
|
718
|
-
return result;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
709
|
+
if (ctx && axios_1.default.isAxiosError(error) && // check if the message requires a reupload
|
|
710
|
+
REUPLOAD_REQUIRED_STATUS.includes((_a = error.response) === null || _a === void 0 ? void 0 : _a.status)) {
|
|
711
|
+
ctx.logger.info({ key: message.key }, 'sending reupload media request...');
|
|
712
|
+
// request reupload
|
|
713
|
+
message = await ctx.reuploadRequest(message);
|
|
714
|
+
const result = await downloadMsg();
|
|
715
|
+
return result;
|
|
721
716
|
}
|
|
722
717
|
throw error;
|
|
723
718
|
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
2
3
|
import { Logger } from 'pino';
|
|
3
4
|
import { proto } from '../../WAProto';
|
|
4
5
|
import { KeyPair } from '../Types';
|
|
5
6
|
import { BinaryNode } from '../WABinary';
|
|
6
|
-
export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER,
|
|
7
|
+
export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, logger, routingInfo }: {
|
|
7
8
|
keyPair: KeyPair;
|
|
8
9
|
NOISE_HEADER: Uint8Array;
|
|
9
|
-
mobile: boolean;
|
|
10
10
|
logger: Logger;
|
|
11
11
|
routingInfo?: Buffer | undefined;
|
|
12
12
|
}) => {
|
|
@@ -17,5 +17,5 @@ export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public
|
|
|
17
17
|
finishInit: () => void;
|
|
18
18
|
processHandshake: ({ serverHello }: proto.HandshakeMessage, noiseKey: KeyPair) => Buffer;
|
|
19
19
|
encodeFrame: (data: Buffer | Uint8Array) => Buffer;
|
|
20
|
-
decodeFrame: (newData: Buffer | Uint8Array, onFrame: (buff: Uint8Array | BinaryNode) => void) => void
|
|
20
|
+
decodeFrame: (newData: Buffer | Uint8Array, onFrame: (buff: Uint8Array | BinaryNode) => void) => Promise<void>;
|
|
21
21
|
};
|
|
@@ -11,7 +11,7 @@ const generateIV = (counter) => {
|
|
|
11
11
|
new DataView(iv).setUint32(8, counter);
|
|
12
12
|
return new Uint8Array(iv);
|
|
13
13
|
};
|
|
14
|
-
const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER,
|
|
14
|
+
const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, logger, routingInfo }) => {
|
|
15
15
|
logger = logger.child({ class: 'ns' });
|
|
16
16
|
const authenticate = (data) => {
|
|
17
17
|
if (!isFinished) {
|
|
@@ -83,15 +83,10 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
83
83
|
const decStaticContent = decrypt(serverHello.static);
|
|
84
84
|
mixIntoKey(crypto_1.Curve.sharedKey(privateKey, decStaticContent));
|
|
85
85
|
const certDecoded = decrypt(serverHello.payload);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const { intermediate: certIntermediate } = WAProto_1.proto.CertChain.decode(certDecoded);
|
|
91
|
-
const { issuerSerial } = WAProto_1.proto.CertChain.NoiseCertificate.Details.decode(certIntermediate.details);
|
|
92
|
-
if (issuerSerial !== Defaults_1.WA_CERT_DETAILS.SERIAL) {
|
|
93
|
-
throw new boom_1.Boom('certification match failed', { statusCode: 400 });
|
|
94
|
-
}
|
|
86
|
+
const { intermediate: certIntermediate } = WAProto_1.proto.CertChain.decode(certDecoded);
|
|
87
|
+
const { issuerSerial } = WAProto_1.proto.CertChain.NoiseCertificate.Details.decode(certIntermediate.details);
|
|
88
|
+
if (issuerSerial !== Defaults_1.WA_CERT_DETAILS.SERIAL) {
|
|
89
|
+
throw new boom_1.Boom('certification match failed', { statusCode: 400 });
|
|
95
90
|
}
|
|
96
91
|
const keyEnc = encrypt(noiseKey.public);
|
|
97
92
|
mixIntoKey(crypto_1.Curve.sharedKey(noiseKey.private, serverHello.ephemeral));
|
|
@@ -125,7 +120,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
125
120
|
frame.set(data, introSize + 3);
|
|
126
121
|
return frame;
|
|
127
122
|
},
|
|
128
|
-
decodeFrame: (newData, onFrame) => {
|
|
123
|
+
decodeFrame: async (newData, onFrame) => {
|
|
129
124
|
var _a;
|
|
130
125
|
// the binary protocol uses its own framing mechanism
|
|
131
126
|
// on top of the WS frames
|
|
@@ -143,7 +138,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
143
138
|
inBytes = inBytes.slice(size + 3);
|
|
144
139
|
if (isFinished) {
|
|
145
140
|
const result = decrypt(frame);
|
|
146
|
-
frame = (0, WABinary_1.decodeBinaryNode)(result);
|
|
141
|
+
frame = await (0, WABinary_1.decodeBinaryNode)(result);
|
|
147
142
|
}
|
|
148
143
|
logger.trace({ msg: (_a = frame === null || frame === void 0 ? void 0 : frame.attrs) === null || _a === void 0 ? void 0 : _a.id }, 'recv frame');
|
|
149
144
|
onFrame(frame);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { AxiosRequestConfig } from 'axios';
|
|
2
2
|
import type { Logger } from 'pino';
|
|
3
3
|
import { proto } from '../../WAProto';
|
|
4
|
-
import { AuthenticationCreds, BaileysEventEmitter, SignalKeyStoreWithTransaction, SocketConfig } from '../Types';
|
|
4
|
+
import { AuthenticationCreds, BaileysEventEmitter, CacheStore, SignalKeyStoreWithTransaction, SocketConfig } from '../Types';
|
|
5
5
|
type ProcessMessageContext = {
|
|
6
6
|
shouldProcessHistoryMsg: boolean;
|
|
7
|
+
placeholderResendCache?: CacheStore;
|
|
7
8
|
creds: AuthenticationCreds;
|
|
8
9
|
keyStore: SignalKeyStoreWithTransaction;
|
|
9
10
|
ev: BaileysEventEmitter;
|
|
@@ -37,5 +38,5 @@ type PollContext = {
|
|
|
37
38
|
* @returns list of SHA256 options
|
|
38
39
|
*/
|
|
39
40
|
export declare function decryptPollVote({ encPayload, encIv }: proto.Message.IPollEncValue, { pollCreatorJid, pollMsgId, pollEncKey, voterJid, }: PollContext): proto.Message.PollVoteMessage;
|
|
40
|
-
declare const processMessage: (message: proto.IWebMessageInfo, { shouldProcessHistoryMsg, ev, creds, keyStore, logger, options, getMessage }: ProcessMessageContext) => Promise<void>;
|
|
41
|
+
declare const processMessage: (message: proto.IWebMessageInfo, { shouldProcessHistoryMsg, placeholderResendCache, ev, creds, keyStore, logger, options, getMessage }: ProcessMessageContext) => Promise<void>;
|
|
41
42
|
export default processMessage;
|
|
@@ -102,8 +102,8 @@ function decryptPollVote({ encPayload, encIv }, { pollCreatorJid, pollMsgId, pol
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
exports.decryptPollVote = decryptPollVote;
|
|
105
|
-
const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, keyStore, logger, options, getMessage }) => {
|
|
106
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
105
|
+
const processMessage = async (message, { shouldProcessHistoryMsg, placeholderResendCache, ev, creds, keyStore, logger, options, getMessage }) => {
|
|
106
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
107
107
|
const meId = creds.me.id;
|
|
108
108
|
const { accountSettings } = creds;
|
|
109
109
|
const chat = { id: (0, WABinary_1.jidNormalizedUser)((0, exports.getChatId)(message.key)) };
|
|
@@ -137,14 +137,22 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
137
137
|
isLatest,
|
|
138
138
|
}, 'got history notification');
|
|
139
139
|
if (process) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
140
|
+
if (histNotification.syncType !== WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND) {
|
|
141
|
+
ev.emit('creds.update', {
|
|
142
|
+
processedHistoryMessages: [
|
|
143
|
+
...(creds.processedHistoryMessages || []),
|
|
144
|
+
{ key: message.key, messageTimestamp: message.messageTimestamp }
|
|
145
|
+
]
|
|
146
|
+
});
|
|
147
|
+
}
|
|
146
148
|
const data = await (0, history_1.downloadAndProcessHistorySyncNotification)(histNotification, options);
|
|
147
|
-
ev.emit('messaging-history.set', {
|
|
149
|
+
ev.emit('messaging-history.set', {
|
|
150
|
+
...data,
|
|
151
|
+
isLatest: histNotification.syncType !== WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND
|
|
152
|
+
? isLatest
|
|
153
|
+
: undefined,
|
|
154
|
+
peerDataRequestSessionId: histNotification.peerDataRequestSessionId
|
|
155
|
+
});
|
|
148
156
|
}
|
|
149
157
|
break;
|
|
150
158
|
case WAProto_1.proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE:
|
|
@@ -187,14 +195,22 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
187
195
|
case WAProto_1.proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE:
|
|
188
196
|
const response = protocolMsg.peerDataOperationRequestResponseMessage;
|
|
189
197
|
if (response) {
|
|
198
|
+
placeholderResendCache === null || placeholderResendCache === void 0 ? void 0 : placeholderResendCache.del(response.stanzaId);
|
|
199
|
+
// TODO: IMPLEMENT HISTORY SYNC ETC (sticker uploads etc.).
|
|
190
200
|
const { peerDataOperationResult } = response;
|
|
191
201
|
for (const result of peerDataOperationResult) {
|
|
192
202
|
const { placeholderMessageResendResponse: retryResponse } = result;
|
|
203
|
+
//eslint-disable-next-line max-depth
|
|
193
204
|
if (retryResponse) {
|
|
194
205
|
const webMessageInfo = WAProto_1.proto.WebMessageInfo.decode(retryResponse.webMessageInfoBytes);
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
206
|
+
// wait till another upsert event is available, don't want it to be part of the PDO response message
|
|
207
|
+
setTimeout(() => {
|
|
208
|
+
ev.emit('messages.upsert', {
|
|
209
|
+
messages: [webMessageInfo],
|
|
210
|
+
type: 'notify',
|
|
211
|
+
requestId: response.stanzaId
|
|
212
|
+
});
|
|
213
|
+
}, 500);
|
|
198
214
|
}
|
|
199
215
|
}
|
|
200
216
|
}
|
|
@@ -208,11 +224,11 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
208
224
|
};
|
|
209
225
|
ev.emit('messages.reaction', [{
|
|
210
226
|
reaction,
|
|
211
|
-
key: content.reactionMessage.key,
|
|
227
|
+
key: (_d = content.reactionMessage) === null || _d === void 0 ? void 0 : _d.key,
|
|
212
228
|
}]);
|
|
213
229
|
}
|
|
214
230
|
else if (message.messageStubType) {
|
|
215
|
-
const jid = message.key.remoteJid;
|
|
231
|
+
const jid = (_e = message.key) === null || _e === void 0 ? void 0 : _e.remoteJid;
|
|
216
232
|
//let actor = whatsappID (message.participant)
|
|
217
233
|
let participants;
|
|
218
234
|
const emitParticipantsUpdate = (action) => (ev.emit('group-participants.update', { id: jid, author: message.participant, participants, action }));
|
|
@@ -220,8 +236,15 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
220
236
|
var _a;
|
|
221
237
|
ev.emit('groups.update', [{ id: jid, ...update, author: (_a = message.participant) !== null && _a !== void 0 ? _a : undefined }]);
|
|
222
238
|
};
|
|
239
|
+
const emitGroupRequestJoin = (participant, action, method) => {
|
|
240
|
+
ev.emit('group.join-request', { id: jid, author: message.participant, participant, action, method: method });
|
|
241
|
+
};
|
|
223
242
|
const participantsIncludesMe = () => participants.find(jid => (0, WABinary_1.areJidsSameUser)(meId, jid));
|
|
224
243
|
switch (message.messageStubType) {
|
|
244
|
+
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER:
|
|
245
|
+
participants = message.messageStubParameters || [];
|
|
246
|
+
emitParticipantsUpdate('modify');
|
|
247
|
+
break;
|
|
225
248
|
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_LEAVE:
|
|
226
249
|
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_REMOVE:
|
|
227
250
|
participants = message.messageStubParameters || [];
|
|
@@ -249,30 +272,41 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
249
272
|
emitParticipantsUpdate('promote');
|
|
250
273
|
break;
|
|
251
274
|
case Types_1.WAMessageStubType.GROUP_CHANGE_ANNOUNCE:
|
|
252
|
-
const announceValue = (
|
|
275
|
+
const announceValue = (_f = message.messageStubParameters) === null || _f === void 0 ? void 0 : _f[0];
|
|
253
276
|
emitGroupUpdate({ announce: announceValue === 'true' || announceValue === 'on' });
|
|
254
277
|
break;
|
|
255
278
|
case Types_1.WAMessageStubType.GROUP_CHANGE_RESTRICT:
|
|
256
|
-
const restrictValue = (
|
|
279
|
+
const restrictValue = (_g = message.messageStubParameters) === null || _g === void 0 ? void 0 : _g[0];
|
|
257
280
|
emitGroupUpdate({ restrict: restrictValue === 'true' || restrictValue === 'on' });
|
|
258
281
|
break;
|
|
259
282
|
case Types_1.WAMessageStubType.GROUP_CHANGE_SUBJECT:
|
|
260
|
-
const name = (
|
|
283
|
+
const name = (_h = message.messageStubParameters) === null || _h === void 0 ? void 0 : _h[0];
|
|
261
284
|
chat.name = name;
|
|
262
285
|
emitGroupUpdate({ subject: name });
|
|
263
286
|
break;
|
|
287
|
+
case Types_1.WAMessageStubType.GROUP_CHANGE_DESCRIPTION:
|
|
288
|
+
const description = (_j = message.messageStubParameters) === null || _j === void 0 ? void 0 : _j[0];
|
|
289
|
+
chat.description = description;
|
|
290
|
+
emitGroupUpdate({ desc: description });
|
|
291
|
+
break;
|
|
264
292
|
case Types_1.WAMessageStubType.GROUP_CHANGE_INVITE_LINK:
|
|
265
|
-
const code = (
|
|
293
|
+
const code = (_k = message.messageStubParameters) === null || _k === void 0 ? void 0 : _k[0];
|
|
266
294
|
emitGroupUpdate({ inviteCode: code });
|
|
267
295
|
break;
|
|
268
296
|
case Types_1.WAMessageStubType.GROUP_MEMBER_ADD_MODE:
|
|
269
|
-
const memberAddValue = (
|
|
297
|
+
const memberAddValue = (_l = message.messageStubParameters) === null || _l === void 0 ? void 0 : _l[0];
|
|
270
298
|
emitGroupUpdate({ memberAddMode: memberAddValue === 'all_member_add' });
|
|
271
299
|
break;
|
|
272
300
|
case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE:
|
|
273
|
-
const approvalMode = (
|
|
301
|
+
const approvalMode = (_m = message.messageStubParameters) === null || _m === void 0 ? void 0 : _m[0];
|
|
274
302
|
emitGroupUpdate({ joinApprovalMode: approvalMode === 'on' });
|
|
275
303
|
break;
|
|
304
|
+
case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD:
|
|
305
|
+
const participant = (_o = message.messageStubParameters) === null || _o === void 0 ? void 0 : _o[0];
|
|
306
|
+
const action = (_p = message.messageStubParameters) === null || _p === void 0 ? void 0 : _p[1];
|
|
307
|
+
const method = (_q = message.messageStubParameters) === null || _q === void 0 ? void 0 : _q[2];
|
|
308
|
+
emitGroupRequestJoin(participant, action, method);
|
|
309
|
+
break;
|
|
276
310
|
}
|
|
277
311
|
}
|
|
278
312
|
else if (content === null || content === void 0 ? void 0 : content.pollUpdateMessage) {
|
|
@@ -283,7 +317,7 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
283
317
|
const meIdNormalised = (0, WABinary_1.jidNormalizedUser)(meId);
|
|
284
318
|
const pollCreatorJid = (0, generics_1.getKeyAuthor)(creationMsgKey, meIdNormalised);
|
|
285
319
|
const voterJid = (0, generics_1.getKeyAuthor)(message.key, meIdNormalised);
|
|
286
|
-
const pollEncKey = (
|
|
320
|
+
const pollEncKey = (_r = pollMsg.messageContextInfo) === null || _r === void 0 ? void 0 : _r.messageSecret;
|
|
287
321
|
try {
|
|
288
322
|
const voteMsg = decryptPollVote(content.pollUpdateMessage.vote, {
|
|
289
323
|
pollEncKey,
|