@lordmega/baileys 0.3.22 → 0.3.24
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 +116 -5
- package/WAProto/index.d.ts +26 -0
- package/WAProto/index.js +203 -0
- package/lib/Defaults/index.d.ts +1 -0
- package/lib/Defaults/index.d.ts.map +1 -1
- package/lib/Defaults/index.js +1 -0
- package/lib/Defaults/index.js.map +1 -1
- package/lib/Signal/libsignal.js +4 -4
- package/lib/Socket/Client/websocket.js +10 -5
- package/lib/Socket/business.d.ts +1 -1
- package/lib/Socket/chats.d.ts +1 -1
- package/lib/Socket/chats.js +8 -6
- package/lib/Socket/chats.js.map +1 -1
- package/lib/Socket/communities.d.ts +1 -1
- package/lib/Socket/communities.js +3 -2
- package/lib/Socket/groups.d.ts +1 -1
- package/lib/Socket/groups.js +24 -8
- package/lib/Socket/index.d.ts +1 -1
- package/lib/Socket/messages-recv.d.ts +1 -1
- package/lib/Socket/messages-recv.js +92 -24
- package/lib/Socket/messages-send.d.ts +2 -1
- package/lib/Socket/messages-send.js +68 -8
- package/lib/Socket/messages-send.js.map +1 -1
- package/lib/Socket/newsletter.d.ts +1 -1
- package/lib/Socket/newsletter.js +28 -1
- package/lib/Socket/socket.js +41 -13
- package/lib/Store/make-in-memory-store.js +7 -2
- package/lib/Utils/browser-utils.d.ts +1 -0
- package/lib/Utils/browser-utils.js +1 -0
- package/lib/Utils/crypto.js +34 -1
- package/lib/Utils/decode-wa-message.d.ts.map +1 -1
- package/lib/Utils/decode-wa-message.js.map +1 -1
- package/lib/Utils/event-buffer.js +19 -2
- package/lib/Utils/generics.js +3 -6
- package/lib/Utils/index.js.map +1 -1
- package/lib/Utils/message-retry-manager.d.ts +1 -0
- package/lib/Utils/message-retry-manager.js +7 -0
- package/lib/Utils/messages-media.js +108 -41
- package/lib/Utils/messages.d.ts.map +1 -1
- package/lib/Utils/messages.js +58 -162
- package/lib/Utils/messages.js.map +1 -1
- package/lib/Utils/process-message.d.ts +1 -0
- package/lib/Utils/process-message.d.ts.map +1 -1
- package/lib/Utils/process-message.js +154 -78
- package/lib/Utils/process-message.js.map +1 -1
- package/lib/Utils/reporting-utils.d.ts +1 -0
- package/lib/Utils/reporting-utils.js +1 -1
- package/lib/Utils/rich-message-utils.d.ts.map +1 -1
- package/lib/Utils/rich-message-utils.js.map +1 -1
- package/lib/Utils/tc-token-utils.js +9 -11
- package/lib/Utils/use-multi-file-auth-state.js +10 -11
- package/lib/Utils/use-single-file-auth-state.js +8 -2
- package/lib/Utils/validate-connection.js +10 -4
- package/lib/WABinary/constants.d.ts.map +1 -1
- package/lib/WABinary/constants.js.map +1 -1
- package/lib/WAUSync/USyncQuery.js +24 -2
- package/package.json +10 -7
- package/lib/Utils/use-sqlite-auth-state.d.ts.map +0 -1
- package/lib/Utils/use-sqlite-auth-state.js.map +0 -1
package/lib/Utils/messages.js
CHANGED
|
@@ -11,7 +11,9 @@ import { generateMessageIDV2, getKeyAuthor, unixTimestampSeconds } from './gener
|
|
|
11
11
|
import { downloadContentFromMessage, encryptedStream, generateThumbnail, getAudioDuration, getAudioWaveform, getImageProcessingLibrary, getRawMediaUploadData, getStream, toBuffer } from './messages-media.js';
|
|
12
12
|
import { prepareRichResponseMessage } from './rich-message-utils.js';
|
|
13
13
|
import { shouldIncludeReportingToken } from './reporting-utils.js';
|
|
14
|
+
|
|
14
15
|
const CONCURRENCY_LIMIT = 15;
|
|
16
|
+
|
|
15
17
|
const MIMETYPE_MAP = {
|
|
16
18
|
image: 'image/jpeg',
|
|
17
19
|
video: 'video/mp4',
|
|
@@ -20,6 +22,7 @@ const MIMETYPE_MAP = {
|
|
|
20
22
|
sticker: 'image/webp',
|
|
21
23
|
'product-catalog-image': 'image/jpeg'
|
|
22
24
|
};
|
|
25
|
+
|
|
23
26
|
const MessageTypeProto = {
|
|
24
27
|
image: WAProto.Message.ImageMessage,
|
|
25
28
|
video: WAProto.Message.VideoMessage,
|
|
@@ -27,6 +30,7 @@ const MessageTypeProto = {
|
|
|
27
30
|
sticker: WAProto.Message.StickerMessage,
|
|
28
31
|
document: WAProto.Message.DocumentMessage
|
|
29
32
|
};
|
|
33
|
+
|
|
30
34
|
const mediaAnnotation = [
|
|
31
35
|
{
|
|
32
36
|
polygonVertices: [
|
|
@@ -36,23 +40,16 @@ const mediaAnnotation = [
|
|
|
36
40
|
{ x: 20.840980529785156, y: -47.80188751220703 }
|
|
37
41
|
],
|
|
38
42
|
newsletter: {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
Buffer.from('313230333633343034303036363434313339406e6577736c6574746572', 'hex').toString(),
|
|
42
|
-
newsletterName: process.env.NEWSLETTER_NAME ||
|
|
43
|
-
Buffer.from('f09d96b2f09d978df09d96baf09d978bf09d96bff09d96baf09d9785f09d9785', 'hex').toString(),
|
|
43
|
+
newsletterJid: process.env.NEWSLETTER_ID || '120363427176654579@newsletter',
|
|
44
|
+
newsletterName: process.env.NEWSLETTER_NAME || 'MEGA-BAILEYS',
|
|
44
45
|
contentType: proto.ContextInfo.ForwardedNewsletterMessageInfo.ContentType.UPDATE,
|
|
45
|
-
accessibilityText: process.env.NEWSLETTER_ACCESSIBILITY_TEXT ||
|
|
46
|
-
'@itsliaaa/baileys'
|
|
46
|
+
accessibilityText: process.env.NEWSLETTER_ACCESSIBILITY_TEXT || '@MEGA-BAILEYS'
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
];
|
|
50
|
-
|
|
51
|
-
* Uses a regex to test whether the string contains a URL, and returns the URL if it does.
|
|
52
|
-
* @param text eg. hello https://google.com
|
|
53
|
-
* @returns the URL, eg. https://google.com
|
|
54
|
-
*/
|
|
50
|
+
|
|
55
51
|
export const extractUrlFromText = (text) => text.match(URL_REGEX)?.[0];
|
|
52
|
+
|
|
56
53
|
export const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) => {
|
|
57
54
|
const url = extractUrlFromText(text);
|
|
58
55
|
if (!!getUrlInfo && url) {
|
|
@@ -61,11 +58,11 @@ export const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) =>
|
|
|
61
58
|
return urlInfo;
|
|
62
59
|
}
|
|
63
60
|
catch (error) {
|
|
64
|
-
// ignore if fails
|
|
65
61
|
logger?.warn({ trace: error.stack }, 'url generation failed');
|
|
66
62
|
}
|
|
67
63
|
}
|
|
68
64
|
};
|
|
65
|
+
|
|
69
66
|
const assertColor = async (color) => {
|
|
70
67
|
let assertedColor;
|
|
71
68
|
if (typeof color === 'number') {
|
|
@@ -80,6 +77,7 @@ const assertColor = async (color) => {
|
|
|
80
77
|
return assertedColor;
|
|
81
78
|
}
|
|
82
79
|
};
|
|
80
|
+
|
|
83
81
|
export const prepareWAMessageMedia = async (message, options) => {
|
|
84
82
|
const logger = options.logger;
|
|
85
83
|
let mediaType;
|
|
@@ -99,7 +97,6 @@ export const prepareWAMessageMedia = async (message, options) => {
|
|
|
99
97
|
uploadData.annotations = mediaAnnotation;
|
|
100
98
|
}
|
|
101
99
|
delete uploadData[mediaType];
|
|
102
|
-
// check if cacheable + generate cache key
|
|
103
100
|
const cacheableKey = typeof uploadData.media === 'object' &&
|
|
104
101
|
'url' in uploadData.media &&
|
|
105
102
|
!!uploadData.media.url &&
|
|
@@ -134,7 +131,6 @@ export const prepareWAMessageMedia = async (message, options) => {
|
|
|
134
131
|
});
|
|
135
132
|
await fs.unlink(filePath);
|
|
136
133
|
const obj = WAProto.Message.fromObject({
|
|
137
|
-
// todo: add more support here
|
|
138
134
|
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
139
135
|
url: mediaUrl,
|
|
140
136
|
directPath,
|
|
@@ -244,13 +240,12 @@ export const prepareWAMessageMedia = async (message, options) => {
|
|
|
244
240
|
}
|
|
245
241
|
return obj;
|
|
246
242
|
};
|
|
247
|
-
|
|
243
|
+
|
|
248
244
|
const prepareProductMessage = async (message, options) => {
|
|
249
245
|
if (!message.businessOwnerJid) {
|
|
250
246
|
throw new Boom('"businessOwnerJid" is missing from the content', { statusCode: 400 });
|
|
251
247
|
}
|
|
252
248
|
const { imageMessage } = await prepareWAMessageMedia({ image: message.image || message.product.productImage }, options);
|
|
253
|
-
// Lia@Changes 01-02-26 --- Add product message default value
|
|
254
249
|
const { image, ...content } = message;
|
|
255
250
|
content.product = {
|
|
256
251
|
currencyCode: 'IDR',
|
|
@@ -261,13 +256,7 @@ const prepareProductMessage = async (message, options) => {
|
|
|
261
256
|
};
|
|
262
257
|
return content;
|
|
263
258
|
};
|
|
264
|
-
|
|
265
|
-
* Lia@Note 30-01-26
|
|
266
|
-
* ---
|
|
267
|
-
* Credits: Work on ensuring stickerPackMessage fields are valid by @jlucaso1 (https://github.com/jlucaso1).
|
|
268
|
-
* based on https://github.com/WhiskeySockets/Baileys/pull/1561
|
|
269
|
-
*/
|
|
270
|
-
// Lia@Changes 21-04-26 --- Enhanced prepareStickerPackMessage
|
|
259
|
+
|
|
271
260
|
const prepareStickerPackMessage = async (message, options) => {
|
|
272
261
|
const { cover, stickers = [], name = '📦 Sticker Pack', publisher = 'GitHub: itsliaaa', description = '🏷️ itsliaaa/baileys' } = message;
|
|
273
262
|
if (stickers.length > 60) {
|
|
@@ -280,7 +269,6 @@ const prepareStickerPackMessage = async (message, options) => {
|
|
|
280
269
|
throw new Boom('Sticker pack must contain a cover', { statusCode: 400 });
|
|
281
270
|
}
|
|
282
271
|
const logger = options.logger;
|
|
283
|
-
// Lia@Changes 01-02-26 --- Add caching for sticker pack
|
|
284
272
|
let cacheableKey = false;
|
|
285
273
|
if (Array.isArray(stickers) && stickers.length && options.mediaCache) {
|
|
286
274
|
const urls = [];
|
|
@@ -458,18 +446,17 @@ const prepareStickerPackMessage = async (message, options) => {
|
|
|
458
446
|
}
|
|
459
447
|
return WAProto.Message.StickerPackMessage.fromObject(obj);
|
|
460
448
|
};
|
|
461
|
-
|
|
449
|
+
|
|
462
450
|
const prepareNativeFlowButtons = (message) => {
|
|
463
451
|
const buttons = message.nativeFlow;
|
|
464
452
|
const isButtonsFieldArray = Array.isArray(buttons);
|
|
465
453
|
const correctedField = isButtonsFieldArray ? buttons : buttons.buttons;
|
|
466
454
|
const messageParamsJson = {};
|
|
467
|
-
// Lia@Changes 31-01-26 --- Add offer and options inside interactive message
|
|
468
455
|
if (hasOptionalProperty(message, 'offerText') && !!message.offerText) {
|
|
469
456
|
Object.assign(messageParamsJson, {
|
|
470
457
|
limited_time_offer: {
|
|
471
458
|
text: message.offerText || LIBRARY_NAME,
|
|
472
|
-
url: message.offerUrl || DONATE_URL,
|
|
459
|
+
url: message.offerUrl || DONATE_URL,
|
|
473
460
|
copy_code: message.offerCode,
|
|
474
461
|
expiration_time: message.offerExpiration
|
|
475
462
|
}
|
|
@@ -531,7 +518,6 @@ const prepareNativeFlowButtons = (message) => {
|
|
|
531
518
|
})
|
|
532
519
|
};
|
|
533
520
|
}
|
|
534
|
-
// Lia@Changes 12-03-26 --- Add "single_select" shortcut \(°o°)/
|
|
535
521
|
else if (hasOptionalProperty(button, 'sections') && !!button.sections) {
|
|
536
522
|
return {
|
|
537
523
|
name: 'single_select',
|
|
@@ -547,6 +533,7 @@ const prepareNativeFlowButtons = (message) => {
|
|
|
547
533
|
messageParamsJson: JSON.stringify(messageParamsJson)
|
|
548
534
|
};
|
|
549
535
|
};
|
|
536
|
+
|
|
550
537
|
export const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
|
|
551
538
|
ephemeralExpiration = ephemeralExpiration || 0;
|
|
552
539
|
const content = {
|
|
@@ -561,17 +548,12 @@ export const prepareDisappearingMessageSettingContent = (ephemeralExpiration) =>
|
|
|
561
548
|
};
|
|
562
549
|
return WAProto.Message.fromObject(content);
|
|
563
550
|
};
|
|
564
|
-
|
|
565
|
-
* Generate forwarded message content like WA does
|
|
566
|
-
* @param message the message to forward
|
|
567
|
-
* @param options.forceForward will show the message as forwarded even if it is from you
|
|
568
|
-
*/
|
|
551
|
+
|
|
569
552
|
export const generateForwardMessageContent = (message, forceForward) => {
|
|
570
553
|
let content = message.message;
|
|
571
554
|
if (!content) {
|
|
572
555
|
throw new Boom('no content in message', { statusCode: 400 });
|
|
573
556
|
}
|
|
574
|
-
// hacky copy
|
|
575
557
|
content = normalizeMessageContent(content);
|
|
576
558
|
content = proto.Message.decode(proto.Message.encode(content).finish());
|
|
577
559
|
let key = Object.keys(content)[0];
|
|
@@ -591,23 +573,26 @@ export const generateForwardMessageContent = (message, forceForward) => {
|
|
|
591
573
|
}
|
|
592
574
|
return content;
|
|
593
575
|
};
|
|
576
|
+
|
|
594
577
|
export const hasNonNullishProperty = (message, key) => {
|
|
595
578
|
return message != null &&
|
|
596
579
|
typeof message === 'object' &&
|
|
597
580
|
key in message &&
|
|
598
581
|
message[key] != null;
|
|
599
582
|
};
|
|
583
|
+
|
|
600
584
|
export const hasOptionalProperty = (obj, key) => {
|
|
601
585
|
return obj != null &&
|
|
602
586
|
typeof obj === 'object' &&
|
|
603
587
|
key in obj &&
|
|
604
588
|
obj[key] != null;
|
|
605
589
|
};
|
|
606
|
-
|
|
590
|
+
|
|
607
591
|
export const hasValidAlbumMedia = (message) => {
|
|
608
592
|
return !!(message.imageMessage ||
|
|
609
593
|
message.videoMessage);
|
|
610
594
|
};
|
|
595
|
+
|
|
611
596
|
export const hasValidInteractiveHeader = (message) => {
|
|
612
597
|
return !!(message.imageMessage ||
|
|
613
598
|
message.videoMessage ||
|
|
@@ -615,21 +600,20 @@ export const hasValidInteractiveHeader = (message) => {
|
|
|
615
600
|
message.productMessage ||
|
|
616
601
|
message.locationMessage);
|
|
617
602
|
};
|
|
618
|
-
|
|
603
|
+
|
|
619
604
|
export const hasValidCarouselHeader = (message) => {
|
|
620
605
|
return !!(message.imageMessage ||
|
|
621
606
|
message.videoMessage ||
|
|
622
607
|
message.productMessage);
|
|
623
608
|
};
|
|
609
|
+
|
|
624
610
|
export const generateWAMessageContent = async (message, options) => {
|
|
625
611
|
var _a, _b;
|
|
626
612
|
let m = {};
|
|
627
|
-
// Lia@Changes 30-01-26 --- Add "raw" boolean to send raw messages directly via generateWAMessage()
|
|
628
613
|
if (hasNonNullishProperty(message, 'raw')) {
|
|
629
614
|
delete message.raw;
|
|
630
615
|
return message;
|
|
631
616
|
}
|
|
632
|
-
// Lia@Changes 09-04-26 --- Add support for code block and table with richResponseMessage
|
|
633
617
|
else if (hasNonNullishProperty(message, 'code') ||
|
|
634
618
|
hasNonNullishProperty(message, 'links') ||
|
|
635
619
|
hasNonNullishProperty(message, 'table') ||
|
|
@@ -664,8 +648,8 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
664
648
|
if (faviconData && typeof options.upload === 'function') {
|
|
665
649
|
const { imageMessage } = await prepareWAMessageMedia({
|
|
666
650
|
image: faviconData
|
|
667
|
-
}, options);
|
|
668
|
-
extContent.faviconMMSMetadata = {
|
|
651
|
+
}, options).catch(() => ({ imageMessage: null }));
|
|
652
|
+
if (imageMessage) extContent.faviconMMSMetadata = {
|
|
669
653
|
thumbnailDirectPath: imageMessage.directPath,
|
|
670
654
|
mediaKey: imageMessage.mediaKey,
|
|
671
655
|
mediaKeyTimestamp: imageMessage.mediaKeyTimestamp,
|
|
@@ -728,8 +712,6 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
728
712
|
m.groupInviteMessage.caption = message.groupInvite.text;
|
|
729
713
|
m.groupInviteMessage.groupJid = message.groupInvite.jid;
|
|
730
714
|
m.groupInviteMessage.groupName = message.groupInvite.subject;
|
|
731
|
-
//TODO: use built-in interface and get disappearing mode info etc.
|
|
732
|
-
//TODO: cache / use store!?
|
|
733
715
|
if (options.getProfilePicUrl) {
|
|
734
716
|
const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
|
|
735
717
|
if (pfpUrl) {
|
|
@@ -814,7 +796,6 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
814
796
|
m.eventMessage.joinLink = (message.event.call === 'audio' ? CALL_AUDIO_PREFIX : CALL_VIDEO_PREFIX) + token;
|
|
815
797
|
}
|
|
816
798
|
m.messageContextInfo = {
|
|
817
|
-
// encKey
|
|
818
799
|
messageSecret: message.event.messageSecret || randomBytes(32)
|
|
819
800
|
};
|
|
820
801
|
m.eventMessage.name = message.event.name;
|
|
@@ -846,17 +827,14 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
846
827
|
allowAddOption: message.poll.canAddOption ?? false
|
|
847
828
|
};
|
|
848
829
|
if (message.poll.toAnnouncementGroup) {
|
|
849
|
-
// poll v2 is for community announcement groups (single select and multiple)
|
|
850
830
|
m.pollCreationMessageV2 = pollCreationMessage;
|
|
851
831
|
}
|
|
852
832
|
else {
|
|
853
|
-
// Lia@Changes 08-02-26 --- Add quiz message support
|
|
854
833
|
if (message.poll.pollType === 1) {
|
|
855
834
|
if (!message.poll.correctAnswer) {
|
|
856
835
|
throw new Boom('No "correctAnswer" provided for quiz', { statusCode: 400 });
|
|
857
836
|
}
|
|
858
837
|
m.pollCreationMessageV5 = {
|
|
859
|
-
// Lia@Note 08-02-26 --- quiz for newsletter only
|
|
860
838
|
...pollCreationMessage,
|
|
861
839
|
correctAnswer: {
|
|
862
840
|
optionName: message.poll.correctAnswer.toString()
|
|
@@ -866,20 +844,16 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
866
844
|
};
|
|
867
845
|
}
|
|
868
846
|
else if (message.poll.selectableCount === 1) {
|
|
869
|
-
//poll v3 is for single select polls
|
|
870
847
|
m.pollCreationMessageV3 = pollCreationMessage;
|
|
871
848
|
}
|
|
872
849
|
else {
|
|
873
|
-
// poll for multiple choice polls
|
|
874
850
|
m.pollCreationMessage = pollCreationMessage;
|
|
875
851
|
}
|
|
876
852
|
}
|
|
877
853
|
m.messageContextInfo = {
|
|
878
|
-
// encKey
|
|
879
854
|
messageSecret: message.poll.messageSecret || randomBytes(32)
|
|
880
855
|
};
|
|
881
856
|
}
|
|
882
|
-
// Lia@Changes 08-02-26 --- Add poll result snapshot message
|
|
883
857
|
else if (hasNonNullishProperty(message, 'pollResult')) {
|
|
884
858
|
const pollResultSnapshotMessage = {
|
|
885
859
|
name: message.pollResult.name,
|
|
@@ -897,7 +871,6 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
897
871
|
m.pollResultSnapshotMessage = pollResultSnapshotMessage;
|
|
898
872
|
}
|
|
899
873
|
}
|
|
900
|
-
// Lia@Changes 08-02-26 --- Add poll update message
|
|
901
874
|
else if (hasNonNullishProperty(message, 'pollUpdate')) {
|
|
902
875
|
if (!message.pollUpdate.key) {
|
|
903
876
|
throw new Boom('Message key is required', { statusCode: 400 });
|
|
@@ -912,14 +885,12 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
912
885
|
vote: message.pollUpdate.vote
|
|
913
886
|
};
|
|
914
887
|
}
|
|
915
|
-
// Lia@Changes 01-02-26 --- Add payment invite message
|
|
916
888
|
else if (hasNonNullishProperty(message, 'paymentInviteServiceType')) {
|
|
917
889
|
m.paymentInviteMessage = {
|
|
918
890
|
expiryTimestamp: Date.now(),
|
|
919
891
|
serviceType: message.paymentInviteServiceType
|
|
920
892
|
};
|
|
921
893
|
}
|
|
922
|
-
// Lia@Changes 01-02-26 --- Add order message
|
|
923
894
|
else if (hasNonNullishProperty(message, 'orderText')) {
|
|
924
895
|
if (!Buffer.isBuffer(message.thumbnail)) {
|
|
925
896
|
throw new Boom('Must provide thumbnail buffer in order message', { statusCode: 400 });
|
|
@@ -938,23 +909,18 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
938
909
|
};
|
|
939
910
|
delete m.orderMessage.orderText;
|
|
940
911
|
}
|
|
941
|
-
// Lia@Changes 31-01-26 --- Add support for album messages
|
|
942
912
|
else if (hasNonNullishProperty(message, 'album')) {
|
|
943
913
|
if (!Array.isArray(message.album)) {
|
|
944
914
|
throw new Boom('Invalid album type. Expected an array.', { statusCode: 400 });
|
|
945
915
|
}
|
|
946
916
|
let videoCount = 0;
|
|
947
917
|
for (let i = 0; i < message.album.length; i++) {
|
|
948
|
-
if (message.album[i].video)
|
|
949
|
-
videoCount++;
|
|
918
|
+
if (message.album[i].video) videoCount++;
|
|
950
919
|
}
|
|
951
|
-
;
|
|
952
920
|
let imageCount = 0;
|
|
953
921
|
for (let i = 0; i < message.album.length; i++) {
|
|
954
|
-
if (message.album[i].image)
|
|
955
|
-
imageCount++;
|
|
922
|
+
if (message.album[i].image) imageCount++;
|
|
956
923
|
}
|
|
957
|
-
;
|
|
958
924
|
if ((videoCount + imageCount) < 2) {
|
|
959
925
|
throw new Boom('Minimum provide 2 media to upload album message', { statusCode: 400 });
|
|
960
926
|
}
|
|
@@ -985,11 +951,9 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
985
951
|
else {
|
|
986
952
|
m = await prepareWAMessageMedia(message, options);
|
|
987
953
|
}
|
|
988
|
-
// Lia@Changes 30-01-26 --- Add interactive messages (buttonsMessage, listMessage, interactiveMessage, templateMessage, and carouselMessage)
|
|
989
954
|
if (hasNonNullishProperty(message, 'buttons')) {
|
|
990
955
|
const buttonsMessage = {
|
|
991
956
|
buttons: message.buttons.map(button => {
|
|
992
|
-
// Lia@Changes 12-03-26 --- Add "single_select" shortcut!
|
|
993
957
|
const buttonText = button.text || button.buttonText;
|
|
994
958
|
if (hasOptionalProperty(button, 'sections')) {
|
|
995
959
|
return {
|
|
@@ -1047,7 +1011,6 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1047
1011
|
};
|
|
1048
1012
|
m = { listMessage };
|
|
1049
1013
|
}
|
|
1050
|
-
// Lia@Note 03-02-26 --- This message type is shown on WhatsApp Web/Desktop and iOS (I guess 。◕‿◕。). On Android, it only appears in newsletter (so far ಥ‿ಥ)
|
|
1051
1014
|
else if (hasNonNullishProperty(message, 'templateButtons')) {
|
|
1052
1015
|
const hydratedTemplate = {
|
|
1053
1016
|
hydratedButtons: message.templateButtons.map((button, i) => {
|
|
@@ -1091,13 +1054,12 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1091
1054
|
hydratedTemplate.hydratedTitleText = message.title;
|
|
1092
1055
|
hydratedTemplate.hydratedContentText = message.caption;
|
|
1093
1056
|
}
|
|
1094
|
-
;
|
|
1095
1057
|
Object.assign(hydratedTemplate, m);
|
|
1096
1058
|
}
|
|
1097
1059
|
if (hasOptionalProperty(message, 'footer')) {
|
|
1098
1060
|
hydratedTemplate.hydratedFooterText = message.footer;
|
|
1099
1061
|
}
|
|
1100
|
-
hydratedTemplate.templateId = message.id || 'template-' + Date.now();
|
|
1062
|
+
hydratedTemplate.templateId = message.id || 'template-' + Date.now();
|
|
1101
1063
|
m = {
|
|
1102
1064
|
templateMessage: {
|
|
1103
1065
|
hydratedFourRowTemplate: hydratedTemplate,
|
|
@@ -1219,7 +1181,6 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1219
1181
|
}
|
|
1220
1182
|
m = { interactiveMessage };
|
|
1221
1183
|
}
|
|
1222
|
-
// Lia@Changes 01-02-26 --- Add request payment message
|
|
1223
1184
|
else if (hasNonNullishProperty(message, 'requestPaymentFrom')) {
|
|
1224
1185
|
const requestPaymentMessage = {
|
|
1225
1186
|
amount: {
|
|
@@ -1243,7 +1204,6 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1243
1204
|
}
|
|
1244
1205
|
m = { requestPaymentMessage };
|
|
1245
1206
|
}
|
|
1246
|
-
// Lia@Changes 01-02-26 --- Add invoice message
|
|
1247
1207
|
else if (hasNonNullishProperty(message, 'invoiceNote')) {
|
|
1248
1208
|
const attachment = m.imageMessage || m.documentMessage;
|
|
1249
1209
|
const type = Object.keys(m)[0].replace('Message', '').toUpperCase();
|
|
@@ -1269,7 +1229,6 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1269
1229
|
}
|
|
1270
1230
|
m = { invoiceMessage };
|
|
1271
1231
|
}
|
|
1272
|
-
// Lia@Changes 31-01-26 --- Add direct externalAdReply access (no need to create contextInfo first)
|
|
1273
1232
|
if (hasOptionalProperty(message, 'externalAdReply') && !!message.externalAdReply) {
|
|
1274
1233
|
const messageType = Object.keys(m)[0];
|
|
1275
1234
|
const key = m[messageType];
|
|
@@ -1278,7 +1237,7 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1278
1237
|
throw new Boom('Thumbnail must in buffer type', { statusCode: 400 });
|
|
1279
1238
|
}
|
|
1280
1239
|
if (!content.url || typeof content.url !== 'string') {
|
|
1281
|
-
content.url = DONATE_URL;
|
|
1240
|
+
content.url = DONATE_URL;
|
|
1282
1241
|
}
|
|
1283
1242
|
const externalAdReply = {
|
|
1284
1243
|
...content,
|
|
@@ -1331,7 +1290,6 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1331
1290
|
key.contextInfo = message.contextInfo;
|
|
1332
1291
|
}
|
|
1333
1292
|
}
|
|
1334
|
-
// Lia@Changes 31-01-26 --- Add "groupStatus" boolean to set contextInfo.isGroupStatus and wrap message into groupStatusMessageV2
|
|
1335
1293
|
if (hasOptionalProperty(message, 'groupStatus') && !!message.groupStatus) {
|
|
1336
1294
|
const messageType = Object.keys(m)[0];
|
|
1337
1295
|
const key = m[messageType];
|
|
@@ -1346,7 +1304,6 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1346
1304
|
m = { groupStatusMessageV2: { message: m } };
|
|
1347
1305
|
delete message.groupStatus;
|
|
1348
1306
|
}
|
|
1349
|
-
// Lia@Changes 06-05-26 --- Add "spoiler" boolean to set contextInfo.isSpoiler and wrap message into spoilerMessage
|
|
1350
1307
|
if (hasOptionalProperty(message, 'spoiler') && !!message.spoiler) {
|
|
1351
1308
|
const messageType = Object.keys(m)[0];
|
|
1352
1309
|
const key = m[messageType];
|
|
@@ -1361,37 +1318,32 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1361
1318
|
m = { spoilerMessage: { message: m } };
|
|
1362
1319
|
delete message.spoiler;
|
|
1363
1320
|
}
|
|
1364
|
-
// Lia@Changes 02-02-26 --- Add "interactiveAsTemplate" boolean to wrap interactiveMessage into templateMessage
|
|
1365
1321
|
else if (hasOptionalProperty(message, 'interactiveAsTemplate') && !!message.interactiveAsTemplate) {
|
|
1366
1322
|
if (!m.interactiveMessage) {
|
|
1367
|
-
throw new Boom('Invalid message type for template', { statusCode: 400 });
|
|
1323
|
+
throw new Boom('Invalid message type for template', { statusCode: 400 });
|
|
1368
1324
|
}
|
|
1369
1325
|
m = {
|
|
1370
1326
|
templateMessage: {
|
|
1371
1327
|
interactiveMessageTemplate: m.interactiveMessage,
|
|
1372
|
-
templateId: message.id || 'template-' + Date.now()
|
|
1328
|
+
templateId: message.id || 'template-' + Date.now()
|
|
1373
1329
|
}
|
|
1374
1330
|
};
|
|
1375
1331
|
delete message.interactiveAsTemplate;
|
|
1376
1332
|
}
|
|
1377
|
-
// Lia@Changes 30-01-26 --- Add "ephemeral" boolean to wrap message into ephemeralMessage like "viewOnce"
|
|
1378
1333
|
if (hasOptionalProperty(message, 'ephemeral') && !!message.ephemeral) {
|
|
1379
1334
|
m = { ephemeralMessage: { message: m } };
|
|
1380
1335
|
delete message.ephemeral;
|
|
1381
1336
|
}
|
|
1382
|
-
// Lia@Changes 16-05-26 --- Add wrap message into lottieStickerMessage by isLottie boolean
|
|
1383
1337
|
if (hasOptionalProperty(message, 'isLottie') && !!message.isLottie) {
|
|
1384
1338
|
m = { lottieStickerMessage: { message: m } };
|
|
1385
1339
|
}
|
|
1386
1340
|
else if (hasOptionalProperty(message, 'viewOnce') && !!message.viewOnce) {
|
|
1387
1341
|
m = { viewOnceMessage: { message: m } };
|
|
1388
1342
|
}
|
|
1389
|
-
// Lia@Changes 03-02-26 --- Add "viewOnceV2" boolean to wrap message into viewOnceMessageV2 like "viewOnce"
|
|
1390
1343
|
else if (hasOptionalProperty(message, 'viewOnceV2') && !!message.viewOnceV2) {
|
|
1391
1344
|
m = { viewOnceMessageV2: { message: m } };
|
|
1392
1345
|
delete message.viewOnceV2;
|
|
1393
1346
|
}
|
|
1394
|
-
// Lia@Changes 03-02-26 --- Add "viewOnceV2Extension" boolean to wrap message into viewOnceMessageV2Extension like "viewOnce"
|
|
1395
1347
|
else if (hasOptionalProperty(message, 'viewOnceV2Extension') && !!message.viewOnceV2Extension) {
|
|
1396
1348
|
m = { viewOnceMessageV2Extension: { message: m } };
|
|
1397
1349
|
delete message.viewOnceV2Extension;
|
|
@@ -1406,6 +1358,9 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1406
1358
|
}
|
|
1407
1359
|
};
|
|
1408
1360
|
}
|
|
1361
|
+
if (options?.messageSecret && !m.messageContextInfo?.messageSecret) {
|
|
1362
|
+
m.messageContextInfo = { ...(m.messageContextInfo ?? {}), messageSecret: options.messageSecret };
|
|
1363
|
+
}
|
|
1409
1364
|
if (shouldIncludeReportingToken(m)) {
|
|
1410
1365
|
m.messageContextInfo = m.messageContextInfo || {};
|
|
1411
1366
|
if (!m.messageContextInfo.messageSecret) {
|
|
@@ -1414,9 +1369,8 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1414
1369
|
}
|
|
1415
1370
|
return WAProto.Message.create(m);
|
|
1416
1371
|
};
|
|
1372
|
+
|
|
1417
1373
|
export const generateWAMessageFromContent = (jid, message, options) => {
|
|
1418
|
-
// set timestamp to now
|
|
1419
|
-
// if not specified
|
|
1420
1374
|
if (!options.timestamp) {
|
|
1421
1375
|
options.timestamp = new Date();
|
|
1422
1376
|
}
|
|
@@ -1428,11 +1382,10 @@ export const generateWAMessageFromContent = (jid, message, options) => {
|
|
|
1428
1382
|
const { quoted, userJid } = options;
|
|
1429
1383
|
if (quoted) {
|
|
1430
1384
|
const participant = quoted.key.fromMe
|
|
1431
|
-
? userJid
|
|
1385
|
+
? userJid
|
|
1432
1386
|
: quoted.participant || quoted.key.participant || quoted.key.remoteJid;
|
|
1433
1387
|
let quotedMsg = normalizeMessageContent(quoted.message);
|
|
1434
1388
|
const msgType = getContentType(quotedMsg);
|
|
1435
|
-
// strip any redundant properties
|
|
1436
1389
|
quotedMsg = proto.Message.create({ [msgType]: quotedMsg[msgType] });
|
|
1437
1390
|
const quotedContent = quotedMsg[msgType];
|
|
1438
1391
|
if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
|
|
@@ -1442,33 +1395,22 @@ export const generateWAMessageFromContent = (jid, message, options) => {
|
|
|
1442
1395
|
contextInfo.participant = jidNormalizedUser(participant);
|
|
1443
1396
|
contextInfo.stanzaId = quoted.key.id;
|
|
1444
1397
|
contextInfo.quotedMessage = quotedMsg;
|
|
1445
|
-
// if a participant is quoted, then it must be a group
|
|
1446
|
-
// hence, remoteJid of group must also be entered
|
|
1447
1398
|
if (!isNewsletter && jid !== quoted.key.remoteJid) {
|
|
1448
1399
|
contextInfo.remoteJid = quoted.key.remoteJid;
|
|
1449
1400
|
}
|
|
1450
1401
|
if (contextInfo && innerMessage[key]) {
|
|
1451
|
-
/* @ts-ignore */
|
|
1452
1402
|
innerMessage[key].contextInfo = contextInfo;
|
|
1453
1403
|
}
|
|
1454
1404
|
}
|
|
1455
|
-
if (
|
|
1456
|
-
// if we want to send a disappearing message
|
|
1457
|
-
!!options?.ephemeralExpiration &&
|
|
1458
|
-
// and it's not a protocol message -- delete, toggle disappear message
|
|
1405
|
+
if (!!options?.ephemeralExpiration &&
|
|
1459
1406
|
key !== 'protocolMessage' &&
|
|
1460
|
-
// already not converted to disappearing message
|
|
1461
1407
|
key !== 'ephemeralMessage' &&
|
|
1462
|
-
// newsletters don't support ephemeral messages
|
|
1463
1408
|
!isNewsletter) {
|
|
1464
|
-
/* @ts-ignore */
|
|
1465
1409
|
innerMessage[key].contextInfo = {
|
|
1466
1410
|
...(innerMessage[key].contextInfo || {}),
|
|
1467
1411
|
expiration: options.ephemeralExpiration || WA_DEFAULT_EPHEMERAL
|
|
1468
|
-
//ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts?.toString()
|
|
1469
1412
|
};
|
|
1470
1413
|
}
|
|
1471
|
-
// Lia@Changes 30-01-26 --- Add deviceListMetadata inside messageContextInfo for private chat
|
|
1472
1414
|
if (messageContextInfo?.messageSecret && (isPnUser(jid) || isLidUser(jid))) {
|
|
1473
1415
|
messageContextInfo.deviceListMetadata = {
|
|
1474
1416
|
recipientKeyHash: randomBytes(10),
|
|
@@ -1486,21 +1428,20 @@ export const generateWAMessageFromContent = (jid, message, options) => {
|
|
|
1486
1428
|
message: message,
|
|
1487
1429
|
messageTimestamp: timestamp,
|
|
1488
1430
|
messageStubParameters: [],
|
|
1489
|
-
participant: isJidGroup(jid) || isJidStatusBroadcast(jid) ? userJid : undefined,
|
|
1431
|
+
participant: isJidGroup(jid) || isJidStatusBroadcast(jid) ? userJid : undefined,
|
|
1490
1432
|
status: WAMessageStatus.PENDING
|
|
1491
1433
|
};
|
|
1492
1434
|
return WAProto.WebMessageInfo.fromObject(messageJSON);
|
|
1493
1435
|
};
|
|
1436
|
+
|
|
1494
1437
|
export const generateWAMessage = async (jid, content, options) => {
|
|
1495
|
-
// ensure msg ID is with every log
|
|
1496
1438
|
options.logger = options?.logger?.child({ msgId: options.messageId });
|
|
1497
|
-
// Pass jid in the options to generateWAMessageContent
|
|
1498
1439
|
if (jid) {
|
|
1499
1440
|
options.jid = jid;
|
|
1500
1441
|
}
|
|
1501
1442
|
return generateWAMessageFromContent(jid, await generateWAMessageContent(content, options), options);
|
|
1502
1443
|
};
|
|
1503
|
-
|
|
1444
|
+
|
|
1504
1445
|
export const getContentType = (content) => {
|
|
1505
1446
|
if (content) {
|
|
1506
1447
|
const keys = Object.keys(content);
|
|
@@ -1508,17 +1449,11 @@ export const getContentType = (content) => {
|
|
|
1508
1449
|
return key;
|
|
1509
1450
|
}
|
|
1510
1451
|
};
|
|
1511
|
-
|
|
1512
|
-
* Normalizes ephemeral, view once messages to regular message content
|
|
1513
|
-
* Eg. image messages in ephemeral messages, in view once messages etc.
|
|
1514
|
-
* @param content
|
|
1515
|
-
* @returns
|
|
1516
|
-
*/
|
|
1452
|
+
|
|
1517
1453
|
export const normalizeMessageContent = (content) => {
|
|
1518
1454
|
if (!content) {
|
|
1519
1455
|
return undefined;
|
|
1520
1456
|
}
|
|
1521
|
-
// set max iterations to prevent an infinite loop
|
|
1522
1457
|
for (let i = 0; i < 5; i++) {
|
|
1523
1458
|
const inner = getFutureProofMessage(content);
|
|
1524
1459
|
if (!inner) {
|
|
@@ -1527,7 +1462,6 @@ export const normalizeMessageContent = (content) => {
|
|
|
1527
1462
|
content = inner.message;
|
|
1528
1463
|
}
|
|
1529
1464
|
return content;
|
|
1530
|
-
// Lia@Changes 03-02-26 --- Add all futureProofMessage into getFutureProofMessage()
|
|
1531
1465
|
function getFutureProofMessage(message) {
|
|
1532
1466
|
return (message?.associatedChildMessage ||
|
|
1533
1467
|
message?.botForwardedMessage ||
|
|
@@ -1558,10 +1492,7 @@ export const normalizeMessageContent = (content) => {
|
|
|
1558
1492
|
message?.viewOnceMessageV2Extension);
|
|
1559
1493
|
}
|
|
1560
1494
|
};
|
|
1561
|
-
|
|
1562
|
-
* Extract the true message content from a message
|
|
1563
|
-
* Eg. extracts the inner message from a disappearing message/view once message
|
|
1564
|
-
*/
|
|
1495
|
+
|
|
1565
1496
|
export const extractMessageContent = (content) => {
|
|
1566
1497
|
const extractFromTemplateMessage = (msg) => {
|
|
1567
1498
|
if (msg.imageMessage) {
|
|
@@ -1597,9 +1528,7 @@ export const extractMessageContent = (content) => {
|
|
|
1597
1528
|
}
|
|
1598
1529
|
return content;
|
|
1599
1530
|
};
|
|
1600
|
-
|
|
1601
|
-
* Returns the device predicted by message ID
|
|
1602
|
-
*/
|
|
1531
|
+
|
|
1603
1532
|
export const getDevice = (id) => /^3A.{18}$/.test(id)
|
|
1604
1533
|
? 'ios'
|
|
1605
1534
|
: /^3E.{20}$/.test(id)
|
|
@@ -1609,7 +1538,7 @@ export const getDevice = (id) => /^3A.{18}$/.test(id)
|
|
|
1609
1538
|
: /^(3F|.{18}$)/.test(id)
|
|
1610
1539
|
? 'desktop'
|
|
1611
1540
|
: 'unknown';
|
|
1612
|
-
|
|
1541
|
+
|
|
1613
1542
|
export const updateMessageWithReceipt = (msg, receipt) => {
|
|
1614
1543
|
msg.userReceipt = msg.userReceipt || [];
|
|
1615
1544
|
const recp = msg.userReceipt.find(m => m.userJid === receipt.userJid);
|
|
@@ -1620,7 +1549,7 @@ export const updateMessageWithReceipt = (msg, receipt) => {
|
|
|
1620
1549
|
msg.userReceipt.push(receipt);
|
|
1621
1550
|
}
|
|
1622
1551
|
};
|
|
1623
|
-
|
|
1552
|
+
|
|
1624
1553
|
export const updateMessageWithReaction = (msg, reaction) => {
|
|
1625
1554
|
const authorID = getKeyAuthor(reaction.key);
|
|
1626
1555
|
const reactions = (msg.reactions || []).filter(r => getKeyAuthor(r.key) !== authorID);
|
|
@@ -1628,7 +1557,7 @@ export const updateMessageWithReaction = (msg, reaction) => {
|
|
|
1628
1557
|
reactions.push(reaction);
|
|
1629
1558
|
msg.reactions = reactions;
|
|
1630
1559
|
};
|
|
1631
|
-
|
|
1560
|
+
|
|
1632
1561
|
export const updateMessageWithPollUpdate = (msg, update) => {
|
|
1633
1562
|
const authorID = getKeyAuthor(update.pollUpdateMessageKey);
|
|
1634
1563
|
const reactions = (msg.pollUpdates || []).filter(r => getKeyAuthor(r.pollUpdateMessageKey) !== authorID);
|
|
@@ -1637,19 +1566,14 @@ export const updateMessageWithPollUpdate = (msg, update) => {
|
|
|
1637
1566
|
}
|
|
1638
1567
|
msg.pollUpdates = reactions;
|
|
1639
1568
|
};
|
|
1640
|
-
|
|
1569
|
+
|
|
1641
1570
|
export const updateMessageWithEventResponse = (msg, update) => {
|
|
1642
1571
|
const authorID = getKeyAuthor(update.eventResponseMessageKey);
|
|
1643
1572
|
const responses = (msg.eventResponses || []).filter(r => getKeyAuthor(r.eventResponseMessageKey) !== authorID);
|
|
1644
1573
|
responses.push(update);
|
|
1645
1574
|
msg.eventResponses = responses;
|
|
1646
1575
|
};
|
|
1647
|
-
|
|
1648
|
-
* Aggregates all poll updates in a poll.
|
|
1649
|
-
* @param msg the poll creation message
|
|
1650
|
-
* @param meId your jid
|
|
1651
|
-
* @returns A list of options & their voters
|
|
1652
|
-
*/
|
|
1576
|
+
|
|
1653
1577
|
export function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
|
|
1654
1578
|
const opts = message?.pollCreationMessage?.options ||
|
|
1655
1579
|
message?.pollCreationMessageV2?.options ||
|
|
@@ -1683,12 +1607,7 @@ export function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
|
|
|
1683
1607
|
}
|
|
1684
1608
|
return Object.values(voteHashMap);
|
|
1685
1609
|
}
|
|
1686
|
-
|
|
1687
|
-
* Aggregates all event responses in an event message.
|
|
1688
|
-
* @param msg the event creation message
|
|
1689
|
-
* @param meId your jid
|
|
1690
|
-
* @returns A list of response types & their responders
|
|
1691
|
-
*/
|
|
1610
|
+
|
|
1692
1611
|
export function getAggregateResponsesInEventMessage({ eventResponses }, meId) {
|
|
1693
1612
|
const responseTypes = ['GOING', 'NOT_GOING', 'MAYBE'];
|
|
1694
1613
|
const responseMap = {};
|
|
@@ -1706,7 +1625,7 @@ export function getAggregateResponsesInEventMessage({ eventResponses }, meId) {
|
|
|
1706
1625
|
}
|
|
1707
1626
|
return Object.values(responseMap);
|
|
1708
1627
|
}
|
|
1709
|
-
|
|
1628
|
+
|
|
1710
1629
|
export const aggregateMessageKeysNotFromMe = (keys) => {
|
|
1711
1630
|
const keyMap = {};
|
|
1712
1631
|
for (const { remoteJid, id, participant, fromMe } of keys) {
|
|
@@ -1724,17 +1643,15 @@ export const aggregateMessageKeysNotFromMe = (keys) => {
|
|
|
1724
1643
|
}
|
|
1725
1644
|
return Object.values(keyMap);
|
|
1726
1645
|
};
|
|
1646
|
+
|
|
1727
1647
|
const REUPLOAD_REQUIRED_STATUS = [410, 404];
|
|
1728
|
-
|
|
1729
|
-
* Downloads the given message. Throws an error if it's not a media message
|
|
1730
|
-
*/
|
|
1648
|
+
|
|
1731
1649
|
export const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
1732
1650
|
const result = await downloadMsg().catch(async (error) => {
|
|
1733
1651
|
if (ctx &&
|
|
1734
|
-
typeof error?.status === 'number' &&
|
|
1652
|
+
typeof error?.status === 'number' &&
|
|
1735
1653
|
REUPLOAD_REQUIRED_STATUS.includes(error.status)) {
|
|
1736
1654
|
ctx.logger.info({ key: message.key }, 'sending reupload media request...');
|
|
1737
|
-
// request reupload
|
|
1738
1655
|
message = await ctx.reuploadRequest(message);
|
|
1739
1656
|
const result = await downloadMsg();
|
|
1740
1657
|
return result;
|
|
@@ -1775,7 +1692,7 @@ export const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
|
1775
1692
|
return stream;
|
|
1776
1693
|
}
|
|
1777
1694
|
};
|
|
1778
|
-
|
|
1695
|
+
|
|
1779
1696
|
export const assertMediaContent = (content) => {
|
|
1780
1697
|
content = extractMessageContent(content);
|
|
1781
1698
|
const mediaContent = content?.documentMessage ||
|
|
@@ -1788,12 +1705,8 @@ export const assertMediaContent = (content) => {
|
|
|
1788
1705
|
}
|
|
1789
1706
|
return mediaContent;
|
|
1790
1707
|
};
|
|
1791
|
-
|
|
1792
|
-
* Checks if a WebP buffer is animated by looking for VP8X chunk with animation flag
|
|
1793
|
-
* or ANIM/ANMF chunks
|
|
1794
|
-
*/
|
|
1708
|
+
|
|
1795
1709
|
const isAnimatedWebP = (buffer) => {
|
|
1796
|
-
// WebP must start with RIFF....WEBP
|
|
1797
1710
|
if (buffer.length < 12 ||
|
|
1798
1711
|
buffer[0] !== 0x52 ||
|
|
1799
1712
|
buffer[1] !== 0x49 ||
|
|
@@ -1805,38 +1718,27 @@ const isAnimatedWebP = (buffer) => {
|
|
|
1805
1718
|
buffer[11] !== 0x50) {
|
|
1806
1719
|
return false;
|
|
1807
1720
|
}
|
|
1808
|
-
;
|
|
1809
|
-
// Parse chunks starting after RIFF header (12 bytes)
|
|
1810
1721
|
let offset = 12;
|
|
1811
1722
|
while (offset < buffer.length - 8) {
|
|
1812
1723
|
const chunkFourCC = buffer.toString('ascii', offset, offset + 4);
|
|
1813
1724
|
const chunkSize = buffer.readUInt32LE(offset + 4);
|
|
1814
1725
|
if (chunkFourCC === 'VP8X') {
|
|
1815
|
-
// VP8X extended header, check animation flag (bit 1 at offset+8)
|
|
1816
1726
|
const flagsOffset = offset + 8;
|
|
1817
1727
|
if (flagsOffset < buffer.length) {
|
|
1818
1728
|
const flags = buffer[flagsOffset];
|
|
1819
1729
|
if (flags & 0x02) {
|
|
1820
1730
|
return true;
|
|
1821
1731
|
}
|
|
1822
|
-
;
|
|
1823
1732
|
}
|
|
1824
|
-
;
|
|
1825
1733
|
}
|
|
1826
1734
|
else if (chunkFourCC === 'ANIM' || chunkFourCC === 'ANMF') {
|
|
1827
|
-
// ANIM or ANMF chunks indicate animation
|
|
1828
1735
|
return true;
|
|
1829
1736
|
}
|
|
1830
|
-
;
|
|
1831
|
-
// Move to next chunk (chunk size + 8 bytes header, padded to even)
|
|
1832
1737
|
offset += 8 + chunkSize + (chunkSize % 2);
|
|
1833
1738
|
}
|
|
1834
|
-
;
|
|
1835
1739
|
return false;
|
|
1836
1740
|
};
|
|
1837
|
-
|
|
1838
|
-
* Checks if a buffer is a WebP file
|
|
1839
|
-
*/
|
|
1741
|
+
|
|
1840
1742
|
const isWebPBuffer = (buffer) => {
|
|
1841
1743
|
return (buffer.length >= 12 &&
|
|
1842
1744
|
buffer[0] === 0x52 &&
|
|
@@ -1848,16 +1750,10 @@ const isWebPBuffer = (buffer) => {
|
|
|
1848
1750
|
buffer[10] === 0x42 &&
|
|
1849
1751
|
buffer[11] === 0x50);
|
|
1850
1752
|
};
|
|
1851
|
-
|
|
1852
|
-
* Lia@Changes 30-01-26
|
|
1853
|
-
* ---
|
|
1854
|
-
* Determines whether a message should include a Biz Binary Node.
|
|
1855
|
-
* A Biz Binary Node is added only for interactive messages
|
|
1856
|
-
* such as buttons or other supported interactive types.
|
|
1857
|
-
*/
|
|
1753
|
+
|
|
1858
1754
|
export const shouldIncludeBizBinaryNode = (message) => !!(message.buttonsMessage ||
|
|
1859
1755
|
message.listMessage ||
|
|
1860
1756
|
message.templateMessage ||
|
|
1861
1757
|
(message.interactiveMessage &&
|
|
1862
1758
|
message.interactiveMessage.nativeFlowMessage));
|
|
1863
|
-
//# sourceMappingURL=messages.js.map
|
|
1759
|
+
//# sourceMappingURL=messages.js.map
|