@pontalabs/baileys 1.0.11 → 1.1.0

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.
Files changed (119) hide show
  1. package/README.md +96 -85
  2. package/lib/Defaults/connection.js +39 -0
  3. package/lib/Defaults/constants.js +50 -0
  4. package/lib/Defaults/history.js +13 -0
  5. package/lib/Defaults/index.js +36 -151
  6. package/lib/Defaults/media.js +43 -0
  7. package/lib/Defaults/phonenumber-mcc.json +221 -221
  8. package/lib/Defaults/prefix.js +12 -0
  9. package/lib/Defaults/vialeys-version.json +7 -0
  10. package/lib/Signal/Group/ciphertext-message.js +10 -15
  11. package/lib/Signal/Group/group-session-builder.js +34 -60
  12. package/lib/Signal/Group/group_cipher.js +69 -76
  13. package/lib/Signal/Group/index.js +41 -60
  14. package/lib/Signal/Group/keyhelper.js +12 -57
  15. package/lib/Signal/Group/sender-chain-key.js +20 -33
  16. package/lib/Signal/Group/sender-key-distribution-message.js +43 -48
  17. package/lib/Signal/Group/sender-key-message.js +58 -53
  18. package/lib/Signal/Group/sender-key-name.js +21 -31
  19. package/lib/Signal/Group/sender-key-record.js +21 -34
  20. package/lib/Signal/Group/sender-key-state.js +59 -106
  21. package/lib/Signal/Group/sender-message-key.js +16 -21
  22. package/lib/Signal/libsignal.js +282 -203
  23. package/lib/Signal/lid-mapping.js +164 -184
  24. package/lib/Socket/Client/index.js +31 -22
  25. package/lib/Socket/Client/types.js +9 -15
  26. package/lib/Socket/Client/websocket.js +42 -37
  27. package/lib/Socket/business.js +212 -336
  28. package/lib/Socket/chats.js +696 -940
  29. package/lib/Socket/community.js +454 -369
  30. package/lib/Socket/groups.js +278 -280
  31. package/lib/Socket/index.js +9 -21
  32. package/lib/Socket/messages-recv.js +1027 -1570
  33. package/lib/Socket/messages-send.js +1180 -1136
  34. package/lib/Socket/mex.js +59 -0
  35. package/lib/Socket/newsletter.js +193 -251
  36. package/lib/Socket/socket.js +758 -898
  37. package/lib/Store/index.js +35 -24
  38. package/lib/Store/make-cache-manager-store.js +53 -66
  39. package/lib/Store/make-in-memory-store.js +319 -325
  40. package/lib/Store/make-ordered-dictionary.js +49 -57
  41. package/lib/Store/object-repository.js +10 -15
  42. package/lib/Types/Auth.js +2 -3
  43. package/lib/Types/Bussines.js +2 -3
  44. package/lib/Types/Call.js +2 -3
  45. package/lib/Types/Chat.js +10 -9
  46. package/lib/Types/Contact.js +2 -3
  47. package/lib/Types/Events.js +2 -3
  48. package/lib/Types/GroupMetadata.js +2 -3
  49. package/lib/Types/Label.js +6 -12
  50. package/lib/Types/LabelAssociation.js +4 -13
  51. package/lib/Types/Message.js +10 -18
  52. package/lib/Types/MexUpdates.js +15 -18
  53. package/lib/Types/Newsletter.js +26 -34
  54. package/lib/Types/Product.js +2 -3
  55. package/lib/Types/Signal.js +2 -3
  56. package/lib/Types/Socket.js +2 -3
  57. package/lib/Types/State.js +8 -13
  58. package/lib/Types/USync.js +2 -3
  59. package/lib/Types/index.js +49 -40
  60. package/lib/Utils/auth-utils.js +190 -495
  61. package/lib/Utils/browser-utils.js +29 -0
  62. package/lib/Utils/business.js +177 -199
  63. package/lib/Utils/chat-utils.js +711 -624
  64. package/lib/Utils/crypto.js +116 -161
  65. package/lib/Utils/decode-wa-message.js +225 -321
  66. package/lib/Utils/event-buffer.js +363 -405
  67. package/lib/Utils/generics.js +318 -472
  68. package/lib/Utils/history.js +72 -76
  69. package/lib/Utils/index.js +49 -41
  70. package/lib/Utils/link-preview.js +59 -103
  71. package/lib/Utils/logger.js +4 -7
  72. package/lib/Utils/lt-hash.js +29 -42
  73. package/lib/Utils/make-mutex.js +26 -42
  74. package/lib/Utils/message-retry-manager.js +134 -160
  75. package/lib/Utils/messages-media.js +665 -731
  76. package/lib/Utils/messages.js +518 -1
  77. package/lib/Utils/noise-handler.js +127 -125
  78. package/lib/Utils/pre-key-manager.js +86 -0
  79. package/lib/Utils/process-message.js +739 -351
  80. package/lib/Utils/signal.js +146 -129
  81. package/lib/Utils/use-multi-file-auth-state.js +68 -135
  82. package/lib/Utils/validate-connection.js +183 -142
  83. package/lib/Utils/vialeys-event-stream.js +41 -0
  84. package/lib/WABinary/constants.js +1281 -1289
  85. package/lib/WABinary/decode.js +145 -200
  86. package/lib/WABinary/encode.js +149 -202
  87. package/lib/WABinary/generic-utils.js +79 -97
  88. package/lib/WABinary/index.js +36 -25
  89. package/lib/WABinary/jid-utils.js +91 -123
  90. package/lib/WABinary/types.js +2 -3
  91. package/lib/WAM/BinaryInfo.js +8 -13
  92. package/lib/WAM/constants.js +16584 -11464
  93. package/lib/WAM/encode.js +117 -133
  94. package/lib/WAM/index.js +34 -23
  95. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +62 -69
  96. package/lib/WAUSync/Protocols/USyncContactProtocol.js +11 -25
  97. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +32 -44
  98. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +13 -23
  99. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +24 -38
  100. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +17 -31
  101. package/lib/WAUSync/Protocols/index.js +37 -26
  102. package/lib/WAUSync/USyncQuery.js +66 -66
  103. package/lib/WAUSync/USyncUser.js +13 -18
  104. package/lib/WAUSync/index.js +34 -23
  105. package/lib/index.js +95 -28
  106. package/package.json +2 -1
  107. package/lib/Defaults/baileys-version.json +0 -3
  108. package/lib/Signal/Group/queue-job.d.ts +0 -1
  109. package/lib/Signal/Group/queue-job.js +0 -57
  110. package/lib/Socket/usync.d.ts +0 -37
  111. package/lib/Socket/usync.js +0 -83
  112. package/lib/Utils/baileys-event-stream.d.ts +0 -18
  113. package/lib/Utils/baileys-event-stream.js +0 -70
  114. package/lib/Utils/signal-housekeeping.d.ts +0 -19
  115. package/lib/Utils/signal-housekeeping.js +0 -73
  116. package/lib/Utils/use-mongo-file-auth-state.d.ts +0 -6
  117. package/lib/Utils/use-mongo-file-auth-state.js +0 -84
  118. package/lib/Utils/use-single-file-auth-state.d.ts +0 -13
  119. package/lib/Utils/use-single-file-auth-state.js +0 -80
@@ -16,6 +16,48 @@ const generics_1 = require("./generics")
16
16
  const messages_media_1 = require("./messages-media")
17
17
  const rich_message_utils_1 = require("./rich-message-utils")
18
18
 
19
+ // --- shim kompatibilitas tambahan dari @pontalabs 1.1.9 (untuk richMessage/buttonsMessage) ---
20
+ const Jimp = require("jimp")
21
+ const { proto } = WAProto_1
22
+ const { getStream, toBuffer } = messages_media_1
23
+ const { promises } = fs_1
24
+ const hasNonNullishProperty = (message, key) =>
25
+ typeof message === "object" &&
26
+ message !== null &&
27
+ key in message &&
28
+ message[key] !== null &&
29
+ message[key] !== undefined
30
+ async function processLocationThumbnail(input, options = {}) {
31
+ const {
32
+ maxWidth = 300,
33
+ maxHeight = 300,
34
+ quality = 80
35
+ } = options
36
+
37
+ let buffer
38
+
39
+ if (
40
+ typeof input === "string" &&
41
+ (input.startsWith("http://") || input.startsWith("https://"))
42
+ ) {
43
+ const { stream } = await getStream({ url: input })
44
+ buffer = await toBuffer(stream)
45
+ } else if (typeof input === "string") {
46
+ buffer = await promises.readFile(input)
47
+ } else if (Buffer.isBuffer(input)) {
48
+ buffer = input
49
+ } else {
50
+ throw new Error("thumbnail must be URL, path or Buffer")
51
+ }
52
+
53
+ const image = await Jimp.read(buffer)
54
+
55
+ image.scaleToFit(maxWidth, maxHeight)
56
+
57
+ return await image.quality(quality).getBufferAsync(Jimp.MIME_JPEG)
58
+ }
59
+ // --- akhir shim ---
60
+
19
61
  const MIMETYPE_MAP = {
20
62
  image: 'image/jpeg',
21
63
  video: 'video/mp4',
@@ -1434,6 +1476,450 @@ const generateWAMessageContent = async (message, options) => {
1434
1476
  m = {
1435
1477
  interactiveMessage
1436
1478
  }
1479
+ } else if (hasNonNullishProperty(message, "buttonsMessage")) {
1480
+ const btnMsg = { ...message.buttonsMessage };
1481
+ if (btnMsg.locationMessage?.jpegThumbnail && !Buffer.isBuffer(btnMsg.locationMessage.jpegThumbnail)) {
1482
+ btnMsg.locationMessage.jpegThumbnail = await processLocationThumbnail(btnMsg.locationMessage.jpegThumbnail);
1483
+ }
1484
+ m = { buttonsMessage: btnMsg };
1485
+ } else if (hasNonNullishProperty(message, "richMessage")) {
1486
+ const { randomUUID } = require('crypto');
1487
+ const rich = message.richMessage;
1488
+ const submessages = [];
1489
+ const sections = [];
1490
+ const richResponseSources = [];
1491
+
1492
+ const extractIE = (text) => {
1493
+ let ie = [], result = '', last = 0, citation_index = 1, hyperlink_index = 0, latex_index = 0, stack = [];
1494
+ for (let i = 0; i < text.length; i++) {
1495
+ if (text[i] == '[' && text[i - 1] != '\\') {
1496
+ stack.push(i);
1497
+ } else if (text[i] == ']' && (text[i + 1] == '(' || text[i + 1] == '<')) {
1498
+ let start = stack.pop();
1499
+ if (start == null) continue;
1500
+ let open = text[i + 1], close = open == '(' ? ')' : '>', type = open == '(' ? 'link' : 'latex', end = i + 2, depth = 1;
1501
+ while (end < text.length && depth) {
1502
+ if (text[end] == open && text[end - 1] != '\\') depth++;
1503
+ else if (text[end] == close && text[end - 1] != '\\') depth--;
1504
+ end++;
1505
+ }
1506
+ if (depth) continue;
1507
+ let raw = text.slice(start + 1, i).trim(), url = text.slice(i + 2, end - 1).trim(), key, tag, data;
1508
+ if (type == 'latex') {
1509
+ let [txt = '', width = null, height = null, font_height = null, padding = null] = raw.split('|');
1510
+ key = `LATEX_${latex_index++}`;
1511
+ tag = `{{${key}}}${txt || 'image'}{{/${key}}}`;
1512
+ data = { type: 'latex', ie: { key, text: txt, url, width, height, font_height, padding } };
1513
+ } else if (raw) {
1514
+ key = `HLINK_${hyperlink_index++}`;
1515
+ tag = `{{${key}}}${url}{{/${key}}}`;
1516
+ data = { type: 'hyperlink', ie: { key, text: raw, url } };
1517
+ } else {
1518
+ key = `CITE_${citation_index - 1}`;
1519
+ tag = `{{${key}}}${url}{{/${key}}}`;
1520
+ data = { type: 'citation', ie: { reference_id: citation_index++, key, text: '', url } };
1521
+ }
1522
+ result += text.slice(last, start) + tag;
1523
+ last = end;
1524
+ ie.push(data);
1525
+ i = end - 1;
1526
+ }
1527
+ }
1528
+ result += text.slice(last);
1529
+ return { text: result, ie };
1530
+ };
1531
+
1532
+ const tokenizer = (code, lang = 'javascript') => {
1533
+ const keywordsMap = {
1534
+ javascript: new Set(['break','case','catch','continue','debugger','delete','do','else','finally','for','function','if','in','instanceof','new','return','switch','this','throw','try','typeof','var','void','while','with','true','false','null','undefined','class','const','let','super','extends','export','import','yield','static','constructor','async','await','get','set'])
1535
+ };
1536
+ const TYPE_MAP = { 0:'DEFAULT', 1:'KEYWORD', 2:'METHOD', 3:'STR', 4:'NUMBER', 5:'COMMENT' };
1537
+ const keywords = keywordsMap[lang] || new Set();
1538
+ const tokens = [];
1539
+ let i = 0;
1540
+ const push = (content, type) => {
1541
+ if (!content) return;
1542
+ const last = tokens[tokens.length - 1];
1543
+ if (last && last.highlightType === type) last.codeContent += content;
1544
+ else tokens.push({ codeContent: content, highlightType: type });
1545
+ };
1546
+ while (i < code.length) {
1547
+ const c = code[i];
1548
+ if (/\s/.test(c)) { let s = i; while (i < code.length && /\s/.test(code[i])) i++; push(code.slice(s, i), 0); continue; }
1549
+ if (c === '/' && code[i + 1] === '/') { let s = i; i += 2; while (i < code.length && code[i] !== '\n') i++; push(code.slice(s, i), 5); continue; }
1550
+ if (c === '"' || c === "'" || c === '`') { let s = i; const q = c; i++; while (i < code.length) { if (code[i] === '\\' && i + 1 < code.length) i += 2; else if (code[i] === q) { i++; break; } else i++; } push(code.slice(s, i), 3); continue; }
1551
+ if (/[0-9]/.test(c)) { let s = i; while (i < code.length && /[0-9.]/.test(code[i])) i++; push(code.slice(s, i), 4); continue; }
1552
+ if (/[a-zA-Z_$]/.test(c)) { let s = i; while (i < code.length && /[a-zA-Z0-9_$]/.test(code[i])) i++; const word = code.slice(s, i); let type = 0; if (keywords.has(word)) type = 1; else { let j = i; while (j < code.length && /\s/.test(code[j])) j++; if (code[j] === '(') type = 2; } push(word, type); continue; }
1553
+ push(c, 0); i++;
1554
+ }
1555
+ return { codeBlock: tokens, unified_codeBlock: tokens.map(t => ({ content: t.codeContent, type: TYPE_MAP[t.highlightType] })) };
1556
+ };
1557
+
1558
+ const toTableMetadata = (arr) => {
1559
+ const [header, ...rows] = arr;
1560
+ const maxLen = Math.max(header.length, ...rows.map(r => r.length));
1561
+ const normalize = (r) => [...r, ...Array(maxLen - r.length).fill('')];
1562
+ const unified_rows = [{ is_header: true, cells: normalize(header) }, ...rows.map(r => ({ is_header: false, cells: normalize(r) }))];
1563
+ const rowsMeta = unified_rows.map(r => ({ items: r.cells, ...(r.is_header ? { isHeading: true } : {}) }));
1564
+ return { title: '', rows: rowsMeta, unified_rows };
1565
+ };
1566
+
1567
+ if (rich.text) {
1568
+ const parsed = typeof rich.text === 'string' ? extractIE(rich.text) : rich.text;
1569
+ const text = parsed.text || parsed;
1570
+ const inline_entities = parsed.ie ? parsed.ie.map(({ type, ie }) => {
1571
+ if (type === 'hyperlink') return { key: ie.key, metadata: { display_name: ie.text, is_trusted: true, url: ie.url, __typename: 'GenAIInlineLinkItem' } };
1572
+ if (type === 'citation') return { key: ie.key, metadata: { reference_id: ie.reference_id, reference_url: ie.url, reference_title: ie.url, reference_display_name: ie.url, sources: [], __typename: 'GenAISearchCitationItem' } };
1573
+ if (type === 'latex') return { key: ie.key, metadata: { latex_expression: ie.text || '', latex_image: { url: ie.url, width: Number(ie.width) || 100, height: Number(ie.height) || 100 }, font_height: Number(ie.font_height) || 83.33, padding: Number(ie.padding) || 15, __typename: 'GenAILatexItem' } };
1574
+ return null;
1575
+ }).filter(Boolean) : [];
1576
+ submessages.push({ messageType: 2, messageText: text });
1577
+ sections.push({
1578
+ view_model: {
1579
+ primitive: { text, inline_entities, __typename: 'GenAIMarkdownTextUXPrimitive' },
1580
+ __typename: 'GenAISingleLayoutViewModel'
1581
+ }
1582
+ });
1583
+ }
1584
+
1585
+ if (rich.code) {
1586
+ const { language, code } = rich.code;
1587
+ const tok = tokenizer(code, language);
1588
+ submessages.push({ messageType: 5, codeMetadata: { codeLanguage: language, codeBlocks: tok.codeBlock } });
1589
+ sections.push({
1590
+ view_model: {
1591
+ primitive: { language, code_blocks: tok.unified_codeBlock, __typename: 'GenAICodeUXPrimitive' },
1592
+ __typename: 'GenAISingleLayoutViewModel'
1593
+ }
1594
+ });
1595
+ }
1596
+
1597
+ if (rich.table) {
1598
+ const meta = toTableMetadata(rich.table);
1599
+ submessages.push({ messageType: 4, tableMetadata: { title: meta.title, rows: meta.rows } });
1600
+ sections.push({
1601
+ view_model: {
1602
+ primitive: { rows: meta.unified_rows, __typename: 'GenATableUXPrimitive' },
1603
+ __typename: 'GenAISingleLayoutViewModel'
1604
+ }
1605
+ });
1606
+ }
1607
+
1608
+ if (rich.images) {
1609
+ const urls = Array.isArray(rich.images) ? rich.images : [rich.images];
1610
+ submessages.push({
1611
+ messageType: 1,
1612
+ gridImageMetadata: {
1613
+ gridImageUrl: { imagePreviewUrl: urls[0] },
1614
+ imageUrls: urls.map(url => ({ imagePreviewUrl: url, imageHighResUrl: url, sourceUrl: 'https://www.levvicode.cloud/' }))
1615
+ }
1616
+ });
1617
+ urls.forEach(url => {
1618
+ sections.push({
1619
+ view_model: {
1620
+ primitive: { media: { url, mime_type: 'image/jpeg' }, imagine_type: 3, status: { status: 'READY' }, __typename: 'GenAIImaginePrimitive' },
1621
+ __typename: 'GenAISingleLayoutViewModel'
1622
+ }
1623
+ });
1624
+ });
1625
+ }
1626
+
1627
+ if (rich.video) {
1628
+ submessages.push({ messageType: 2, messageText: '[ CANNOT_LOAD_VIDEO - Ponta ]' });
1629
+ sections.push({
1630
+ view_model: {
1631
+ primitive: {
1632
+ media: { url: rich.video, mime_type: 'video/mp4', duration: 10 },
1633
+ imagine_type: 'ANIMATE',
1634
+ status: { status: 'READY' },
1635
+ __typename: 'GenAIImaginePrimitive'
1636
+ },
1637
+ __typename: 'GenAISingleLayoutViewModel'
1638
+ }
1639
+ });
1640
+ }
1641
+
1642
+ if (rich.productSingle) {
1643
+ submessages.push({ messageType: 2, messageText: '[ CANNOT_LOAD_PRODUCT - Ponta ]' });
1644
+ sections.push({
1645
+ view_model: {
1646
+ primitive: { ...rich.productSingle, __typename: 'GenAIProductItemCardPrimitive' },
1647
+ __typename: 'GenAISingleLayoutViewModel'
1648
+ }
1649
+ });
1650
+ }
1651
+
1652
+ if (rich.productMultiple) {
1653
+ submessages.push({ messageType: 2, messageText: '[ CANNOT_LOAD_PRODUCT - Ponta ]' });
1654
+ sections.push({
1655
+ view_model: {
1656
+ primitives: rich.productMultiple.map(p => ({ ...p, __typename: 'GenAIProductItemCardPrimitive' })),
1657
+ __typename: 'GenAIHScrollLayoutViewModel'
1658
+ }
1659
+ });
1660
+ }
1661
+
1662
+ if (rich.product && !rich.productSingle && !rich.productMultiple) {
1663
+ submessages.push({ messageType: 2, messageText: '[ CANNOT_LOAD_PRODUCT - Ponta ]' });
1664
+ if (Array.isArray(rich.product)) {
1665
+ sections.push({
1666
+ view_model: {
1667
+ primitives: rich.product.map(p => ({ ...p, __typename: 'GenAIProductItemCardPrimitive' })),
1668
+ __typename: 'GenAIHScrollLayoutViewModel'
1669
+ }
1670
+ });
1671
+ } else {
1672
+ sections.push({
1673
+ view_model: {
1674
+ primitive: { ...rich.product, __typename: 'GenAIProductItemCardPrimitive' },
1675
+ __typename: 'GenAISingleLayoutViewModel'
1676
+ }
1677
+ });
1678
+ }
1679
+ }
1680
+
1681
+ if (rich.post) {
1682
+ submessages.push({ messageType: 2, messageText: '[ CANNOT_LOAD_POST - Ponta ]' });
1683
+ if (Array.isArray(rich.post)) {
1684
+ sections.push({
1685
+ view_model: {
1686
+ primitives: rich.post.map(p => ({ ...p, __typename: 'GenAIPostPrimitive' })),
1687
+ __typename: 'GenAIHScrollLayoutViewModel'
1688
+ }
1689
+ });
1690
+ } else {
1691
+ sections.push({
1692
+ view_model: {
1693
+ primitive: { ...rich.post, __typename: 'GenAIPostPrimitive' },
1694
+ __typename: 'GenAISingleLayoutViewModel'
1695
+ }
1696
+ });
1697
+ }
1698
+ }
1699
+
1700
+ if (rich.reels) {
1701
+ const items = Array.isArray(rich.reels) ? rich.reels : [rich.reels];
1702
+ submessages.push({
1703
+ messageType: 9,
1704
+ contentItemsMetadata: {
1705
+ contentType: 1,
1706
+ itemsMetadata: items.map(i => ({
1707
+ reelItem: { title: i.title, profileIconUrl: i.profileIconUrl, thumbnailUrl: i.thumbnailUrl, videoUrl: i.videoUrl }
1708
+ }))
1709
+ }
1710
+ });
1711
+ sections.push({
1712
+ view_model: {
1713
+ primitives: items.map(i => ({
1714
+ reels_url: i.videoUrl,
1715
+ thumbnail_url: i.thumbnailUrl,
1716
+ creator: i.title,
1717
+ avatar_url: i.profileIconUrl,
1718
+ reels_title: i.reels_title || '',
1719
+ likes_count: i.likes_count || 0,
1720
+ shares_count: i.shares_count || 0,
1721
+ view_count: i.view_count || 0,
1722
+ reel_source: i.reel_source || 'IG',
1723
+ is_verified: i.is_verified || false,
1724
+ __typename: 'GenAIReelPrimitive'
1725
+ })),
1726
+ __typename: 'GenAIHScrollLayoutViewModel'
1727
+ }
1728
+ });
1729
+ items.forEach((i, idx) => richResponseSources.push({
1730
+ provider: 'Ponta',
1731
+ thumbnailCDNURL: i.thumbnailUrl,
1732
+ sourceProviderURL: i.videoUrl,
1733
+ sourceQuery: '',
1734
+ faviconCDNURL: i.profileIconUrl,
1735
+ citationNumber: idx + 1,
1736
+ sourceTitle: i.title
1737
+ }));
1738
+ }
1739
+
1740
+ if (rich.sources) {
1741
+ const sourceArr = Array.isArray(rich.sources) ? rich.sources : [rich.sources];
1742
+ sections.push({
1743
+ view_model: {
1744
+ primitive: {
1745
+ sources: sourceArr.map(s => typeof s === 'object' ? s : {
1746
+ source_type: 'THIRD_PARTY',
1747
+ source_display_name: s[2] || '',
1748
+ source_subtitle: 'AI',
1749
+ source_url: s[1] || '',
1750
+ favicon: { url: s[0] || '', mime_type: 'image/jpeg', width: 16, height: 16 }
1751
+ }),
1752
+ __typename: 'GenAISearchResultPrimitive'
1753
+ },
1754
+ __typename: 'GenAISingleLayoutViewModel'
1755
+ }
1756
+ });
1757
+ }
1758
+
1759
+ if (rich.tip) {
1760
+ submessages.push({ messageType: 2, messageText: rich.tip });
1761
+ sections.push({
1762
+ view_model: {
1763
+ primitive: { text: rich.tip, __typename: 'GenAIMetadataTextPrimitive' },
1764
+ __typename: 'GenAISingleLayoutViewModel'
1765
+ }
1766
+ });
1767
+ }
1768
+
1769
+ if (rich.suggestions) {
1770
+ sections.push({
1771
+ view_model: {
1772
+ primitives: rich.suggestions.map(s => ({
1773
+ prompt_text: s,
1774
+ prompt_type: 'SUGGESTED_PROMPT',
1775
+ __typename: 'GenAIFollowUpSuggestionPillPrimitive'
1776
+ })),
1777
+ __typename: 'GenAIActionRowLayoutViewModel'
1778
+ }
1779
+ });
1780
+ }
1781
+
1782
+ if (rich.footer) {
1783
+ sections.push({
1784
+ view_model: {
1785
+ primitive: { text: rich.footer, __typename: 'GenAIMetadataTextPrimitive' },
1786
+ __typename: 'GenAISingleLayoutViewModel'
1787
+ }
1788
+ });
1789
+ }
1790
+
1791
+ const unifiedData = { response_id: randomUUID(), sections };
1792
+
1793
+ m = {
1794
+ messageContextInfo: {
1795
+ deviceListMetadata: {},
1796
+ deviceListMetadataVersion: 2,
1797
+ botMetadata: {
1798
+ messageDisclaimerText: rich.title || '',
1799
+ richResponseSourcesMetadata: { sources: richResponseSources }
1800
+ }
1801
+ },
1802
+ botForwardedMessage: {
1803
+ message: {
1804
+ richResponseMessage: {
1805
+ messageType: 1,
1806
+ submessages,
1807
+ unifiedResponse: {
1808
+ data: Buffer.from(JSON.stringify(unifiedData)).toString('base64')
1809
+ },
1810
+ contextInfo: {
1811
+ forwardingScore: 1,
1812
+ isForwarded: true,
1813
+ forwardedAiBotMessageInfo: { botJid: '0@bot' },
1814
+ forwardOrigin: 4
1815
+ }
1816
+ }
1817
+ }
1818
+ }
1819
+ };
1820
+ }
1821
+
1822
+
1823
+
1824
+ else {
1825
+ m = await prepareWAMessageMedia(message, options);
1826
+ }
1827
+
1828
+ if (hasNonNullishProperty(message, "buttonReply")) {
1829
+ switch (message.type) {
1830
+ case "list":
1831
+ m.listResponseMessage = {
1832
+ title: message.buttonReply.title,
1833
+ description: message.buttonReply.description,
1834
+ singleSelectReply: { selectedRowId: message.buttonReply.rowId },
1835
+ lisType: proto.Message.ListResponseMessage.ListType.SINGLE_SELECT,
1836
+ };
1837
+ break;
1838
+ case "template":
1839
+ m.templateButtonReplyMessage = {
1840
+ selectedDisplayText: message.buttonReply.displayText,
1841
+ selectedId: message.buttonReply.id,
1842
+ selectedIndex: message.buttonReply.index,
1843
+ };
1844
+ break;
1845
+ case "plain":
1846
+ m.buttonsResponseMessage = {
1847
+ selectedButtonId: message.buttonReply.id,
1848
+ selectedDisplayText: message.buttonReply.displayText,
1849
+ type: proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT,
1850
+ };
1851
+ break;
1852
+ case "interactive":
1853
+ m.interactiveResponseMessage = {
1854
+ body: {
1855
+ text: message.buttonReply.displayText,
1856
+ format: proto.Message.InteractiveResponseMessage.Body.Format.EXTENSIONS_1,
1857
+ },
1858
+ nativeFlowResponseMessage: {
1859
+ name: message.buttonReply.nativeFlows.name,
1860
+ paramsJson: message.buttonReply.nativeFlows.paramsJson,
1861
+ version: message.buttonReply.nativeFlows.version,
1862
+ },
1863
+ };
1864
+ break;
1865
+ }
1866
+ } else if (hasNonNullishProperty(message, "templateButtons")) {
1867
+ const hydratedTemplate = { hydratedButtons: message.templateButtons };
1868
+ if (hasNonNullishProperty(message, "text")) {
1869
+ hydratedTemplate.hydratedContentText = message.text;
1870
+ } else {
1871
+ if (hasNonNullishProperty(message, "caption")) {
1872
+ hydratedTemplate.hydratedContentText = message.caption;
1873
+ }
1874
+ Object.assign(msg, m);
1875
+ }
1876
+ if (hasNonNullishProperty(message, "footer")) {
1877
+ hydratedTemplate.hydratedFooterText = message.footer;
1878
+ }
1879
+ m = { templateMessage: { hydratedTemplate: hydratedTemplate } };
1880
+ } else if (hasNonNullishProperty(message, "interactiveButtons")) {
1881
+ const interactiveMessage = {
1882
+ nativeFlowMessage: { buttons: message.interactiveButtons },
1883
+ };
1884
+ if (hasNonNullishProperty(message, "text")) {
1885
+ interactiveMessage.body = { text: message.text };
1886
+ }
1887
+ if (hasNonNullishProperty(message, "title")) {
1888
+ interactiveMessage.header = {
1889
+ title: message.title,
1890
+ subtitle: null,
1891
+ hasMediaAttachment: false,
1892
+ };
1893
+ if (hasNonNullishProperty(message, "subtitle")) {
1894
+ interactiveMessage.header.subtitle = message.subtitle;
1895
+ }
1896
+ } else {
1897
+ if (hasNonNullishProperty(message, "caption")) {
1898
+ interactiveMessage.body = { text: message.caption };
1899
+ interactiveMessage.header = {
1900
+ title: null,
1901
+ subtitle: null,
1902
+ hasMediaAttachment: false,
1903
+ ...Object.assign(interactiveMessage, m),
1904
+ };
1905
+ if (hasNonNullishProperty(message, "title")) {
1906
+ interactiveMessage.header.title = message.title;
1907
+ }
1908
+ if (hasNonNullishProperty(message, "subtitle")) {
1909
+ interactiveMessage.header.subtitle = message.subtitle;
1910
+ }
1911
+ if (hasNonNullishProperty(message, "hasMediaAttachment")) {
1912
+ interactiveMessage.header.hasMediaAttachment = Boolean(
1913
+ message.hasMediaAttachment
1914
+ );
1915
+ }
1916
+ }
1917
+ }
1918
+ if (hasNonNullishProperty(message, "footer")) {
1919
+ interactiveMessage.footer = { text: message.footer };
1920
+ }
1921
+ m = { interactiveMessage: interactiveMessage };
1922
+ } else if (hasNonNullishProperty(message, "shop")) {
1437
1923
  }
1438
1924
 
1439
1925
  if ('ephemeral' in message && !!message.ephemeral) {
@@ -1735,6 +2221,34 @@ function getAggregateVotesInPollMessage({
1735
2221
  return Object.values(voteHashMap)
1736
2222
  }
1737
2223
 
2224
+ // --- tambahan dari @pontalabs 1.1.9: dukungan Event RSVP response ---
2225
+ const updateMessageWithEventResponse = (msg, update) => {
2226
+ const authorID = generics_1.getKeyAuthor(update.eventResponseMessageKey)
2227
+ const responses = (msg.eventResponses || []).filter(
2228
+ (r) => generics_1.getKeyAuthor(r.eventResponseMessageKey) !== authorID
2229
+ )
2230
+ responses.push(update)
2231
+ msg.eventResponses = responses
2232
+ }
2233
+ function getAggregateResponsesInEventMessage({ eventResponses }, meLid) {
2234
+ const responseTypes = ["GOING", "NOT_GOING", "MAYBE"]
2235
+ const responseMap = {}
2236
+ for (const type of responseTypes) {
2237
+ responseMap[type] = { response: type, responders: [] }
2238
+ }
2239
+ for (const update of eventResponses) {
2240
+ const { response } = update.response || 0
2241
+ const responseType = proto.Message.EventResponseMessage.EventResponseType[response]
2242
+ if (responseType !== "UNKNOWN" && responseMap[responseType]) {
2243
+ responseMap[responseType].responders.push(
2244
+ generics_1.getKeyAuthor(update.eventResponseMessageKey, meLid)
2245
+ )
2246
+ }
2247
+ }
2248
+ return Object.values(responseMap)
2249
+ }
2250
+ // --- akhir tambahan ---
2251
+
1738
2252
  const aggregateMessageKeysNotFromMe = (keys) => {
1739
2253
  const keyMap = {}
1740
2254
 
@@ -1867,9 +2381,12 @@ module.exports = {
1867
2381
  updateMessageWithReceipt,
1868
2382
  updateMessageWithReaction,
1869
2383
  updateMessageWithPollUpdate,
2384
+ updateMessageWithEventResponse,
1870
2385
  getAggregateVotesInPollMessage,
2386
+ getAggregateResponsesInEventMessage,
1871
2387
  aggregateMessageKeysNotFromMe,
1872
2388
  downloadMediaMessage,
1873
2389
  assertMediaContent,
1874
- patchMessageForMdIfRequired
2390
+ patchMessageForMdIfRequired,
2391
+ hasNonNullishProperty
1875
2392
  }