keithbaileys 1.0.6 → 1.0.8

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.
@@ -1,3 +1,4 @@
1
+
1
2
  "use strict";
2
3
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -200,7 +201,7 @@ const makeMessagesSocket = (config) => {
200
201
  }
201
202
  return didFetchNewSession;
202
203
  };
203
-
204
+ //
204
205
  const sendPeerDataOperationMessage = async (pdoMessage) => {
205
206
  var _a;
206
207
  if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
@@ -597,6 +598,114 @@ const makeMessagesSocket = (config) => {
597
598
  const giftedStatus = new GiftedStatus(Utils_1, waUploadToServer, relayMessage, config, sock);
598
599
 
599
600
  const waitForMsgMediaUpdate = (0, Utils_1.bindWaitForEvent)(ev, 'messages.media-update');
601
+ // ============ RICH MESSAGE METHODS ============
602
+ /**
603
+ * Send a table as a rich (AI-forwarded-style) message.
604
+ * @param {string} jid
605
+ * @param {{ headers: string[], rows: string[][] } | string[][] | [string, string, string]} table
606
+ * Accepts any of:
607
+ * - { headers: string[], rows: string[][] }
608
+ * - a 2D array: [[headers...], [row1...], [row2...]]
609
+ * - legacy flat array: [title, "h1|h2", "r1c1|r1c2;;r2c1|r2c2"]
610
+ * @param {object} [quoted]
611
+ * @param {object} [options]
612
+ */
613
+ const sendTable = async (jid, table, quoted, options = {}) => {
614
+ const { message, messageId } = Utils_1.generateTableContentV2(table, quoted, options);
615
+ await relayMessage(jid, message, { messageId });
616
+ return { message, messageId };
617
+ };
618
+ /**
619
+ * Send a list as a rich message.
620
+ */
621
+ const sendList = async (jid, title, items, quoted, options = {}) => {
622
+ const { message, messageId } = Utils_1.generateListContent(title, items, quoted, options);
623
+ await relayMessage(jid, message, { messageId });
624
+ return { message, messageId };
625
+ };
626
+ /**
627
+ * Send a syntax-highlighted code block as a rich message.
628
+ * @param {string} jid
629
+ * @param {string} code
630
+ * @param {object} [quoted]
631
+ * @param {object} [options] - { language }
632
+ */
633
+ const sendCodeBlock = async (jid, code, quoted, options = {}) => {
634
+ const { message, messageId } = Utils_1.generateCodeBlockContentV2(code, quoted, options);
635
+ await relayMessage(jid, message, { messageId });
636
+ return { message, messageId };
637
+ };
638
+ /**
639
+ * Send one or more links as a rich message.
640
+ */
641
+ const sendLink = async (jid, text, links, quoted, options = {}) => {
642
+ const { message, messageId } = Utils_1.generateLinkContentV2(text, links, quoted, options);
643
+ await relayMessage(jid, message, { messageId });
644
+ return { message, messageId };
645
+ };
646
+ /**
647
+ * Send a LaTeX expression as text metadata (renders client-side).
648
+ */
649
+ const sendLatex = async (jid, quoted, options = {}) => {
650
+ const { message, messageId } = Utils_1.generateLatexContent(quoted, options);
651
+ await relayMessage(jid, message, { messageId });
652
+ return { message, messageId };
653
+ };
654
+ /**
655
+ * Uploads a raw image buffer the same way updateCoverPhoto does, for use by the
656
+ * LaTeX-image rich message senders below (waUploadToServer expects a file path
657
+ * + its sha256, not a raw buffer).
658
+ */
659
+ const uploadRawImageBuffer = async (buffer, mediaType = 'image') => {
660
+ const { fileSha256, filePath } = await Utils_1.getRawMediaUploadData(buffer, mediaType);
661
+ return waUploadToServer(filePath, {
662
+ fileEncSha256B64: fileSha256.toString('base64'),
663
+ mediaType
664
+ });
665
+ };
666
+ /**
667
+ * Send LaTeX expressions rendered to images. Requires a renderLatexToPng(expr) => { buffer, width, height }
668
+ * function to be supplied, since Baileys does not bundle a LaTeX renderer.
669
+ */
670
+ const sendLatexImage = async (jid, quoted, options = {}, renderLatexToPng) => {
671
+ if (typeof renderLatexToPng !== 'function') {
672
+ throw new boom_1.Boom('sendLatexImage requires a renderLatexToPng(expression) function to be passed in');
673
+ }
674
+ const { message, messageId } = await Utils_1.generateLatexImageContent(quoted, options, uploadRawImageBuffer, renderLatexToPng);
675
+ await relayMessage(jid, message, { messageId });
676
+ return { message, messageId };
677
+ };
678
+ /**
679
+ * Send LaTeX expressions rendered inline as images. Requires the same renderLatexToPng function as sendLatexImage.
680
+ */
681
+ const sendLatexInlineImage = async (jid, quoted, options = {}, renderLatexToPng) => {
682
+ if (typeof renderLatexToPng !== 'function') {
683
+ throw new boom_1.Boom('sendLatexInlineImage requires a renderLatexToPng(expression) function to be passed in');
684
+ }
685
+ const { message, messageId } = await Utils_1.generateLatexInlineImageContent(quoted, options, uploadRawImageBuffer, renderLatexToPng);
686
+ await relayMessage(jid, message, { messageId });
687
+ return { message, messageId };
688
+ };
689
+ /**
690
+ * Capture an outgoing/quoted rich (unified-response) message so it can later be re-sent verbatim.
691
+ */
692
+ const captureUnifiedResponse = Utils_1.captureUnifiedResponse;
693
+ /**
694
+ * Re-send a previously captured unified response message.
695
+ */
696
+ const sendUnifiedResponse = async (jid, quoted, captured) => {
697
+ const { message, messageId } = Utils_1.generateUnifiedResponseContent(quoted, captured);
698
+ await relayMessage(jid, message, { messageId });
699
+ return { message, messageId };
700
+ };
701
+ /**
702
+ * Send a rich message composed of multiple submessages (text/table/code/etc).
703
+ */
704
+ const sendRichMessage = async (jid, submessages, quoted, options = {}) => {
705
+ const { message, messageId } = Utils_1.generateRichMessageContent(submessages, quoted);
706
+ await relayMessage(jid, message, { messageId });
707
+ return { message, messageId };
708
+ };
600
709
 
601
710
  return {
602
711
  ...sock,
@@ -614,6 +723,16 @@ const makeMessagesSocket = (config) => {
614
723
  sendPeerDataOperationMessage,
615
724
  createParticipantNodes,
616
725
  getUSyncDevices,
726
+ sendTable,
727
+ sendList,
728
+ sendCodeBlock,
729
+ sendLink,
730
+ sendLatex,
731
+ sendLatexImage,
732
+ sendLatexInlineImage,
733
+ captureUnifiedResponse,
734
+ sendUnifiedResponse,
735
+ sendRichMessage,
617
736
  updateMediaMessage: async (message) => {
618
737
  const content = (0, Utils_1.assertMediaContent)(message.message);
619
738
  const mediaKey = content.mediaKey;
@@ -808,7 +927,7 @@ const makeMessagesSocket = (config) => {
808
927
 
809
928
  return msg;
810
929
  },
811
- sendMessage: async (jid, content, options = {}) => {
930
+ sendMessage: async (jid, content, options = {}) => {
812
931
  var _a, _b, _c;
813
932
  const userJid = authState.creds.me.id;
814
933
  if (typeof content === 'object' &&
@@ -11,6 +11,7 @@ const Types_1 = require("../Types");
11
11
  const Utils_1 = require("../Utils");
12
12
  const WABinary_1 = require("../WABinary");
13
13
  const Client_1 = require("./Client");
14
+ const mex_1 = require("./mex");
14
15
  /**
15
16
  * Connects to WA servers and performs:
16
17
  * - simple queries (no retry mechanism, wait for connection establishment)
@@ -579,6 +580,30 @@ const makeSocket = (config) => {
579
580
  }
580
581
  Object.assign(creds, update);
581
582
  });
583
+ /**
584
+ * Fetches your account's standing when it comes to restrictions.
585
+ * @returns Returns the state of the restrictions.
586
+ */
587
+ const fetchAccountReachoutTimelock = async () => {
588
+ var _a, _b, _c;
589
+ const queryResult = await (0, mex_1.executeWMexQuery)({}, Types_1.QueryIds.REACHOUT_TIMELOCK, Types_1.XWAPaths.xwa2_fetch_account_reachout_timelock, query, generateMessageTag);
590
+ const result = {
591
+ isActive: !!(queryResult === null || queryResult === void 0 ? void 0 : queryResult.is_active),
592
+ timeEnforcementEnds: (queryResult === null || queryResult === void 0 ? void 0 : queryResult.time_enforcement_ends) && (queryResult === null || queryResult === void 0 ? void 0 : queryResult.time_enforcement_ends) !== '0'
593
+ ? new Date(parseInt(queryResult.time_enforcement_ends, 10) * 1000)
594
+ : undefined,
595
+ enforcementType: (_a = queryResult === null || queryResult === void 0 ? void 0 : queryResult.enforcement_type) !== null && _a !== void 0 ? _a : Types_1.ReachoutTimelockEnforcementType.DEFAULT
596
+ };
597
+ ev.emit('connection.update', { reachoutTimeLock: result });
598
+ return result;
599
+ };
600
+ /**
601
+ * Fetches your account's new chat limits.
602
+ * @returns Returns the quota and the usage.
603
+ */
604
+ const fetchNewChatMessageCap = async () => {
605
+ return (0, mex_1.executeWMexQuery)({ input: { type: 'INDIVIDUAL_NEW_CHAT_MSG' } }, Types_1.QueryIds.MESSAGE_CAPPING_INFO, Types_1.XWAPaths.xwa2_message_capping_info, query, generateMessageTag);
606
+ };
582
607
  return {
583
608
  type: 'md',
584
609
  ws,
@@ -602,7 +627,9 @@ const makeSocket = (config) => {
602
627
  requestPairingCode,
603
628
  /** Waits for the connection to WA to reach a state */
604
629
  waitForConnectionUpdate: (0, Utils_1.bindWaitForConnectionUpdate)(ev),
605
- sendWAMBuffer
630
+ sendWAMBuffer,
631
+ fetchAccountReachoutTimelock,
632
+ fetchNewChatMessageCap
606
633
  };
607
634
  };
608
635
  exports.makeSocket = makeSocket;
@@ -15,6 +15,8 @@ var XWAPaths;
15
15
  XWAPaths["xwa2_newsletter_change_owner"] = "xwa2_newsletter_change_owner";
16
16
  XWAPaths["xwa2_newsletter_demote"] = "xwa2_newsletter_demote";
17
17
  XWAPaths["xwa2_newsletter_delete_v2"] = "xwa2_newsletter_delete_v2";
18
+ XWAPaths["xwa2_fetch_account_reachout_timelock"] = "xwa2_fetch_account_reachout_timelock";
19
+ XWAPaths["xwa2_message_capping_info"] = "xwa2_message_capping_info";
18
20
  })(XWAPaths || (exports.XWAPaths = XWAPaths = {}));
19
21
  var QueryIds;
20
22
  (function (QueryIds) {
@@ -30,4 +32,6 @@ var QueryIds;
30
32
  QueryIds["CHANGE_OWNER"] = "7341777602580933";
31
33
  QueryIds["DEMOTE"] = "6551828931592903";
32
34
  QueryIds["DELETE"] = "30062808666639665";
35
+ QueryIds["REACHOUT_TIMELOCK"] = "23983697327930364";
36
+ QueryIds["MESSAGE_CAPPING_INFO"] = "24503548349331633";
33
37
  })(QueryIds || (exports.QueryIds = QueryIds = {}));
@@ -1,2 +1,40 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NewChatMessageCappingMVStatusType = exports.NewChatMessageCappingStatusType = exports.ReachoutTimelockEnforcementType = void 0;
4
+ var ReachoutTimelockEnforcementType;
5
+ (function (ReachoutTimelockEnforcementType) {
6
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_ALCOHOL"] = "BIZ_COMMERCE_VIOLATION_ALCOHOL";
7
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_ADULT"] = "BIZ_COMMERCE_VIOLATION_ADULT";
8
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_ANIMALS"] = "BIZ_COMMERCE_VIOLATION_ANIMALS";
9
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_BODY_PARTS_FLUIDS"] = "BIZ_COMMERCE_VIOLATION_BODY_PARTS_FLUIDS";
10
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DATING"] = "BIZ_COMMERCE_VIOLATION_DATING";
11
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DIGITAL_SERVICES_PRODUCTS"] = "BIZ_COMMERCE_VIOLATION_DIGITAL_SERVICES_PRODUCTS";
12
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DRUGS"] = "BIZ_COMMERCE_VIOLATION_DRUGS";
13
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_DRUGS_ONLY_OTC"] = "BIZ_COMMERCE_VIOLATION_DRUGS_ONLY_OTC";
14
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_GAMBLING"] = "BIZ_COMMERCE_VIOLATION_GAMBLING";
15
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_HEALTHCARE"] = "BIZ_COMMERCE_VIOLATION_HEALTHCARE";
16
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_REAL_FAKE_CURRENCY"] = "BIZ_COMMERCE_VIOLATION_REAL_FAKE_CURRENCY";
17
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_SUPPLEMENTS"] = "BIZ_COMMERCE_VIOLATION_SUPPLEMENTS";
18
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_TOBACCO"] = "BIZ_COMMERCE_VIOLATION_TOBACCO";
19
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_VIOLENT_CONTENT"] = "BIZ_COMMERCE_VIOLATION_VIOLENT_CONTENT";
20
+ ReachoutTimelockEnforcementType["BIZ_COMMERCE_VIOLATION_WEAPONS"] = "BIZ_COMMERCE_VIOLATION_WEAPONS";
21
+ ReachoutTimelockEnforcementType["BIZ_QUALITY"] = "BIZ_QUALITY";
22
+ /** This means there is no restriction */
23
+ ReachoutTimelockEnforcementType["DEFAULT"] = "DEFAULT";
24
+ ReachoutTimelockEnforcementType["WEB_COMPANION_ONLY"] = "WEB_COMPANION_ONLY";
25
+ })(ReachoutTimelockEnforcementType || (exports.ReachoutTimelockEnforcementType = ReachoutTimelockEnforcementType = {}));
26
+ var NewChatMessageCappingStatusType;
27
+ (function (NewChatMessageCappingStatusType) {
28
+ NewChatMessageCappingStatusType["NONE"] = "NONE";
29
+ NewChatMessageCappingStatusType["FIRST_WARNING"] = "FIRST_WARNING";
30
+ NewChatMessageCappingStatusType["SECOND_WARNING"] = "SECOND_WARNING";
31
+ NewChatMessageCappingStatusType["CAPPED"] = "CAPPED";
32
+ })(NewChatMessageCappingStatusType || (exports.NewChatMessageCappingStatusType = NewChatMessageCappingStatusType = {}));
33
+ var NewChatMessageCappingMVStatusType;
34
+ (function (NewChatMessageCappingMVStatusType) {
35
+ NewChatMessageCappingMVStatusType["NOT_ELIGIBLE"] = "NOT_ELIGIBLE";
36
+ NewChatMessageCappingMVStatusType["NOT_ACTIVE"] = "NOT_ACTIVE";
37
+ NewChatMessageCappingMVStatusType["ACTIVE"] = "ACTIVE";
38
+ NewChatMessageCappingMVStatusType["ACTIVE_UPGRADE_AVAILABLE"] = "ACTIVE_UPGRADE_AVAILABLE";
39
+ })(NewChatMessageCappingMVStatusType || (exports.NewChatMessageCappingMVStatusType = NewChatMessageCappingMVStatusType = {}));
40
+
@@ -121,6 +121,9 @@ function decodeMessageNode(stanza, meId, meLid) {
121
121
  const key = {
122
122
  remoteJid: chatId,
123
123
  remoteJidAlt: !(0, WABinary_1.isJidGroup)(chatId) ? addrCtx.senderAlt : undefined,
124
+ remoteJidUsername: !(0, WABinary_1.isJidGroup)(chatId)
125
+ ? (stanza.attrs.peer_recipient_username || stanza.attrs.recipient_username)
126
+ : undefined,
124
127
  fromMe,
125
128
  id: msgId,
126
129
  senderLid: senderLidValue,
@@ -129,6 +132,7 @@ function decodeMessageNode(stanza, meId, meLid) {
129
132
  participantAlt: (0, WABinary_1.isJidGroup)(chatId) ? addrCtx.senderAlt : undefined,
130
133
  participantPn: (_d = stanza === null || stanza === void 0 ? void 0 : stanza.attrs) === null || _d === void 0 ? void 0 : _d.participant_pn,
131
134
  participantLid: (_e = stanza === null || stanza === void 0 ? void 0 : stanza.attrs) === null || _e === void 0 ? void 0 : _e.participant_lid,
135
+ participantUsername: stanza.attrs.participant ? stanza.attrs.participant_username : undefined,
132
136
  addressingMode: addrCtx.addressingMode,
133
137
  ...(msgType === 'newsletter' && stanza.attrs.server_id ? { server_id: stanza.attrs.server_id } : {})
134
138
  };
@@ -31,3 +31,4 @@ __exportStar(require("./use-multi-file-auth-state"), exports);
31
31
  __exportStar(require("./link-preview"), exports);
32
32
  __exportStar(require("./event-buffer"), exports);
33
33
  __exportStar(require("./process-message"), exports);
34
+ __exportStar(require("./rich-messages"), exports);
@@ -307,16 +307,21 @@ const toBuffer = async (stream) => {
307
307
  };
308
308
  exports.toBuffer = toBuffer;
309
309
  const getStream = async (item, opts) => {
310
+ if (item === undefined || item === null) {
311
+ throw new boom_1.Boom('Media input is missing — expected a Buffer, { stream }, or { url } but got ' + item, { statusCode: 400 });
312
+ }
310
313
  if (Buffer.isBuffer(item)) {
311
314
  return { stream: (0, exports.toReadable)(item), type: 'buffer' };
312
315
  }
313
- if ('stream' in item) {
316
+ if (typeof item === 'object' && 'stream' in item && item.stream) {
314
317
  return { stream: item.stream, type: 'readable' };
315
318
  }
316
- if (item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) {
317
- return { stream: await (0, exports.getHttpStream)(item.url, opts), type: 'remote' };
319
+ if (typeof item === 'object' && item.url) {
320
+ return item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')
321
+ ? { stream: await (0, exports.getHttpStream)(item.url, opts), type: 'remote' }
322
+ : { stream: (0, fs_1.createReadStream)(item.url), type: 'file' };
318
323
  }
319
- return { stream: (0, fs_1.createReadStream)(item.url), type: 'file' };
324
+ throw new boom_1.Boom('Unsupported media input — expected a Buffer, { stream }, or { url } but got ' + JSON.stringify(item), { statusCode: 400 });
320
325
  };
321
326
  exports.getStream = getStream;
322
327
  /** generates a thumbnail for a given media, if required */
@@ -621,136 +621,97 @@ else if ('paymentInvite' in message) {
621
621
  else if ('stickerPack' in message) {
622
622
  const { stickers, cover, name, publisher, packId, description } = message.stickerPack;
623
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));
624
+ if (!Array.isArray(stickers) || stickers.length === 0) {
625
+ throw new boom_1.Boom('Sticker pack must contain at least one sticker', { statusCode: 400 });
626
+ }
627
+ if (stickers.length > 120) {
628
+ throw new boom_1.Boom('Sticker pack exceeds the maximum limit of 120 stickers', { statusCode: 400 });
629
+ }
630
+ // WhatsApp requires every sticker to actually be WebP-encoded (not just named
631
+ // ".webp") — verified via magic bytes rather than trusting the file extension.
632
+ // We deliberately don't convert other formats here (that would require sharp or
633
+ // a webp-capable jimp build); pass in stickers that are already WebP.
634
+ const isWebPBuffer = (buf) => (buf.length >= 12 &&
635
+ buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46 &&
636
+ buf[8] === 0x57 && buf[9] === 0x45 && buf[10] === 0x42 && buf[11] === 0x50);
637
+ const isAnimatedWebP = (buf) => {
638
+ let offset = 12;
639
+ while (offset < buf.length - 8) {
640
+ const fourCC = buf.toString('ascii', offset, offset + 4);
641
+ const chunkSize = buf.readUInt32LE(offset + 4);
642
+ if (fourCC === 'VP8X') {
643
+ const flagsOffset = offset + 8;
644
+ if (flagsOffset < buf.length && (buf[flagsOffset] & 0x02)) {
645
+ return true;
646
+ }
652
647
  }
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,
648
+ else if (fourCC === 'ANIM' || fourCC === 'ANMF') {
649
+ return true;
650
+ }
651
+ offset += 8 + chunkSize + (chunkSize % 2);
652
+ }
653
+ return false;
697
654
  };
698
- }
699
- /*else if ('stickerPack' in message) {
700
- const { stickers, cover, name, publisher, packId, description } = message.stickerPack;
701
- const { zip } = require("fflate");
702
-
655
+ if (!cover) {
656
+ throw new boom_1.Boom('Sticker pack: a "cover" image (Buffer, { url } or { stream }) is required', { statusCode: 400 });
657
+ }
703
658
  const stickerData = {};
704
- const stickerPromises = stickers.map(async (s, i) => {
705
- const { stream } = await (0, messages_media_1.getStream)(s.sticker);
659
+ const stickerMetadata = await Promise.all(stickers.map(async (s, i) => {
660
+ const stickerInput = s?.sticker ?? s;
661
+ if (!stickerInput) {
662
+ throw new boom_1.Boom(`Sticker pack: sticker at index ${i} is missing its media (expected { sticker: Buffer | { url } | { stream } })`, { statusCode: 400 });
663
+ }
664
+ const { stream } = await (0, messages_media_1.getStream)(stickerInput);
706
665
  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
-
666
+ if (!buffer || buffer.length === 0) {
667
+ throw new boom_1.Boom(`Sticker pack: sticker at index ${i} is empty`, { statusCode: 400 });
668
+ }
669
+ if (!isWebPBuffer(buffer)) {
670
+ throw new boom_1.Boom(`Sticker pack: sticker at index ${i} is not a valid WebP image. ` +
671
+ 'Convert it to WebP before passing it in (e.g. with sharp or an external converter).', { statusCode: 400 });
672
+ }
673
+ const hash = (0, crypto_2.sha256)(buffer).toString('base64url');
674
+ const fileName = `${i.toString().padStart(2, '0')}_${hash}.webp`;
675
+ stickerData[fileName] = [new Uint8Array(buffer), { level: 6 }];
712
676
  return {
713
677
  fileName,
714
- mimetype: "image/webp",
715
- isAnimated: s.isAnimated || false,
678
+ mimetype: 'image/webp',
679
+ isAnimated: typeof s.isAnimated === 'boolean' ? s.isAnimated : isAnimatedWebP(buffer),
716
680
  isLottie: s.isLottie || false,
717
681
  emojis: s.emojis || [],
718
- accessibilityLabel: s.accessibilityLabel || "",
682
+ accessibilityLabel: s.accessibilityLabel || ''
719
683
  };
720
- });
721
-
722
- const stickerMetadata = await Promise.all(stickerPromises);
723
-
684
+ }));
724
685
  const zipBuffer = await new Promise((resolve, reject) => {
725
686
  zip(stickerData, (err, data) => {
726
687
  if (err) {
727
688
  reject(err);
728
- } else {
689
+ }
690
+ else {
729
691
  resolve(Buffer.from(data));
730
692
  }
731
693
  });
732
694
  });
733
-
734
695
  const coverBuffer = await (0, messages_media_1.toBuffer)((await (0, messages_media_1.getStream)(cover)).stream);
735
-
736
696
  const [stickerPackUpload, coverUpload] = await Promise.all([
737
- (0, messages_media_1.encryptedStream)(zipBuffer, "sticker-pack", {
697
+ (0, messages_media_1.encryptedStream)(zipBuffer, 'sticker-pack', {
738
698
  logger: options.logger,
739
- opts: options.options,
699
+ opts: options.options
740
700
  }),
741
- (0, exports.prepareWAMessageMedia)({ image: coverBuffer }, { ...options, mediaTypeOverride: "image" })
701
+ // prepareWAMessageMedia already resizes/re-encodes the cover to a JPEG via
702
+ // sharp if installed, falling back to jimp automatically (same helper the
703
+ // rest of this file already relies on for thumbnails/profile pictures) —
704
+ // no extra image library needed here.
705
+ (0, exports.prepareWAMessageMedia)({ image: coverBuffer }, { ...options, mediaTypeOverride: 'image' })
742
706
  ]);
743
-
744
707
  const stickerPackUploadResult = await options.upload(stickerPackUpload.encFilePath, {
745
- fileEncSha256B64: stickerPackUpload.fileEncSha256.toString("base64"),
746
- mediaType: "sticker-pack",
747
- timeoutMs: options.mediaUploadTimeoutMs,
708
+ fileEncSha256B64: stickerPackUpload.fileEncSha256.toString('base64'),
709
+ mediaType: 'sticker-pack',
710
+ timeoutMs: options.mediaUploadTimeoutMs
748
711
  });
749
-
750
712
  const coverImage = coverUpload.imageMessage;
751
- const imageDataHash = (0, crypto_2.sha256)(coverBuffer).toString("base64");
713
+ const imageDataHash = (0, crypto_2.sha256)(coverBuffer).toString('base64');
752
714
  const stickerPackId = packId || (0, generics_1.generateMessageIDV2)();
753
-
754
715
  m.stickerPackMessage = {
755
716
  name,
756
717
  publisher,
@@ -765,15 +726,15 @@ else if ('paymentInvite' in message) {
765
726
  directPath: stickerPackUploadResult.directPath,
766
727
  fileLength: stickerPackUpload.fileLength,
767
728
  mediaKeyTimestamp: (0, generics_1.unixTimestampSeconds)(),
768
- trayIconFileName: `${stickerPackId}.png`,
729
+ trayIconFileName: `${stickerPackId}.webp`,
769
730
  imageDataHash,
770
731
  thumbnailDirectPath: coverImage.directPath,
771
- thumbnailFileSha256: coverImage.fileSha256,
772
- thumbnailFileEncSha256: coverImage.fileEncSha256,
732
+ thumbnailSha256: coverImage.fileSha256,
733
+ thumbnailEncSha256: coverImage.fileEncSha256,
773
734
  thumbnailHeight: coverImage.height,
774
- thumbnailWidth: coverImage.width,
735
+ thumbnailWidth: coverImage.width
775
736
  };
776
- }*/
737
+ }
777
738
 
778
739
 
779
740
 
@@ -244,13 +244,14 @@ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderRes
244
244
  const jid = (_f = message.key) === null || _f === void 0 ? void 0 : _f.remoteJid;
245
245
  //let actor = whatsappID (message.participant)
246
246
  let participants;
247
- const emitParticipantsUpdate = (action) => ev.emit('group-participants.update', { id: jid, author: message.participant, participants, action });
247
+ const emitParticipantsUpdate = (action) => { var _a, _b; return ev.emit('group-participants.update', { id: jid, author: message.participant, authorUsername: (_b = (_a = message.key) === null || _a === void 0 ? void 0 : _a.participantUsername) !== null && _b !== void 0 ? _b : undefined, participants, action }); };
248
248
  const emitGroupUpdate = (update) => {
249
- var _a;
250
- ev.emit('groups.update', [{ id: jid, ...update, author: (_a = message.participant) !== null && _a !== void 0 ? _a : undefined }]);
249
+ var _a, _b, _c;
250
+ ev.emit('groups.update', [{ id: jid, ...update, author: (_a = message.participant) !== null && _a !== void 0 ? _a : undefined, authorUsername: (_c = (_b = message.key) === null || _b === void 0 ? void 0 : _b.participantUsername) !== null && _c !== void 0 ? _c : undefined }]);
251
251
  };
252
252
  const emitGroupRequestJoin = (participant, action, method) => {
253
- ev.emit('group.join-request', { id: jid, author: message.participant, participant, action, method: method });
253
+ var _a, _b;
254
+ ev.emit('group.join-request', { id: jid, author: message.participant, authorUsername: (_b = (_a = message.key) === null || _a === void 0 ? void 0 : _a.participantUsername) !== null && _b !== void 0 ? _b : undefined, participant, action, method: method });
254
255
  };
255
256
  const participantsIncludesMe = () => participants.find(jid => (0, WABinary_1.areJidsSameUser)(meId, jid));
256
257
  switch (message.messageStubType) {