keithbaileys 1.0.2 → 1.0.6

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.
@@ -220,6 +220,91 @@ const prepareWAMessageMedia = async (message, options) => {
220
220
  return obj;
221
221
  };
222
222
  exports.prepareWAMessageMedia = prepareWAMessageMedia;
223
+
224
+
225
+
226
+
227
+
228
+ const prepareAlbumMessageContent = async (jid, albums, options) => {
229
+ if (!Array.isArray(albums)) {
230
+ throw new Error("albums must be an array containing media objects.");
231
+ }
232
+
233
+ if (albums.length === 0) {
234
+ throw new Error("albums cannot be empty. At least one media item is required.");
235
+ }
236
+
237
+ const validCount = albums.filter(m => ('image' in m) || ('video' in m)).length;
238
+
239
+ if (validCount === 0) {
240
+ throw new Error("albums contains no valid media. Use 'image' or 'video' keys.");
241
+ }
242
+
243
+ let mediaHandle;
244
+ let mediaMsg;
245
+ const message = [];
246
+
247
+ const albumMsg = generateWAMessageFromContent(jid, {
248
+ albumMessage: {
249
+ expectedImageCount: albums.filter(item => 'image' in item).length,
250
+ expectedVideoCount: albums.filter(item => 'video' in item).length
251
+ }
252
+ }, options);
253
+
254
+ await options.sock.relayMessage(jid, albumMsg.message, {
255
+ messageId: albumMsg.key.id
256
+ });
257
+
258
+ for (const media of albums) {
259
+ let content = {};
260
+ if ('image' in media) {
261
+ content = { image: media.image };
262
+ } else if ('video' in media) {
263
+ content = { video: media.video };
264
+ } else {
265
+ continue;
266
+ }
267
+
268
+ mediaMsg = await generateWAMessage(
269
+ jid,
270
+ {
271
+ ...content,
272
+ ...media
273
+ },
274
+ {
275
+ userJid: options.userJid,
276
+ upload: async (encFilePath, opts) => {
277
+ const up = await options.sock.waUploadToServer(
278
+ encFilePath,
279
+ { ...opts, newsletter: (0, WABinary_1.isJidNewsletter)(jid) }
280
+ );
281
+ mediaHandle = up.handle;
282
+ return up;
283
+ },
284
+ ...options
285
+ }
286
+ );
287
+
288
+ if (mediaMsg) {
289
+ mediaMsg.message.messageContextInfo = {
290
+ messageSecret: (0, crypto_1.randomBytes)(32),
291
+ messageAssociation: {
292
+ associationType: WAProto_1.proto.MessageAssociation.AssociationType.MEDIA_ALBUM,
293
+ parentMessageKey: albumMsg.key
294
+ }
295
+ };
296
+ }
297
+
298
+ message.push(mediaMsg);
299
+ }
300
+
301
+ return message;
302
+ };
303
+
304
+
305
+
306
+
307
+
223
308
  const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
224
309
  ephemeralExpiration = ephemeralExpiration || 0;
225
310
  const content = {
@@ -366,6 +451,41 @@ const generateWAMessageContent = async (message, options) => {
366
451
  m.pinInChatMessage.senderTimestampMs = Date.now();
367
452
  m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0;
368
453
  }
454
+ else if ('keep' in message) {
455
+ m.keepInChatMessage = {};
456
+ m.keepInChatMessage.key = message.keep.key;
457
+ m.keepInChatMessage.keepType = message.keep?.type || 1;
458
+ m.keepInChatMessage.timestampMs = message.keep?.time || Date.now();
459
+ }
460
+ else if ('call' in message) {
461
+ m.scheduledCallCreationMessage = {};
462
+ m.scheduledCallCreationMessage.scheduledTimestampMs = message.call?.time || Date.now();
463
+ m.scheduledCallCreationMessage.callType = message.call?.type || 1;
464
+ m.scheduledCallCreationMessage.title = message.call?.name || "Call Creation";
465
+ }
466
+ else if ('event' in message) {
467
+ m.eventMessage = WAProto_1.proto.Message.EventMessage.fromObject(message.event);
468
+ if (!message.event.startTime) {
469
+ m.eventMessage.startTime = (0, generics_1.unixTimestampSeconds)() + 86400;
470
+ }
471
+ if (options.getCallLink && message.event.call) {
472
+ const link = await options.getCallLink(message.event.call, m.eventMessage.startTime);
473
+ m.eventMessage.joinLink = link;
474
+ }
475
+ }
476
+ else if ('pollResult' in message) {
477
+ if (!Array.isArray(message.pollResult.values)) {
478
+ throw new boom_1.Boom("Invalid pollResult values", { statusCode: 400 });
479
+ }
480
+ const pollResultSnapshotMessage = {
481
+ name: message.pollResult.name,
482
+ pollVotes: message.pollResult.values.map(([optionName, optionVoteCount]) => ({
483
+ optionName,
484
+ optionVoteCount,
485
+ })),
486
+ };
487
+ m.pollResultSnapshotMessage = pollResultSnapshotMessage;
488
+ }
369
489
  else if ('buttonReply' in message) {
370
490
  switch (message.type) {
371
491
  case 'template':
@@ -398,6 +518,15 @@ const generateWAMessageContent = async (message, options) => {
398
518
  }
399
519
  });
400
520
  }
521
+ else if ('album' in message && Array.isArray(message.album)) {
522
+ // For album messages
523
+ m.albumMessage = {
524
+ expectedImageCount: message.album.filter(item => 'image' in item).length,
525
+ expectedVideoCount: message.album.filter(item => 'video' in item).length
526
+ };
527
+ }
528
+
529
+
401
530
  else if ('listReply' in message) {
402
531
  m.listResponseMessage = { ...message.listReply };
403
532
  }
@@ -436,6 +565,218 @@ const generateWAMessageContent = async (message, options) => {
436
565
  }
437
566
  }
438
567
  }
568
+
569
+
570
+ else if ('adminInvite' in message) {
571
+ m.newsletterAdminInviteMessage = {};
572
+ m.newsletterAdminInviteMessage.newsletterJid = message.adminInvite.jid;
573
+ m.newsletterAdminInviteMessage.newsletterName = message.adminInvite.name;
574
+ m.newsletterAdminInviteMessage.caption = message.adminInvite.caption;
575
+ m.newsletterAdminInviteMessage.inviteExpiration = message.adminInvite.expiration;
576
+ m.newsletterAdminInviteMessage.contextInfo = message.contextInfo;
577
+
578
+ if (options.getProfilePicUrl) {
579
+ const pfpUrl = await options.getProfilePicUrl(message.adminInvite.jid);
580
+ if (pfpUrl) {
581
+ const resp = await axios_1.default.get(pfpUrl, { responseType: 'arraybuffer' });
582
+ if (resp.status === 200) {
583
+ m.newsletterAdminInviteMessage.jpegThumbnail = resp.data;
584
+ }
585
+ }
586
+ }
587
+ }
588
+ else if ('payment' in message) {
589
+ const requestPaymentMessage = {
590
+ amount: {
591
+ currencyCode: message.payment?.currency || "IDR",
592
+ offset: message.payment?.offset || 0,
593
+ value: message.payment?.amount || 999999999,
594
+ },
595
+ expiryTimestamp: message.payment?.expiry || 0,
596
+ amount1000: message.payment?.amount || 999999999 * 1000,
597
+ currencyCodeIso4217: message.payment?.currency || "IDR",
598
+ requestFrom: message.payment?.from || "0@s.whatsapp.net",
599
+ noteMessage: {
600
+ extendedTextMessage: {
601
+ text: message.payment?.note || "Notes",
602
+ },
603
+ },
604
+ background: {
605
+ placeholderArgb: message.payment?.image?.placeholderArgb || 4278190080,
606
+ textArgb: message.payment?.image?.textArgb || 4294967295,
607
+ subtextArgb: message.payment?.image?.subtextArgb || 4294967295,
608
+ type: 1,
609
+ },
610
+ };
611
+ m.requestPaymentMessage = requestPaymentMessage;
612
+ }
613
+ else if ('paymentInvite' in message) {
614
+ m.messageContextInfo = {};
615
+ m.paymentInviteMessage = {};
616
+ m.paymentInviteMessage.expiryTimestamp = message.paymentInvite?.expiry || 0;
617
+ m.paymentInviteMessage.serviceType = message.paymentInvite?.type || 2;
618
+ }
619
+
620
+
621
+ else if ('stickerPack' in message) {
622
+ const { stickers, cover, name, publisher, packId, description } = message.stickerPack;
623
+ const { zip } = require("fflate");
624
+
625
+ const stickerData = {};
626
+ const stickerPromises = stickers.map(async (s, i) => {
627
+ const { stream } = await (0, messages_media_1.getStream)(s.sticker);
628
+ const buffer = await (0, messages_media_1.toBuffer)(stream);
629
+ const hash = (0, crypto_2.sha256)(buffer).toString("base64url");
630
+ const fileName = `${i.toString().padStart(2, "0")}_${hash}.webp`;
631
+
632
+ stickerData[fileName] = [new Uint8Array(buffer), { level: 0 }];
633
+
634
+ return {
635
+ fileName,
636
+ mimetype: "image/webp",
637
+ isAnimated: s.isAnimated || false,
638
+ isLottie: s.isLottie || false,
639
+ emojis: s.emojis || [],
640
+ accessibilityLabel: s.accessibilityLabel || "",
641
+ };
642
+ });
643
+
644
+ const stickerMetadata = await Promise.all(stickerPromises);
645
+
646
+ const zipBuffer = await new Promise((resolve, reject) => {
647
+ zip(stickerData, (err, data) => {
648
+ if (err) {
649
+ reject(err);
650
+ } else {
651
+ resolve(Buffer.from(data));
652
+ }
653
+ });
654
+ });
655
+
656
+ const coverBuffer = await (0, messages_media_1.toBuffer)((await (0, messages_media_1.getStream)(cover)).stream);
657
+
658
+ const [stickerPackUpload, coverUpload] = await Promise.all([
659
+ (0, messages_media_1.encryptedStream)(zipBuffer, "sticker-pack", {
660
+ logger: options.logger,
661
+ opts: options.options,
662
+ }),
663
+ (0, exports.prepareWAMessageMedia)({ image: coverBuffer }, { ...options, mediaTypeOverride: "image" })
664
+ ]);
665
+
666
+ const stickerPackUploadResult = await options.upload(stickerPackUpload.encFilePath, {
667
+ fileEncSha256B64: stickerPackUpload.fileEncSha256.toString("base64"),
668
+ mediaType: "sticker-pack",
669
+ timeoutMs: options.mediaUploadTimeoutMs,
670
+ });
671
+
672
+ const coverImage = coverUpload.imageMessage;
673
+ const imageDataHash = (0, crypto_2.sha256)(coverBuffer).toString("base64");
674
+ const stickerPackId = packId || (0, generics_1.generateMessageIDV2)();
675
+
676
+ m.stickerPackMessage = {
677
+ name,
678
+ publisher,
679
+ stickerPackId,
680
+ packDescription: description,
681
+ stickerPackOrigin: WAProto_1.proto.Message.StickerPackMessage.StickerPackOrigin.THIRD_PARTY,
682
+ stickerPackSize: stickerPackUpload.fileLength,
683
+ stickers: stickerMetadata,
684
+ fileSha256: stickerPackUpload.fileSha256,
685
+ fileEncSha256: stickerPackUpload.fileEncSha256,
686
+ mediaKey: stickerPackUpload.mediaKey,
687
+ directPath: stickerPackUploadResult.directPath,
688
+ fileLength: stickerPackUpload.fileLength,
689
+ mediaKeyTimestamp: (0, generics_1.unixTimestampSeconds)(),
690
+ trayIconFileName: `${stickerPackId}.png`,
691
+ imageDataHash,
692
+ thumbnailDirectPath: coverImage.directPath,
693
+ thumbnailFileSha256: coverImage.fileSha256,
694
+ thumbnailFileEncSha256: coverImage.fileEncSha256,
695
+ thumbnailHeight: coverImage.height,
696
+ thumbnailWidth: coverImage.width,
697
+ };
698
+ }
699
+ /*else if ('stickerPack' in message) {
700
+ const { stickers, cover, name, publisher, packId, description } = message.stickerPack;
701
+ const { zip } = require("fflate");
702
+
703
+ const stickerData = {};
704
+ const stickerPromises = stickers.map(async (s, i) => {
705
+ const { stream } = await (0, messages_media_1.getStream)(s.sticker);
706
+ const buffer = await (0, messages_media_1.toBuffer)(stream);
707
+ const hash = (0, crypto_2.sha256)(buffer).toString("base64url");
708
+ const fileName = `${i.toString().padStart(2, "0")}_${hash}.webp`;
709
+
710
+ stickerData[fileName] = [new Uint8Array(buffer), { level: 0 }];
711
+
712
+ return {
713
+ fileName,
714
+ mimetype: "image/webp",
715
+ isAnimated: s.isAnimated || false,
716
+ isLottie: s.isLottie || false,
717
+ emojis: s.emojis || [],
718
+ accessibilityLabel: s.accessibilityLabel || "",
719
+ };
720
+ });
721
+
722
+ const stickerMetadata = await Promise.all(stickerPromises);
723
+
724
+ const zipBuffer = await new Promise((resolve, reject) => {
725
+ zip(stickerData, (err, data) => {
726
+ if (err) {
727
+ reject(err);
728
+ } else {
729
+ resolve(Buffer.from(data));
730
+ }
731
+ });
732
+ });
733
+
734
+ const coverBuffer = await (0, messages_media_1.toBuffer)((await (0, messages_media_1.getStream)(cover)).stream);
735
+
736
+ const [stickerPackUpload, coverUpload] = await Promise.all([
737
+ (0, messages_media_1.encryptedStream)(zipBuffer, "sticker-pack", {
738
+ logger: options.logger,
739
+ opts: options.options,
740
+ }),
741
+ (0, exports.prepareWAMessageMedia)({ image: coverBuffer }, { ...options, mediaTypeOverride: "image" })
742
+ ]);
743
+
744
+ const stickerPackUploadResult = await options.upload(stickerPackUpload.encFilePath, {
745
+ fileEncSha256B64: stickerPackUpload.fileEncSha256.toString("base64"),
746
+ mediaType: "sticker-pack",
747
+ timeoutMs: options.mediaUploadTimeoutMs,
748
+ });
749
+
750
+ const coverImage = coverUpload.imageMessage;
751
+ const imageDataHash = (0, crypto_2.sha256)(coverBuffer).toString("base64");
752
+ const stickerPackId = packId || (0, generics_1.generateMessageIDV2)();
753
+
754
+ m.stickerPackMessage = {
755
+ name,
756
+ publisher,
757
+ stickerPackId,
758
+ packDescription: description,
759
+ stickerPackOrigin: WAProto_1.proto.Message.StickerPackMessage.StickerPackOrigin.THIRD_PARTY,
760
+ stickerPackSize: stickerPackUpload.fileLength,
761
+ stickers: stickerMetadata,
762
+ fileSha256: stickerPackUpload.fileSha256,
763
+ fileEncSha256: stickerPackUpload.fileEncSha256,
764
+ mediaKey: stickerPackUpload.mediaKey,
765
+ directPath: stickerPackUploadResult.directPath,
766
+ fileLength: stickerPackUpload.fileLength,
767
+ mediaKeyTimestamp: (0, generics_1.unixTimestampSeconds)(),
768
+ trayIconFileName: `${stickerPackId}.png`,
769
+ imageDataHash,
770
+ thumbnailDirectPath: coverImage.directPath,
771
+ thumbnailFileSha256: coverImage.fileSha256,
772
+ thumbnailFileEncSha256: coverImage.fileEncSha256,
773
+ thumbnailHeight: coverImage.height,
774
+ thumbnailWidth: coverImage.width,
775
+ };
776
+ }*/
777
+
778
+
779
+
439
780
  else if ('sharePhoneNumber' in message) {
440
781
  m.protocolMessage = {
441
782
  type: WAProto_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
@@ -573,15 +914,22 @@ const normalizeMessageContent = (content) => {
573
914
  content = inner.message;
574
915
  }
575
916
  return content;
576
- function getFutureProofMessage(message) {
577
- return ((message === null || message === void 0 ? void 0 : message.ephemeralMessage) ||
578
- (message === null || message === void 0 ? void 0 : message.viewOnceMessage) ||
579
- (message === null || message === void 0 ? void 0 : message.documentWithCaptionMessage) ||
580
- (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2) ||
581
- (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension) ||
582
- (message === null || message === void 0 ? void 0 : message.editedMessage));
583
- }
584
- };
917
+ }
918
+
919
+ function getFutureProofMessage(message) {
920
+ return ((message === null || message === void 0 ? void 0 : message.ephemeralMessage) ||
921
+ (message === null || message === void 0 ? void 0 : message.viewOnceMessage) ||
922
+ (message === null || message === void 0 ? void 0 : message.documentWithCaptionMessage) ||
923
+ (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2) ||
924
+ (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension) ||
925
+ (message === null || message === void 0 ? void 0 : message.editedMessage) ||
926
+ (message === null || message === void 0 ? void 0 : message.statusMentionMessage) ||
927
+ (message === null || message === void 0 ? void 0 : message.groupMentionedMessage) ||
928
+ (message === null || message === void 0 ? void 0 : message.groupStatusMentionMessage) ||
929
+ (message === null || message === void 0 ? void 0 : message.pollCreationMessageV4) ||
930
+ (message === null || message === void 0 ? void 0 : message.associatedChildMessage) ||
931
+ (message === null || message === void 0 ? void 0 : message.pollCreationOptionImageMessage));
932
+ }
585
933
  exports.normalizeMessageContent = normalizeMessageContent;
586
934
  /**
587
935
  * Extract the true message content from a message
@@ -727,6 +1075,9 @@ const aggregateMessageKeysNotFromMe = (keys) => {
727
1075
  }
728
1076
  return Object.values(keyMap);
729
1077
  };
1078
+
1079
+ exports.prepareAlbumMessageContent = prepareAlbumMessageContent;
1080
+
730
1081
  exports.aggregateMessageKeysNotFromMe = aggregateMessageKeysNotFromMe;
731
1082
  const REUPLOAD_REQUIRED_STATUS = [410, 404];
732
1083
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keithbaileys",
3
- "version": "1.0.2",
3
+ "version": "1.0.6",
4
4
  "description": "A lightweight, full-featured WhatsApp Web API library for Node.js",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -21,6 +21,7 @@
21
21
  "@hapi/boom": "^9.1.3",
22
22
  "async-mutex": "^0.5.0",
23
23
  "axios": "^1.6.0",
24
+ "fflate": "^0.8.2",
24
25
  "libsignal": "github:WhiskeySockets/libsignal-node",
25
26
  "lodash": "^4.17.21",
26
27
  "music-metadata": "^7.12.3",