@vanzxy/baileys 1.4.5 → 1.4.7

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.
@@ -61,7 +61,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
61
61
  var _a, _Button_client, _Button_validateAgainstSchema, _ButtonV2_client, _Carousel_client, _Poll_client, _AIRich_client;
62
62
  Object.defineProperty(exports, "__esModule", { value: true });
63
63
  exports.Toolkit = exports.VanzxyRich = exports.VanzxyAI = exports.LeafRich = exports.AIVanzxy = exports.AIRich = exports.Poll = exports.Carousel = exports.ButtonV2 = exports.Button = exports.MESSAGE_BUILDER_VERSION = void 0;
64
- const MESSAGE_BUILDER_VERSION = '4.7';
64
+ const MESSAGE_BUILDER_VERSION = '4.9';
65
65
  exports.MESSAGE_BUILDER_VERSION = MESSAGE_BUILDER_VERSION;
66
66
  const messages_js_1 = require("./messages.js");
67
67
  const rich_message_utils_js_1 = require("./rich-message-utils.js");
@@ -1378,7 +1378,7 @@ class AIRich extends BaseBuilder {
1378
1378
  }))));
1379
1379
  return this;
1380
1380
  }
1381
- addImage(imageUrl, { resolveUrl = false } = {}) {
1381
+ addImage(imageUrl, { resolveUrl = false, instant = false } = {}) {
1382
1382
  if (!(typeof imageUrl === 'string' || Buffer.isBuffer(imageUrl) || (Array.isArray(imageUrl) && imageUrl.every((v) => typeof v === 'string' || Buffer.isBuffer(v))))) {
1383
1383
  throw new TypeError('imageUrl must be string | buffer | array of string/buffer');
1384
1384
  }
@@ -1420,6 +1420,9 @@ class AIRich extends BaseBuilder {
1420
1420
  status: { status: 'READY' },
1421
1421
  __typename: 'GenAIImaginePrimitive',
1422
1422
  }));
1423
+ if (instant) {
1424
+ this._inlineImages.push({ url: imagePreviewUrl, caption: undefined });
1425
+ }
1423
1426
  });
1424
1427
  return this;
1425
1428
  }
@@ -2599,7 +2602,7 @@ class AIRich extends BaseBuilder {
2599
2602
  unified_rows,
2600
2603
  };
2601
2604
  }
2602
- addGenerating({ imagine_type = 'IMAGE', estimated_completion_time } = {}) {
2605
+ addGenerating({ imagine_type = 'IMAGE', estimated_completion_time, textFallback = true } = {}) {
2603
2606
  this._submessages.push({ messageType: 2, messageText: '[ Sedang diproses... ]' });
2604
2607
  this._sections.push(AIRich.newLayout('Single', {
2605
2608
  media: { url: '', mime_type: imagine_type === 'ANIMATE' ? 'video/mp4' : 'image/png' },
@@ -2610,6 +2613,11 @@ class AIRich extends BaseBuilder {
2610
2613
  },
2611
2614
  __typename: 'GenAIImaginePrimitive',
2612
2615
  }));
2616
+ // Vanz@Fix 23-08-26 (v4.8) --- instant FOATextPrimitive fallback instead of
2617
+ // relying on WA's own generation-timeout text. Set { textFallback: false } to skip.
2618
+ if (textFallback) {
2619
+ this._sections.push(AIRich.newLayout('Single', { text: '[ Sedang diproses... ]', __typename: 'FOATextPrimitive' }));
2620
+ }
2613
2621
  return this;
2614
2622
  }
2615
2623
  static async sendSupportPayload(client, jid, text, { ticketId = crypto_1.default.randomUUID(), isAiMessage = true, shouldShowSystemMessage = true, version = 1 } = {}) {
@@ -181,7 +181,7 @@ export class AIRich extends BaseBuilder {
181
181
  addBloks(data: { type: string; data?: string; uuid?: string; initial_response?: any; versioning_id?: string; textFallback?: boolean }): this;
182
182
  addSuggest(suggestion: Record<string, any>, options?: { scroll?: boolean; layout?: string }): this;
183
183
  /** GenAIImaginePrimitive with status GENERATING — pending-generation placeholder, distinct from addImage()/addVideo()'s READY status. */
184
- addGenerating(options?: { imagine_type?: 'IMAGE' | 'ANIMATE'; estimated_completion_time?: number }): this;
184
+ addGenerating(options?: { imagine_type?: 'IMAGE' | 'ANIMATE'; estimated_completion_time?: number; textFallback?: boolean }): this;
185
185
  build(): Record<string, any>;
186
186
  send(jid: string, options?: Record<string, any>): Promise<any>;
187
187
 
@@ -10,6 +10,12 @@
10
10
  * and message-authenticity fields backported from arslan-baileys 1.1.0 and
11
11
  * this project's own rich-message-utils.js. See changes tagged "Vanz@" below.
12
12
  *
13
+ * Vanz@Fix 23-08-26 --- v4.7 -> v4.8. addGenerating() now defaults to appending a
14
+ * FOATextPrimitive text fallback ('[ Sedang diproses... ]'), same pattern as
15
+ * addTask/addThinkingStatus/addBloks. Previously the card had no client-visible
16
+ * content until WA's own timeout swapped it for its built-in failed-generation
17
+ * text; this makes the fallback instant. Opt out with { textFallback: false }.
18
+ *
13
19
  * Vanz@Merge 22-08-26 --- v4.6 -> v4.7. Button class hardened + extended:
14
20
  * - Bug fix: addCall() wrote its second arg into buttonParamsJson.id, but
15
21
  * the cta_call native-flow schema keys on `phone_number` (id is ignored
@@ -38,7 +44,7 @@
38
44
 
39
45
  'use strict';
40
46
 
41
- const MESSAGE_BUILDER_VERSION = '4.7';
47
+ const MESSAGE_BUILDER_VERSION = '4.9';
42
48
 
43
49
  import { generateWAMessageFromContent, prepareWAMessageMedia } from './messages.js';
44
50
  import { botMetadataSignature, botMetadataCertificate } from './rich-message-utils.js';
@@ -1581,6 +1587,68 @@ class AIRich extends BaseBuilder {
1581
1587
  // mediaKey still doesn't render, so it's a trust-chain gate, not a domain/encoding issue).
1582
1588
  // Track every addInlineImage() call here so send() can fall back to a normal imageMessage.
1583
1589
  this._inlineImages = [];
1590
+
1591
+ // Vanz@Add (v4.9.1) --- { id, insertAt } support for every add*()/set*() call, without
1592
+ // touching each method's own body/signature. Every add*() call ends up pushing 0-N items
1593
+ // onto _submessages and 0-N onto _sections (some push to both, some to just one — e.g.
1594
+ // addSuggest only touches _submessages, addSection only touches _sections). A Proxy wraps
1595
+ // every add*/set* call: it snapshots array lengths before calling the real method, lets the
1596
+ // method push onto the tail as it always has, then — if the caller passed { insertAt } —
1597
+ // peels those freshly-pushed items back off the tail and re-splices them right after the
1598
+ // last item that belongs to the block named by insertAt. Blocks are tracked by *object
1599
+ // reference*, not saved numeric index, so earlier insertions shifting the array around never
1600
+ // invalidates a later insertAt lookup (indexOf on the reference always finds the live position).
1601
+ this._blocks = new Map(); // id -> { subItems: object[], secItems: object[] }
1602
+ return new Proxy(this, {
1603
+ get(target, prop, receiver) {
1604
+ const orig = Reflect.get(target, prop, receiver);
1605
+ if (typeof orig !== 'function' || !/^(add|set)/.test(String(prop))) return orig;
1606
+
1607
+ return (...args) => {
1608
+ const opts = args.find((a) => a && typeof a === 'object' && !Array.isArray(a) && !Buffer.isBuffer(a) && ('id' in a || 'insertAt' in a));
1609
+ const id = opts?.id;
1610
+ const insertAt = opts?.insertAt;
1611
+
1612
+ const subBefore = target._submessages.length;
1613
+ const secBefore = target._sections.length;
1614
+
1615
+ const result = orig.apply(receiver, args);
1616
+
1617
+ const subItems = target._submessages.splice(subBefore);
1618
+ const secItems = target._sections.splice(secBefore);
1619
+
1620
+ if (insertAt) {
1621
+ const anchor = target._blocks.get(insertAt);
1622
+ if (!anchor) throw new Error(`insertAt: no block registered with id "${insertAt}" (register it by passing { id: "${insertAt}" } on an earlier add*() call)`);
1623
+
1624
+ const lastSub = anchor.subItems[anchor.subItems.length - 1];
1625
+ const subIdx = lastSub ? target._submessages.indexOf(lastSub) + 1 : target._submessages.length;
1626
+ target._submessages.splice(subIdx, 0, ...subItems);
1627
+
1628
+ const lastSec = anchor.secItems[anchor.secItems.length - 1];
1629
+ const secIdx = lastSec ? target._sections.indexOf(lastSec) + 1 : target._sections.length;
1630
+ target._sections.splice(secIdx, 0, ...secItems);
1631
+ } else {
1632
+ target._submessages.push(...subItems);
1633
+ target._sections.push(...secItems);
1634
+ }
1635
+
1636
+ if (id) target._blocks.set(id, { subItems, secItems });
1637
+
1638
+ return result === target ? receiver : result;
1639
+ };
1640
+ },
1641
+ });
1642
+ }
1643
+
1644
+ /** Flatten every primitive pushed into `_sections` so far into one array — lets you build a
1645
+ * card set in one AIRich instance and re-embed it into another via addSection(AIRich.newLayout(...)). */
1646
+ get items() {
1647
+ return this._sections.flatMap((s) => {
1648
+ const vm = s?.view_model;
1649
+ if (!vm) return [];
1650
+ return vm.primitives ?? (vm.primitive !== undefined ? [vm.primitive] : []);
1651
+ });
1584
1652
  }
1585
1653
 
1586
1654
  /** Push a raw pre-built submessage block (escape hatch for shapes not covered by the add*() helpers). */
@@ -1697,7 +1765,7 @@ class AIRich extends BaseBuilder {
1697
1765
  }
1698
1766
 
1699
1767
  /** Add a "Sources" strip. @param {string[]|string[][]} sources Flat list of urls, or `[title, url]` pairs. */
1700
- addSource(sources = []) {
1768
+ addSource(sources = [], { resolveUrl = false } = {}) {
1701
1769
  if (!(Array.isArray(sources) && (sources.every((item) => typeof item === 'string') || sources.every((item) => Array.isArray(item) && item.every((v) => typeof v === 'string'))))) {
1702
1770
  throw new TypeError('Sources must be a string array or an array of string arrays');
1703
1771
  }
@@ -1712,7 +1780,7 @@ class AIRich extends BaseBuilder {
1712
1780
  source_subtitle: 'AI',
1713
1781
  source_url: url ?? '',
1714
1782
  favicon: {
1715
- url: Toolkit.resolveMedia(this.#client, icon ?? '', 'image'),
1783
+ url: Toolkit.resolveMedia(this.#client, icon ?? '', 'image', { resolveUrl }),
1716
1784
  mime_type: 'image/jpeg',
1717
1785
  width: 16,
1718
1786
  height: 16,
@@ -1730,7 +1798,7 @@ class AIRich extends BaseBuilder {
1730
1798
  }
1731
1799
 
1732
1800
  /** Add a horizontally-scrollable reel of image/video items. */
1733
- addReels(reelsItems = []) {
1801
+ addReels(reelsItems = [], { resolveUrl = false } = {}) {
1734
1802
  if (
1735
1803
  !(
1736
1804
  (reelsItems && typeof reelsItems === 'object' && !Array.isArray(reelsItems)) ||
@@ -1746,8 +1814,8 @@ class AIRich extends BaseBuilder {
1746
1814
 
1747
1815
  const reels = reelsItems.map((item) => ({
1748
1816
  ...item,
1749
- _avatar: Toolkit.resolveMedia(this.#client, item.profileIconUrl ?? item.profile_url ?? item.profile ?? '', 'image'),
1750
- _thumbnail: Toolkit.resolveMedia(this.#client, item.thumbnailUrl ?? item.thumbnail ?? '', 'image'),
1817
+ _avatar: Toolkit.resolveMedia(this.#client, item.profileIconUrl ?? item.profile_url ?? item.profile ?? '', 'image', { resolveUrl }),
1818
+ _thumbnail: Toolkit.resolveMedia(this.#client, item.thumbnailUrl ?? item.thumbnail ?? '', 'image', { resolveUrl }),
1751
1819
  }));
1752
1820
 
1753
1821
  this._submessages.push({
@@ -1800,10 +1868,24 @@ class AIRich extends BaseBuilder {
1800
1868
  }
1801
1869
 
1802
1870
  /** Add a full-width image (or grid of images if `imageUrl` is an array). */
1803
- addImage(imageUrl, { resolveUrl = false } = {}) {
1871
+ /**
1872
+ * @param {{ resolveUrl?: boolean, instant?: boolean|'only' }} [options]
1873
+ * `instant: true` — sends BOTH: the GRID_IMAGE card (still shows WA's "can't verify"
1874
+ * forwarded-download prompt, unavoidable per-design of botForwardedMessage) AND a plain
1875
+ * (non-forwarded) imageMessage via send()'s inline-image fallback queue (`_inlineImages`,
1876
+ * shared with addInlineImage()) that renders instantly with no prompt. Two images, by design.
1877
+ * `instant: 'only'` — Vanz@Add (v4.9.2): skips building the GRID_IMAGE card entirely (no
1878
+ * submessage, no GenAIImaginePrimitive section) and queues ONLY the plain imageMessage.
1879
+ * One image, no prompt, nothing to download — use this when you don't need the rich card,
1880
+ * just the picture to show up immediately.
1881
+ */
1882
+ addImage(imageUrl, { resolveUrl = false, instant = false } = {}) {
1804
1883
  if (!(typeof imageUrl === 'string' || Buffer.isBuffer(imageUrl) || (Array.isArray(imageUrl) && imageUrl.every((v) => typeof v === 'string' || Buffer.isBuffer(v))))) {
1805
1884
  throw new TypeError('imageUrl must be string | buffer | array of string/buffer');
1806
1885
  }
1886
+ if (instant !== false && instant !== true && instant !== 'only') {
1887
+ throw new TypeError(`instant must be false, true, or 'only' — got ${JSON.stringify(instant)}`);
1888
+ }
1807
1889
 
1808
1890
  const list = Array.isArray(imageUrl)
1809
1891
  ? imageUrl.map((v) => {
@@ -1825,28 +1907,38 @@ class AIRich extends BaseBuilder {
1825
1907
  ];
1826
1908
  })();
1827
1909
 
1828
- this._submessages.push({
1829
- messageType: 1,
1830
- gridImageMetadata: {
1831
- gridImageUrl: {
1832
- imagePreviewUrl: list[0]?.imagePreviewUrl,
1910
+ const buildCard = instant !== 'only';
1911
+
1912
+ if (buildCard) {
1913
+ this._submessages.push({
1914
+ messageType: 1,
1915
+ gridImageMetadata: {
1916
+ gridImageUrl: {
1917
+ imagePreviewUrl: list[0]?.imagePreviewUrl,
1918
+ },
1919
+ imageUrls: list,
1833
1920
  },
1834
- imageUrls: list,
1835
- },
1836
- });
1921
+ });
1922
+ }
1837
1923
 
1838
1924
  list.forEach(({ imagePreviewUrl }) => {
1839
- this._sections.push(
1840
- AIRich.newLayout('Single', {
1841
- media: {
1842
- url: imagePreviewUrl,
1843
- mime_type: 'image/png',
1844
- },
1845
- imagine_type: 'IMAGE',
1846
- status: { status: 'READY' },
1847
- __typename: 'GenAIImaginePrimitive',
1848
- })
1849
- );
1925
+ if (buildCard) {
1926
+ this._sections.push(
1927
+ AIRich.newLayout('Single', {
1928
+ media: {
1929
+ url: imagePreviewUrl,
1930
+ mime_type: 'image/png',
1931
+ },
1932
+ imagine_type: 'IMAGE',
1933
+ status: { status: 'READY' },
1934
+ __typename: 'GenAIImaginePrimitive',
1935
+ })
1936
+ );
1937
+ }
1938
+
1939
+ if (instant) {
1940
+ this._inlineImages.push({ url: imagePreviewUrl, caption: undefined });
1941
+ }
1850
1942
  });
1851
1943
 
1852
1944
  return this;
@@ -1917,8 +2009,12 @@ class AIRich extends BaseBuilder {
1917
2009
  // fetch-full-video + ffmpeg-frame-extraction + duration-parse round trip per video, which
1918
2010
  // was the main source of blurose's slower response time. Pass { autoFill: true } to opt
1919
2011
  // back into the complete/slow path (real thumbnail + duration + file_length).
2012
+ // Vanz@Fix 23-08-26 --- addVideo() had no resolveUrl option at all (unlike addImage()), so the
2013
+ // video url always stayed a raw external link, which stock WA clients show a "download" state
2014
+ // for before rendering. Mirrors addImage()'s { resolveUrl } — when true, the url is uploaded to
2015
+ // WA's own media server first via Toolkit.toUrl() so it renders instantly like WA-native media.
1920
2016
  /** Add a video block. */
1921
- addVideo(videoUrl, { autoFill = false } = {}) {
2017
+ addVideo(videoUrl, { autoFill = false, resolveUrl = false } = {}) {
1922
2018
  const isObjectVideo = (v) => v && typeof v === 'object' && v.url;
1923
2019
 
1924
2020
  const isValidPrimitive =
@@ -1941,7 +2037,9 @@ class AIRich extends BaseBuilder {
1941
2037
  items.forEach((item) => {
1942
2038
  const isObject = isObjectVideo(item);
1943
2039
 
1944
- const url = isObject ? Toolkit.resolveMedia(this.#client, item.url ?? '', 'video') : Toolkit.resolveMedia(this.#client, item, 'video');
2040
+ const url = isObject
2041
+ ? Toolkit.resolveMedia(this.#client, item.url ?? '', 'video', { resolveUrl })
2042
+ : Toolkit.resolveMedia(this.#client, item, 'video', { resolveUrl });
1945
2043
 
1946
2044
  const bufferPromise = autoFill ? Promise.resolve(url).then((u) => Toolkit.fetchBuffer(u)) : null;
1947
2045
 
@@ -1999,7 +2097,7 @@ class AIRich extends BaseBuilder {
1999
2097
  }
2000
2098
 
2001
2099
  /** Add an inline product card (or array of cards). Each item needs at least a `title`. */
2002
- addProduct(data = {}) {
2100
+ addProduct(data = {}, { resolveUrl = false } = {}) {
2003
2101
  if (!((data && typeof data === 'object' && !Array.isArray(data)) || (Array.isArray(data) && data.every((item) => item && typeof item === 'object' && !Array.isArray(item))))) {
2004
2102
  throw new TypeError('Product items must be an object or an array of objects');
2005
2103
  }
@@ -2024,11 +2122,11 @@ class AIRich extends BaseBuilder {
2024
2122
  sale_price: item.sale_price,
2025
2123
  product_url: item.product_url ?? item.url,
2026
2124
  image: {
2027
- url: Toolkit.resolveMedia(this.#client, item.image_url ?? item.image, 'image'),
2125
+ url: Toolkit.resolveMedia(this.#client, item.image_url ?? item.image, 'image', { resolveUrl }),
2028
2126
  },
2029
2127
  additional_images: [
2030
2128
  {
2031
- url: Toolkit.resolveMedia(this.#client, item.icon_url ?? item.icon, 'image'),
2129
+ url: Toolkit.resolveMedia(this.#client, item.icon_url ?? item.icon, 'image', { resolveUrl }),
2032
2130
  },
2033
2131
  ],
2034
2132
  __typename: 'GenAIProductItemCardPrimitive',
@@ -2040,7 +2138,7 @@ class AIRich extends BaseBuilder {
2040
2138
  }
2041
2139
 
2042
2140
  /** Add an inline social-post style card (or array of cards). */
2043
- addPost(data = {}) {
2141
+ addPost(data = {}, { resolveUrl = false } = {}) {
2044
2142
  if (!((data && typeof data === 'object' && !Array.isArray(data)) || (Array.isArray(data) && data.every((item) => item && typeof item === 'object' && !Array.isArray(item))))) {
2045
2143
  throw new TypeError('Post items must be an object or an array of objects');
2046
2144
  }
@@ -2056,9 +2154,9 @@ class AIRich extends BaseBuilder {
2056
2154
  title: p.title ?? '',
2057
2155
  subtitle: p.subtitle ?? '',
2058
2156
  username: p.username ?? '',
2059
- profile_picture_url: Toolkit.resolveMedia(this.#client, p.profile_picture_url ?? p.profile_url ?? p.profile ?? '', 'image'),
2157
+ profile_picture_url: Toolkit.resolveMedia(this.#client, p.profile_picture_url ?? p.profile_url ?? p.profile ?? '', 'image', { resolveUrl }),
2060
2158
  is_verified: !!(p.is_verified || p.verified),
2061
- thumbnail_url: Toolkit.resolveMedia(this.#client, p.thumbnail_url ?? p.thumbnail ?? '', 'image'),
2159
+ thumbnail_url: Toolkit.resolveMedia(this.#client, p.thumbnail_url ?? p.thumbnail ?? '', 'image', { resolveUrl }),
2062
2160
  post_caption: p.post_caption ?? p.caption ?? '',
2063
2161
  likes_count: p.likes_count ?? p.like ?? 0,
2064
2162
  comments_count: p.comments_count ?? p.comment ?? 0,
@@ -2067,7 +2165,7 @@ class AIRich extends BaseBuilder {
2067
2165
  post_deeplink: p.post_deeplink ?? p.deeplink ?? '',
2068
2166
  source_app: p.source_app || p.source || 'INSTAGRAM',
2069
2167
  footer_label: p.footer_label ?? p.footer ?? '',
2070
- footer_icon: Toolkit.resolveMedia(this.#client, p.footer_icon ?? p.icon ?? '', 'image'),
2168
+ footer_icon: Toolkit.resolveMedia(this.#client, p.footer_icon ?? p.icon ?? '', 'image', { resolveUrl }),
2071
2169
  is_carousel: posts.length > 1,
2072
2170
  orientation: p.orientation ?? 'LANDSCAPE',
2073
2171
  post_type: p.post_type ?? 'VIDEO',
@@ -3288,7 +3386,7 @@ class AIRich extends BaseBuilder {
3288
3386
  * Use this to show a pending-generation state before the real media is ready.
3289
3387
  * @param {{ imagine_type?: 'IMAGE'|'ANIMATE', estimated_completion_time?: number }} [options]
3290
3388
  */
3291
- addGenerating({ imagine_type = 'IMAGE', estimated_completion_time } = {}) {
3389
+ addGenerating({ imagine_type = 'IMAGE', estimated_completion_time, textFallback = true } = {}) {
3292
3390
  this._submessages.push({ messageType: 2, messageText: '[ Sedang diproses... ]' });
3293
3391
  this._sections.push(
3294
3392
  AIRich.newLayout('Single', {
@@ -3301,6 +3399,14 @@ class AIRich extends BaseBuilder {
3301
3399
  __typename: 'GenAIImaginePrimitive',
3302
3400
  })
3303
3401
  );
3402
+ // Vanz@Fix 23-08-26 (v4.8) --- media.url kosong + status GENERATING gak punya renderer
3403
+ // visual instan di stock WA client; sebelumnya cuma diem sampe WA nge-timeout sendiri
3404
+ // dan nampilin fallback bawaannya ("Saat ini, saya tidak bisa membuat gambar itu...").
3405
+ // Same fix class kayak addTask/addBloks: append FOATextPrimitive biar ada fallback
3406
+ // instan, gak perlu nunggu timeout WA. Set { textFallback: false } buat skip.
3407
+ if (textFallback) {
3408
+ this._sections.push(AIRich.newLayout('Single', { text: '[ Sedang diproses... ]', __typename: 'FOATextPrimitive' }));
3409
+ }
3304
3410
  return this;
3305
3411
  }
3306
3412
 
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Type declarations for lib/Utils/MessageBuilder.js
3
+ * Hand-written (this file had no .d.ts before — not shipped by upstream
4
+ * either). Public chaining API only; internal/private members omitted.
5
+ */
6
+
7
+ export const MESSAGE_BUILDER_VERSION: string; // '4.7'
8
+
9
+ export abstract class BaseBuilder {
10
+ setTitle(title: string): this;
11
+ setSubtitle(subtitle: string): this;
12
+ setBody(body: string): this;
13
+ setFooter(footer: string): this;
14
+ setContextInfo(obj: Record<string, any>): this;
15
+ addPayload(obj: Record<string, any>): this;
16
+ }
17
+
18
+ export interface LimitedTimeOfferParams {
19
+ text?: string;
20
+ url?: string;
21
+ copy_code?: string;
22
+ expiration_time?: number;
23
+ }
24
+
25
+ export interface BottomSheetParams {
26
+ in_thread_buttons_limit?: number;
27
+ divider_indices?: number[];
28
+ list_title?: string;
29
+ button_title?: string;
30
+ }
31
+
32
+ export interface TapTargetConfigurationParams {
33
+ title?: string;
34
+ description?: string;
35
+ canonical_url?: string;
36
+ domain?: string;
37
+ buttonIndex?: number;
38
+ }
39
+
40
+ export class Button extends BaseBuilder {
41
+ constructor(client: any);
42
+ setVideo(path: string | Buffer, options?: Record<string, any>): this;
43
+ setImage(path: string | Buffer, options?: Record<string, any>): this;
44
+ setDocument(path: string | Buffer, options?: Record<string, any>): this;
45
+ setMedia(obj: Record<string, any>): this;
46
+ clearButtons(): this;
47
+ setParams(obj: Record<string, any>): this;
48
+ addButton(name: string, params: string | Record<string, any>): this;
49
+ makeRow(header?: string, title?: string, description?: string, id?: string): this;
50
+ makeSection(title?: string, highlight_label?: string): this;
51
+ addSelection(title: string, options?: Record<string, any>): this;
52
+ addReply(display_text: string, id: string, options?: Record<string, any>): this;
53
+ /** cta_call. Note (v4.7): keys on `phone_number`, not `id` — fixed from a prior version that silently mis-keyed this field. */
54
+ addCall(display_text: string, phone_number: string, options?: Record<string, any>): this;
55
+ addReminder(display_text: string, id: string, options?: Record<string, any>): this;
56
+ addCancelReminder(display_text: string, id: string, options?: Record<string, any>): this;
57
+ addAddress(display_text: string, id: string, options?: Record<string, any>): this;
58
+ addLocation(options?: Record<string, any>): this;
59
+ addUrl(display_text: string, url: string, webview_interaction?: boolean, options?: Record<string, any>): this;
60
+ addCopy(display_text: string, copy_code: string, options?: Record<string, any>): this;
61
+ /** open_webview — opens a titled in-app webview. */
62
+ addOpenWebview(title: string, url: string, options?: Record<string, any>): this;
63
+ /** cta_catalog — opens the sender's WhatsApp Business catalog. Business-account gated. */
64
+ addCatalog(display_text?: string, options?: Record<string, any>): this;
65
+ /** automated_greeting_message_view_catalog. Business-account gated. */
66
+ addViewCatalog(options?: Record<string, any>): this;
67
+ /** call_permission_request. */
68
+ addCallPermission(display_text?: string, options?: Record<string, any>): this;
69
+ /** payment_info — structured payment-settings payload (e.g. PIX). Payment-enabled accounts only. */
70
+ addPaymentInfo(payload?: Record<string, any>): this;
71
+ /** review_and_pay — order/payment summary flow. Server-validated by WhatsApp. */
72
+ addReviewAndPay(payload?: Record<string, any>): this;
73
+ /** wa_payment_transaction_details. */
74
+ addTransactionDetails(payload?: Record<string, any>): this;
75
+ /** mpm — multi-product message. Business-catalog accounts only. */
76
+ addMultiProduct(payload?: Record<string, any>): this;
77
+ setLimitedTimeOffer(params?: LimitedTimeOfferParams): this;
78
+ setBottomSheet(params?: BottomSheetParams): this;
79
+ setTapTargetConfiguration(params?: TapTargetConfigurationParams): this;
80
+ toCard(): Promise<Record<string, any>>;
81
+ build(jid: string, options?: Record<string, any>): Promise<Record<string, any>>;
82
+ send(jid: string, options?: Record<string, any>): Promise<any>;
83
+
84
+ /** Native-flow names WA renders with a dedicated node instead of the generic v=9 "mixed" node. */
85
+ static SPECIAL_FLOW: Record<string, { v: string; name: string }>;
86
+
87
+ // Presets attached at runtime via attachPresets() from MessageKit.js.
88
+ static confirm?: (client: any, text: string, options?: Record<string, any>) => Button;
89
+ static yesNo?: (client: any, text: string, options?: Record<string, any>) => Button;
90
+ static menu?: (client: any, options?: Record<string, any>) => Button;
91
+ }
92
+
93
+ export class ButtonV2 extends BaseBuilder {
94
+ constructor(client: any);
95
+ addButton(displayText: string, buttonId?: string): this;
96
+ addRawButton(obj: Record<string, any>): this;
97
+ setThumbnail(path: string | Buffer): this;
98
+ setMedia(obj: Record<string, any>): this;
99
+ /** @param options.viewOnce Default true — some clients require this for legacy buttonsMessage to render; pass false for a normal (non-disappearing) message. */
100
+ build(jid: string, options?: Record<string, any> & { viewOnce?: boolean }): Promise<Record<string, any>>;
101
+ send(jid: string, options?: Record<string, any> & { viewOnce?: boolean }): Promise<any>;
102
+ }
103
+
104
+ export class Carousel extends BaseBuilder {
105
+ constructor(client: any);
106
+ /** WhatsApp caps carousels at this many cards (10); addCard() throws past it. */
107
+ static MAX_CARDS: number;
108
+ addCard(card: Record<string, any> | Record<string, any>[]): this;
109
+ build(jid: string, options?: Record<string, any>): Record<string, any>;
110
+ send(jid: string, options?: Record<string, any>): Promise<any>;
111
+ }
112
+
113
+ export class Poll extends BaseBuilder {
114
+ constructor(client: any);
115
+ setName(name: string): this;
116
+ addOption(name: string): this;
117
+ addOptions(names: string[]): this;
118
+ setSelectable(count: number): this;
119
+ setMultiSelect(canSelectMultiple?: boolean): this;
120
+ setHideVoter(hide?: boolean): this;
121
+ setCanAddOption(allow?: boolean): this;
122
+ setAnnouncementGroup(isAnnouncement?: boolean): this;
123
+ setEndDate(date: Date | string | number): this;
124
+ /** Defers hash/version handling to the socket's own sendMessage({poll}) logic — see .js docblock. */
125
+ setQuiz(correctOptionName: string): this;
126
+ build(): { poll: Record<string, any> };
127
+ send(jid: string, options?: Record<string, any>): Promise<any>;
128
+ }
129
+
130
+ export interface AddTextOptions {
131
+ hyperlink?: boolean;
132
+ citation?: boolean;
133
+ latex?: boolean;
134
+ }
135
+
136
+ export interface AddInlineImageOptions {
137
+ text?: string;
138
+ alignment?: string;
139
+ tapLinkUrl?: string;
140
+ resolveUrl?: boolean;
141
+ }
142
+
143
+ export class AIRich extends BaseBuilder {
144
+ constructor(client: any);
145
+ addSubmessage(submessage: Record<string, any>): this;
146
+ addSection(section: Record<string, any>): this;
147
+ addText(text: string, options?: AddTextOptions): this;
148
+ addCode(language: string, code: string): this;
149
+ addTable(table: string[][], options?: AddTextOptions): this;
150
+ addSource(sources?: Record<string, any>[], options?: { resolveUrl?: boolean }): this;
151
+ addReels(reelsItems?: Record<string, any>[], options?: { resolveUrl?: boolean }): this;
152
+ addImage(imageUrl: string, options?: { resolveUrl?: boolean }): this;
153
+ addInlineImage(imageUrl: string, options?: AddInlineImageOptions): this;
154
+ addVideo(videoUrl: string, options?: { autoFill?: boolean; resolveUrl?: boolean }): this;
155
+ addProduct(data?: Record<string, any>, options?: { resolveUrl?: boolean }): this;
156
+ addPost(data?: Record<string, any>, options?: { resolveUrl?: boolean }): this;
157
+ addTip(text: string): this;
158
+ /** FOATextPrimitive — large heading text, distinct from addText()'s paragraph text. */
159
+ addHeading(text: string): this;
160
+ /** GenAIImagePrimitive — "ready" static image (preview + full-res), distinct from addImage()'s generation-style card. */
161
+ addImageCard(previewUrl: string | Buffer, fullUrl?: string | Buffer, options?: { resolveUrl?: boolean }): this;
162
+ /** GenAI3PExtWidgetPrimitive — experimental, reverse-engineered; see JSDoc in the .js file for caveats. */
163
+ addWidget(data: Record<string, any> | Record<string, any>[], options?: { layout?: 'Single' | 'HScroll' | 'ActionRow' | string }): this;
164
+ /** GenAIFooterActionPrimitive — footer action link chips (e.g. "Join our Group"). */
165
+ addFooterAction(actions: { text: string; url: string; type?: string } | { text: string; url: string; type?: string }[]): this;
166
+ /** GenAIDividerPrimitive — plain horizontal line, no content. */
167
+ addDivider(): this;
168
+ /** GenAISpacerPrimitive — blank vertical spacing. */
169
+ addSpacer(spacing?: number): this;
170
+ /** GenAILatexUXPrimitive — has a real AI_RICH_RESPONSE_LATEX submessage (unlike most primitives here). */
171
+ addLatex(expression: string): this;
172
+ /** GenAITaskPrimitive — task/checklist card. */
173
+ addTask(data: { task_id?: string; title: string; subtitle?: string; status?: string; textFallback?: boolean }): this;
174
+ /** GenAIBotProgressStatusPrimitive — one-shot "searching/working" status chip. */
175
+ addProgressStatus(title: string, options?: { icon?: string; is_in_progress?: boolean; target_secondary_screen_id?: string; target_secondary_screen_tab_id?: string }): this;
176
+ /** GenAIBotThinkingStatusPrimitive — one-shot "thinking" status chip. */
177
+ addThinkingStatus(title: string, options?: { icon?: string; is_in_progress?: boolean; target_secondary_screen_id?: string; target_secondary_screen_tab_id?: string; textFallback?: boolean }): this;
178
+ /** GenAIMetaSubsQuotaUpsellPrimitive — subscription-quota-limit upsell card. */
179
+ addQuotaUpsell(data: { title: string; body?: string; body_line1?: string; body_line2?: string; buttons?: { label: string; action?: string; deeplink?: string }[] }): this;
180
+ /** FOABloksPrimitive — raw Bloks payload; most experimental primitive, fields passed through as-is. */
181
+ addBloks(data: { type: string; data?: string; uuid?: string; initial_response?: any; versioning_id?: string; textFallback?: boolean }): this;
182
+ addSuggest(suggestion: Record<string, any>, options?: { scroll?: boolean; layout?: string }): this;
183
+ /** GenAIImaginePrimitive with status GENERATING — pending-generation placeholder, distinct from addImage()/addVideo()'s READY status. */
184
+ addGenerating(options?: { imagine_type?: 'IMAGE' | 'ANIMATE'; estimated_completion_time?: number; textFallback?: boolean }): this;
185
+ build(): Record<string, any>;
186
+ send(jid: string, options?: Record<string, any>): Promise<any>;
187
+
188
+ static tokenizer(code: string, lang?: string): Record<string, any>;
189
+ static toTableMetadata(arr: string[][], options?: AddTextOptions): Record<string, any>;
190
+ static newLayout(name: string, data: Record<string, any> | Record<string, any>[], extra?: Record<string, any>): Record<string, any>;
191
+ /** Send a support-ticket marker message (messageContextInfo.supportPayload). */
192
+ static sendSupportPayload(client: any, jid: string, text: string, options?: { ticketId?: string; isAiMessage?: boolean; shouldShowSystemMessage?: boolean; version?: number }): Promise<any>;
193
+ /** Send an image + video as one paired-media unit (messageAssociation). */
194
+ static sendPairedMedia(client: any, jid: string, media: { image: string | Buffer; video: string | Buffer }): Promise<any>;
195
+ }
196
+
197
+ // Same class as AIRich — exported under alternate names (see Vanz@Alias in
198
+ // MessageBuilder.js). All four are structurally identical to AIRich.
199
+ export { AIRich as AIVanzxy, AIRich as LeafRich, AIRich as VanzxyAI, AIRich as VanzxyRich };
200
+
201
+ export class Toolkit {
202
+ static extractIE(text: string, options?: AddTextOptions): Record<string, any>;
203
+ static getMp4Duration(buffer: Buffer, options?: { silent?: boolean }): Promise<number>;
204
+ static getMp4Preview(
205
+ videoBuffer: Buffer,
206
+ options?: { time?: number; result?: 'buffer' | string; resize?: boolean; width?: number; height?: number; silent?: boolean }
207
+ ): Promise<Buffer | Record<string, any>>;
208
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vanzxy/baileys",
3
- "version": "1.4.5",
3
+ "version": "1.4.7",
4
4
  "description": "Enhanced Baileys fork by Vanzxy — based on @itsliaaa/baileys + @whiskeysockets/baileys with fixes for audio group status and clean media without newsletter button.",
5
5
  "type": "module",
6
6
  "main": "./cjs/lib/index.js",