ishumdz-bail 1.0.24 → 1.0.26

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.
@@ -586,7 +586,10 @@ export const generateWAMessageContent = async (message, options) => {
586
586
  if ('interactiveButtons' in message && !!message.interactiveButtons) {
587
587
  const nativeFlow = proto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
588
588
  buttons: message.interactiveButtons,
589
- messageParamsJson: message.messageParams ?? "{}"
589
+ messageParamsJson: message.messageParams ?? "{}",
590
+ // PATCH (1.0.26): default messageVersion to 1 — version 0 renders as
591
+ // greyed-out, untappable placeholder buttons on current clients.
592
+ messageVersion: message.messageVersion ?? 1
590
593
  });
591
594
  let interactiveMessage = { nativeFlowMessage: nativeFlow };
592
595
  if ('text' in message) {
@@ -652,12 +655,27 @@ export const generateWAMessageContent = async (message, options) => {
652
655
  m = { interactiveMessage };
653
656
  }
654
657
  else if ('buttonsMessage' in message && !!message.buttonsMessage) {
655
- // PATCH: raw buttonsMessage — always classic pass-through. Modern clients
656
- // render the horizontal row when a header exists (image/video/document/
657
- // location) or when a thumbnail header is attached; text-only without any
658
- // header is the "version doesn't support it" case. Add a header in that
659
- // situation, or use the `buttons` API which auto-adds one.
660
- m = { buttonsMessage: proto.Message.ButtonsMessage.create(message.buttonsMessage) };
658
+ // PATCH: raw buttonsMessage — classic pass-through. Modern clients render
659
+ // the horizontal row only when a header exists (image/video/document/
660
+ // location). A text-only raw message WITHOUT any header is exactly the
661
+ // "version doesn't support it" case — so when the caller passed none, we
662
+ // attach the invisible 1x1 PNG image header automatically (same trick the
663
+ // `buttons` API uses) and the row always renders. This is unconditional:
664
+ // header-less raw messages can never produce the "not supported" bubble.
665
+ const raw = proto.Message.ButtonsMessage.fromObject(message.buttonsMessage)
666
+ // NOTE: fromObject turns missing fields into null (protobuf defaults), so
667
+ // a nullish headerType (= caller never set it) counts as "no header" too.
668
+ const hasHeader = !!(raw.imageMessage || raw.videoMessage || raw.documentMessage ||
669
+ raw.locationMessage ||
670
+ (raw.headerType != null && raw.headerType !== ButtonType.EMPTY && raw.headerType !== ButtonType.UNKNOWN))
671
+ if (!hasHeader) {
672
+ try {
673
+ const media = await prepareWAMessageMedia({ image: BUTTONS_INVISIBLE_PNG() }, options)
674
+ raw.imageMessage = media.imageMessage
675
+ raw.headerType = ButtonType.IMAGE
676
+ } catch { /* upload failed — send as-is */ }
677
+ }
678
+ m = { buttonsMessage: raw };
661
679
  }
662
680
  else if ('buttons' in message && !!message.buttons) {
663
681
  // PATCH: `buttons` API — HORIZONTAL button row via classic ButtonsMessage
@@ -707,6 +725,63 @@ export const generateWAMessageContent = async (message, options) => {
707
725
  applyContextInfoAndMentions(interactiveMessage, message);
708
726
  m = { interactiveMessage };
709
727
  }
728
+ else if (message.buttons.some(b => buildActionFlow(b) || buildButtonSections(b))) {
729
+ // PATCH (1.0.26): a classic ButtonsMessage that MIXES native-flow
730
+ // extras (rows/sections sheet, url/copy/call actions) with a media
731
+ // or location header renders as "version doesn't support it" on
732
+ // current clients (real-device evidence). So when any button
733
+ // carries an extra, the WHOLE message is upgraded to a native-flow
734
+ // interactive card — map/media header + body + footer + every
735
+ // button type (single_select, cta_url, quick_reply) — which modern
736
+ // clients render fully. Plain-only rows keep the classic
737
+ // horizontal ButtonsMessage (that path is proven to render).
738
+ const flowButtons = message.buttons.map(b => {
739
+ const action = buildActionFlow(b);
740
+ if (action) return { name: action.name, buttonParamsJson: JSON.stringify(action.params) };
741
+ const sections = buildButtonSections(b);
742
+ if (sections) return { name: 'single_select', buttonParamsJson: JSON.stringify({ title: b.buttonText?.displayText || b.displayText || 'Menu', sections }) };
743
+ return { name: 'quick_reply', buttonParamsJson: JSON.stringify({ display_text: b.buttonText?.displayText || b.displayText || b.text || '', id: b.buttonId || b.id || b.buttonText?.displayText || '' }) };
744
+ });
745
+ const interactiveMessage = {
746
+ nativeFlowMessage: { buttons: flowButtons, messageParamsJson: '', messageVersion: 1 }
747
+ };
748
+ if ('text' in message) interactiveMessage.body = { text: message.text };
749
+ else if ('caption' in message) interactiveMessage.body = { text: message.caption };
750
+ if ('footer' in message && !!message.footer) interactiveMessage.footer = { text: message.footer };
751
+ const header = {
752
+ title: message.title || (message.caption ? String(message.caption).split('\n')[0].slice(0, 42) : '') || 'Menu',
753
+ subtitle: message.subtitle || '',
754
+ hasMediaAttachment: false
755
+ };
756
+ if ('location' in message && !!message.location) {
757
+ const loc = message.location;
758
+ header.locationMessage = {
759
+ degreesLatitude: loc.degreesLatitude ?? loc.latitude ?? 0,
760
+ degreesLongitude: loc.degreesLongitude ?? loc.longitude ?? 0,
761
+ name: loc.name ?? null,
762
+ address: loc.address ?? null,
763
+ ...(loc.jpegThumbnail ? { jpegThumbnail: loc.jpegThumbnail } : {})
764
+ };
765
+ header.hasMediaAttachment = true;
766
+ } else if ('video' in message && !!message.video) {
767
+ const media = await prepareWAMessageMedia({ video: message.video }, options);
768
+ header.videoMessage = media.videoMessage;
769
+ if (message.gifPlayback) header.videoMessage.gifPlayback = true;
770
+ header.hasMediaAttachment = true;
771
+ } else if ('gif' in message && !!message.gif) {
772
+ const media = await prepareWAMessageMedia({ video: message.gif }, options);
773
+ header.videoMessage = media.videoMessage;
774
+ header.videoMessage.gifPlayback = true;
775
+ header.hasMediaAttachment = true;
776
+ } else if ('image' in message && !!message.image) {
777
+ const media = await prepareWAMessageMedia({ image: message.image }, options);
778
+ header.imageMessage = media.imageMessage;
779
+ header.hasMediaAttachment = true;
780
+ }
781
+ if (header.title || header.hasMediaAttachment) interactiveMessage.header = header;
782
+ applyContextInfoAndMentions(interactiveMessage, message);
783
+ m = { interactiveMessage };
784
+ }
710
785
  else if ('location' in message && !!message.location) {
711
786
  const loc = message.location;
712
787
  const buttonsMessage = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ishumdz-bail",
3
- "version": "1.0.24",
3
+ "version": "1.0.26",
4
4
  "description": "WhatsApp API Modification By Lovely",
5
5
  "keywords": [
6
6
  "whatsapp",
@@ -43,7 +43,7 @@
43
43
  "prepare": "",
44
44
  "preinstall": "node ./engine-requirements.js",
45
45
  "release": "release-it",
46
- "test": "jest"
46
+ "test": "node --test \"test/**/*.test.mjs\""
47
47
  },
48
48
  "dependencies": {
49
49
  "@cacheable/node-cache": "^1.4.0",