@itsliaaa/baileys 0.1.18 โ 0.1.20
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.
- package/README.md +107 -9
- package/lib/Defaults/index.js +7 -0
- package/lib/Store/make-in-memory-store.js +1 -2
- package/lib/Types/RichType.js +22 -0
- package/lib/Utils/index.js +1 -0
- package/lib/Utils/messages.js +84 -81
- package/lib/Utils/rich-message-utils.js +274 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,35 @@
|
|
|
1
1
|
# ๐ฑ @itsliaaa/baileys
|
|
2
2
|
|
|
3
|
-

|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@itsliaaa/baileys)
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
A lightweight fork of Baileys with practical fixes and small but meaningful improvements.
|
|
7
|
+
<br><br>
|
|
8
|
+
<a href="https://www.npmjs.com/package/@itsliaaa/baileys">
|
|
9
|
+
<img src="https://img.shields.io/npm/v/@itsliaaa/baileys?color=FFFFFF&labelColor=red&logo=npm&logoColor=white&style=for-the-badge"/>
|
|
10
|
+
</a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/@itsliaaa/baileys">
|
|
12
|
+
<img src="https://img.shields.io/npm/dm/@itsliaaa/baileys?color=FFFFFF&labelColor=red&logo=npm&logoColor=white&style=for-the-badge"/>
|
|
13
|
+
</a>
|
|
14
|
+
<a href="https://github.com/itsliaaa/baileys">
|
|
15
|
+
<img src="https://img.shields.io/github/stars/itsliaaa/baileys?color=FFFFFF&labelColor=black&logo=github&logoColor=white&style=for-the-badge"/>
|
|
16
|
+
</a>
|
|
17
|
+
<a href="LICENSE">
|
|
18
|
+
<img src="https://img.shields.io/badge/license-MIT-blue?labelColor=black&style=for-the-badge"/>
|
|
19
|
+
</a>
|
|
20
|
+
<a href="https://nodejs.org">
|
|
21
|
+
<img src="https://img.shields.io/badge/node-%3E%3D20-339933?logo=node.js&labelColor=green&logoColor=white&style=for-the-badge"/>
|
|
22
|
+
</a>
|
|
23
|
+
<a href="#">
|
|
24
|
+
<img src="https://img.shields.io/badge/ESM-only?logo=javascript&labelColor=yellow&logoColor=black&style=for-the-badge"/>
|
|
25
|
+
</a>
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
โ For donation: [Saweria](https://saweria.co/itsliaaa)
|
|
6
29
|
|
|
7
30
|
### โจ Highlights
|
|
8
31
|
|
|
9
|
-
This fork
|
|
32
|
+
This fork designed for production use with a focus on clarity and safety:
|
|
10
33
|
|
|
11
34
|
- ๐ซ No obfuscation. Easy to read and audit.
|
|
12
35
|
- ๐ซ No auto-follow channel (newsletter) behavior.
|
|
@@ -20,9 +43,17 @@ This fork focuses on clarity and safety:
|
|
|
20
43
|
- ๐๏ธ Added [`@napi-rs/image`](https://www.npmjs.com/package/@napi-rs/image) as a supported image processing backend in [`getImageProcessingLibrary()`](#%EF%B8%8F-image-processing), offering a balance between performance and compatibility.
|
|
21
44
|
|
|
22
45
|
#### ๐จ Message Handling & Compatibility
|
|
23
|
-
- ๐๐ป Added support for sending [interactive
|
|
24
|
-
- ๐ฉ
|
|
25
|
-
-
|
|
46
|
+
- ๐๐ป Added support for sending [interactive messages](#-sending-interactive-messages) (buttons, lists, interactive, templates, carousel).
|
|
47
|
+
- ๐ฉ Expanded message support for:
|
|
48
|
+
- [album messages](#%EF%B8%8F-album-image--video)
|
|
49
|
+
- [group status messages](#4%EF%B8%8Fโฃ-group-status)
|
|
50
|
+
- [status mention messages](#%EF%B8%8F-status-mention)
|
|
51
|
+
- [sticker pack messages](#-sticker-pack)
|
|
52
|
+
- [rich response messages](#-rich-response)
|
|
53
|
+
- [messages with code blocks](#-message-with-code-block)
|
|
54
|
+
- [messages with tables](#-message-with-table)
|
|
55
|
+
- [payment-related messages](#-sending-payment-messages) (payment requests, invites, orders, invoices).
|
|
56
|
+
- ๐ฐ Simplified sending messages with ad thumbnails using [`externalAdReply`](#3%EF%B8%8Fโฃ-external-ad-reply), without requiring manual `contextInfo`.
|
|
26
57
|
|
|
27
58
|
#### ๐งฉ Additional Message Options
|
|
28
59
|
- ๐๏ธ Added optional boolean flags for message handling:
|
|
@@ -286,7 +317,7 @@ const vcard = 'BEGIN:VCARD\n'
|
|
|
286
317
|
|
|
287
318
|
sock.sendMessage(jid, {
|
|
288
319
|
contacts: {
|
|
289
|
-
displayName: 'Lia',
|
|
320
|
+
displayName: 'Lia Wynn',
|
|
290
321
|
contacts: [
|
|
291
322
|
{ vcard }
|
|
292
323
|
]
|
|
@@ -377,6 +408,73 @@ sock.sendMessage([jidA, jidB, jidC], {
|
|
|
377
408
|
})
|
|
378
409
|
```
|
|
379
410
|
|
|
411
|
+
##### โจ Rich Response
|
|
412
|
+
|
|
413
|
+
> [!NOTE]
|
|
414
|
+
`richResponse[]` is a representation of [`submessages[]`](https://baileys.wiki/docs/api/namespaces/proto/interfaces/IAIRichResponseSubMessage) inside `richResponseMessage`.
|
|
415
|
+
|
|
416
|
+
> [!TIP]
|
|
417
|
+
You can still use the original [`submessages[]`](https://baileys.wiki/docs/api/namespaces/proto/interfaces/IAIRichResponseSubMessage) field directly.
|
|
418
|
+
> The code example below is just an implementation using a helper, not a required structure.
|
|
419
|
+
|
|
420
|
+
```javascript
|
|
421
|
+
sock.sendMessage(jid, {
|
|
422
|
+
richResponse: [{
|
|
423
|
+
text: 'Example Usage',
|
|
424
|
+
}, {
|
|
425
|
+
language: 'javascript',
|
|
426
|
+
code: [{
|
|
427
|
+
highlightType: 0,
|
|
428
|
+
codeContent: 'console.log("Hello, World!")'
|
|
429
|
+
}]
|
|
430
|
+
}, {
|
|
431
|
+
text: 'Pretty simple, right?\n'
|
|
432
|
+
}, {
|
|
433
|
+
text: 'Comparison between Node.js, Bun, and Deno',
|
|
434
|
+
}, {
|
|
435
|
+
title: 'Runtime Comparison',
|
|
436
|
+
table: [{
|
|
437
|
+
isHeading: true,
|
|
438
|
+
items: ['', 'Node.js', 'Bun', 'Deno']
|
|
439
|
+
}, {
|
|
440
|
+
isHeading: false,
|
|
441
|
+
items: ['Engine', 'V8 (C++)', 'JavaScriptCore (C++)', 'V8 (C++)']
|
|
442
|
+
}, {
|
|
443
|
+
isHeading: false,
|
|
444
|
+
items: ['Performance', '4/5', '5/5', '4/5']
|
|
445
|
+
}]
|
|
446
|
+
}, {
|
|
447
|
+
text: 'Does this help clarify the differences?'
|
|
448
|
+
}]
|
|
449
|
+
})
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
##### ๐งพ Message with Code Block
|
|
453
|
+
|
|
454
|
+
```javascript
|
|
455
|
+
sock.sendMessage(jid, {
|
|
456
|
+
header: 'Example Usage',
|
|
457
|
+
code: 'console.log("Hello, World!")',
|
|
458
|
+
footer: 'Pretty simple, right?',
|
|
459
|
+
language: 'javascript'
|
|
460
|
+
})
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
##### ๐ Message with Table
|
|
464
|
+
|
|
465
|
+
```javascript
|
|
466
|
+
sock.sendMessage(jid, {
|
|
467
|
+
header: 'Comparison between Node.js, Bun, and Deno',
|
|
468
|
+
title: 'Runtime Comparison',
|
|
469
|
+
table: [
|
|
470
|
+
['', 'Node.js', 'Bun', 'Deno'],
|
|
471
|
+
['Engine', 'V8 (C++)', 'JavaScriptCore (C++)', 'V8 (C++)'],
|
|
472
|
+
['Performance', '4/5', '5/5', '4/5']
|
|
473
|
+
],
|
|
474
|
+
footer: 'Does this help clarify the differences?'
|
|
475
|
+
})
|
|
476
|
+
```
|
|
477
|
+
|
|
380
478
|
#### ๐ Sending Media Messages
|
|
381
479
|
|
|
382
480
|
> [!NOTE]
|
|
@@ -669,7 +767,7 @@ sock.sendMessage(jid, {
|
|
|
669
767
|
caption: '๐ผ๏ธ Image 3',
|
|
670
768
|
footer: '๐ท๏ธ Pinterest',
|
|
671
769
|
optionText: '๐๐ป Select Options',
|
|
672
|
-
optionTitle: '
|
|
770
|
+
optionTitle: '๐๐ป Select Options',
|
|
673
771
|
offerText: '๐ท๏ธ New Coupon!',
|
|
674
772
|
offerCode: '@itsliaaa/baileys',
|
|
675
773
|
offerUrl: 'https://www.npmjs.com/package/@itsliaaa/baileys',
|
package/lib/Defaults/index.js
CHANGED
|
@@ -26,6 +26,7 @@ export const NOISE_MODE = 'Noise_XX_25519_AESGCM_SHA256\0\0\0\0';
|
|
|
26
26
|
export const DICT_VERSION = 3;
|
|
27
27
|
export const KEY_BUNDLE_TYPE = Buffer.from([5]);
|
|
28
28
|
export const NOISE_WA_HEADER = Buffer.from([87, 65, 6, DICT_VERSION]); // last is "DICT_VERSION"
|
|
29
|
+
export const LEXER_REGEX = /(\/\/.*|\/\*[\s\S]*?\*\/|#.*)|("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`[\s\S]*?`)|(\b[a-zA-Z_]\w*\b)(?=\s*\()|(\b[a-zA-Z_]\w*\b)|(\b\d+(?:\.\d+)?\b)|(\s+|[^\w\s]+)/g;
|
|
29
30
|
/** from: https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url */
|
|
30
31
|
export const URL_REGEX = /https:\/\/(?![^:@\/\s]+:[^:@\/\s]+@)[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(:\d+)?(\/[^\s]*)?/g;
|
|
31
32
|
export const WA_CERT_DETAILS = {
|
|
@@ -140,4 +141,10 @@ export const TimeMs = {
|
|
|
140
141
|
Hour: 60 * 60 * 1000,
|
|
141
142
|
Day: 24 * 60 * 60 * 1000,
|
|
142
143
|
Week: 7 * 24 * 60 * 60 * 1000
|
|
144
|
+
};
|
|
145
|
+
export const FORWARDED_AI_BOT_INFO = {
|
|
146
|
+
isForwarded: true,
|
|
147
|
+
forwardingScore: 1,
|
|
148
|
+
forwardedAiBotMessageInfo: { botJid: '867051314767696@bot' },
|
|
149
|
+
forwardOrigin: 4
|
|
143
150
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export var CodeHighlightType;
|
|
2
|
+
(function (CodeHighlightType) {
|
|
3
|
+
CodeHighlightType[CodeHighlightType["DEFAULT"] = 0] = "DEFAULT";
|
|
4
|
+
CodeHighlightType[CodeHighlightType["KEYWORD"] = 1] = "KEYWORD";
|
|
5
|
+
CodeHighlightType[CodeHighlightType["METHOD"] = 2] = "METHOD";
|
|
6
|
+
CodeHighlightType[CodeHighlightType["STRING"] = 3] = "STRING";
|
|
7
|
+
CodeHighlightType[CodeHighlightType["NUMBER"] = 4] = "NUMBER";
|
|
8
|
+
CodeHighlightType[CodeHighlightType["COMMENT"] = 5] = "COMMENT";
|
|
9
|
+
})(CodeHighlightType || (CodeHighlightType = {}));
|
|
10
|
+
export var RichSubMessageType;
|
|
11
|
+
(function (RichSubMessageType) {
|
|
12
|
+
RichSubMessageType[RichSubMessageType["UNKNOWN"] = 0] = "UNKNOWN";
|
|
13
|
+
RichSubMessageType[RichSubMessageType["GRID_IMAGE"] = 1] = "GRID_IMAGE";
|
|
14
|
+
RichSubMessageType[RichSubMessageType["TEXT"] = 2] = "TEXT";
|
|
15
|
+
RichSubMessageType[RichSubMessageType["INLINE_IMAGE"] = 3] = "INLINE_IMAGE";
|
|
16
|
+
RichSubMessageType[RichSubMessageType["TABLE"] = 4] = "TABLE";
|
|
17
|
+
RichSubMessageType[RichSubMessageType["CODE"] = 5] = "CODE";
|
|
18
|
+
RichSubMessageType[RichSubMessageType["DYNAMIC"] = 6] = "DYNAMIC";
|
|
19
|
+
RichSubMessageType[RichSubMessageType["MAP"] = 7] = "MAP";
|
|
20
|
+
RichSubMessageType[RichSubMessageType["LATEX"] = 8] = "LATEX";
|
|
21
|
+
RichSubMessageType[RichSubMessageType["CONTENT_ITEMS"] = 9] = "CONTENT_ITEMS";
|
|
22
|
+
})(RichSubMessageType || (RichSubMessageType = {}));
|
package/lib/Utils/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export * from './generics.js';
|
|
|
2
2
|
export * from './decode-wa-message.js';
|
|
3
3
|
export * from './messages.js';
|
|
4
4
|
export * from './messages-media.js';
|
|
5
|
+
export * from './rich-message-utils.js';
|
|
5
6
|
export * from './validate-connection.js';
|
|
6
7
|
export * from './crypto.js';
|
|
7
8
|
export * from './signal.js';
|
package/lib/Utils/messages.js
CHANGED
|
@@ -10,6 +10,7 @@ import { isPnUser, isLidUser, isJidGroup, isJidNewsletter, isJidStatusBroadcast,
|
|
|
10
10
|
import { sha256 } from './crypto.js';
|
|
11
11
|
import { generateMessageIDV2, getKeyAuthor, unixTimestampSeconds } from './generics.js';
|
|
12
12
|
import { downloadContentFromMessage, encryptedStream, generateThumbnail, getAudioDuration, getAudioWaveform, getImageProcessingLibrary, getRawMediaUploadData, getStream, toBuffer } from './messages-media.js';
|
|
13
|
+
import { prepareRichCodeBlock, prepareRichResponseMessage, prepareRichTable, wrapToBotForwardedMessage } from './rich-message-utils.js';
|
|
13
14
|
import { shouldIncludeReportingToken } from './reporting-utils.js';
|
|
14
15
|
const MIMETYPE_MAP = {
|
|
15
16
|
image: 'image/jpeg',
|
|
@@ -692,7 +693,7 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
692
693
|
// Lia@Changes 30-01-26 --- Add "raw" boolean to send raw messages directly via generateWAMessage()
|
|
693
694
|
if (hasNonNullishProperty(message, 'raw')) {
|
|
694
695
|
delete message.raw;
|
|
695
|
-
return
|
|
696
|
+
return message;
|
|
696
697
|
}
|
|
697
698
|
else if (hasNonNullishProperty(message, 'text')) {
|
|
698
699
|
const extContent = { text: message.text };
|
|
@@ -726,27 +727,25 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
726
727
|
m.extendedTextMessage = extContent;
|
|
727
728
|
}
|
|
728
729
|
else if (hasNonNullishProperty(message, 'contacts')) {
|
|
729
|
-
const
|
|
730
|
-
const contactLen = contacts.contacts.length;
|
|
730
|
+
const contactLen = message.contacts.contacts.length;
|
|
731
731
|
if (!contactLen) {
|
|
732
732
|
throw new Boom('require atleast 1 contact', { statusCode: 400 });
|
|
733
733
|
}
|
|
734
734
|
if (contactLen === 1) {
|
|
735
|
-
m.contactMessage = contacts.contacts[0];
|
|
735
|
+
m.contactMessage = message.contacts.contacts[0];
|
|
736
736
|
}
|
|
737
737
|
else {
|
|
738
|
-
m.contactsArrayMessage = contacts;
|
|
738
|
+
m.contactsArrayMessage = message.contacts;
|
|
739
739
|
}
|
|
740
740
|
}
|
|
741
741
|
else if (hasNonNullishProperty(message, 'location')) {
|
|
742
742
|
m.locationMessage = message.location;
|
|
743
743
|
}
|
|
744
744
|
else if (hasNonNullishProperty(message, 'react')) {
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
react.senderTimestampMs = Date.now();
|
|
745
|
+
if (!message.react.senderTimestampMs) {
|
|
746
|
+
message.react.senderTimestampMs = Date.now();
|
|
748
747
|
}
|
|
749
|
-
m.reactionMessage = react;
|
|
748
|
+
m.reactionMessage = message.react;
|
|
750
749
|
}
|
|
751
750
|
else if (hasNonNullishProperty(message, 'delete')) {
|
|
752
751
|
m.protocolMessage = {
|
|
@@ -758,26 +757,24 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
758
757
|
m = generateForwardMessageContent(message.forward, message.force);
|
|
759
758
|
}
|
|
760
759
|
else if (hasNonNullishProperty(message, 'disappearingMessagesInChat')) {
|
|
761
|
-
const
|
|
762
|
-
|
|
763
|
-
? disappearingMessagesInChat
|
|
760
|
+
const exp = typeof message.disappearingMessagesInChat === 'boolean'
|
|
761
|
+
? message.disappearingMessagesInChat
|
|
764
762
|
? WA_DEFAULT_EPHEMERAL
|
|
765
763
|
: 0
|
|
766
|
-
: disappearingMessagesInChat;
|
|
764
|
+
: message.disappearingMessagesInChat;
|
|
767
765
|
m = prepareDisappearingMessageSettingContent(exp);
|
|
768
766
|
}
|
|
769
767
|
else if (hasNonNullishProperty(message, 'groupInvite')) {
|
|
770
|
-
const { groupInvite } = message; // Lia@Changes 04-02-26 --- Destructured for readability & cleaner access (โ โทโ โฟโ โทโ )
|
|
771
768
|
m.groupInviteMessage = {};
|
|
772
|
-
m.groupInviteMessage.inviteCode = groupInvite.inviteCode;
|
|
773
|
-
m.groupInviteMessage.inviteExpiration = groupInvite.inviteExpiration;
|
|
774
|
-
m.groupInviteMessage.caption = groupInvite.text;
|
|
775
|
-
m.groupInviteMessage.groupJid = groupInvite.jid;
|
|
776
|
-
m.groupInviteMessage.groupName = groupInvite.subject;
|
|
769
|
+
m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode;
|
|
770
|
+
m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration;
|
|
771
|
+
m.groupInviteMessage.caption = message.groupInvite.text;
|
|
772
|
+
m.groupInviteMessage.groupJid = message.groupInvite.jid;
|
|
773
|
+
m.groupInviteMessage.groupName = message.groupInvite.subject;
|
|
777
774
|
//TODO: use built-in interface and get disappearing mode info etc.
|
|
778
775
|
//TODO: cache / use store!?
|
|
779
776
|
if (options.getProfilePicUrl) {
|
|
780
|
-
const pfpUrl = await options.getProfilePicUrl(groupInvite.jid, 'preview');
|
|
777
|
+
const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
|
|
781
778
|
if (pfpUrl) {
|
|
782
779
|
const resp = await fetch(pfpUrl, { method: 'GET', dispatcher: options?.options?.dispatcher });
|
|
783
780
|
if (resp.ok) {
|
|
@@ -805,47 +802,44 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
805
802
|
m.keepInChatMessage.timestampMs = Date.now();
|
|
806
803
|
}
|
|
807
804
|
else if (hasNonNullishProperty(message, 'flowReply')) {
|
|
808
|
-
const { flowReply } = message; // Lia@Changes 04-02-26 --- Destructured for readability & cleaner access (โ โทโ โฟโ โทโ )
|
|
809
805
|
m.interactiveResponseMessage = {
|
|
810
806
|
body: {
|
|
811
|
-
format: flowReply.format || proto.Message.InteractiveResponseMessage.Body.Format.DEFAULT,
|
|
812
|
-
text: flowReply.text
|
|
807
|
+
format: message.flowReply.format || proto.Message.InteractiveResponseMessage.Body.Format.DEFAULT,
|
|
808
|
+
text: message.flowReply.text
|
|
813
809
|
},
|
|
814
810
|
nativeFlowResponseMessage: {
|
|
815
|
-
name: flowReply.name,
|
|
816
|
-
paramsJson: flowReply.paramsJson || '{}',
|
|
817
|
-
version: flowReply.version || 1
|
|
811
|
+
name: message.flowReply.name,
|
|
812
|
+
paramsJson: message.flowReply.paramsJson || '{}',
|
|
813
|
+
version: message.flowReply.version || 1
|
|
818
814
|
}
|
|
819
815
|
};
|
|
820
816
|
}
|
|
821
817
|
else if (hasNonNullishProperty(message, 'buttonReply')) {
|
|
822
|
-
const { buttonReply } = message; // Lia@Changes 04-02-26 --- Destructured for readability & cleaner access (โ โทโ โฟโ โทโ )
|
|
823
818
|
switch (message.type) {
|
|
824
819
|
case 'template':
|
|
825
820
|
m.templateButtonReplyMessage = {
|
|
826
|
-
selectedDisplayText: buttonReply.displayText,
|
|
827
|
-
selectedId: buttonReply.id,
|
|
828
|
-
selectedIndex: buttonReply.index
|
|
821
|
+
selectedDisplayText: message.buttonReply.displayText,
|
|
822
|
+
selectedId: message.buttonReply.id,
|
|
823
|
+
selectedIndex: message.buttonReply.index
|
|
829
824
|
};
|
|
830
825
|
break;
|
|
831
826
|
case 'plain':
|
|
832
827
|
m.buttonsResponseMessage = {
|
|
833
|
-
selectedButtonId: buttonReply.id,
|
|
834
|
-
selectedDisplayText: buttonReply.displayText,
|
|
828
|
+
selectedButtonId: message.buttonReply.id,
|
|
829
|
+
selectedDisplayText: message.buttonReply.displayText,
|
|
835
830
|
type: proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT
|
|
836
831
|
};
|
|
837
832
|
break;
|
|
838
833
|
}
|
|
839
834
|
}
|
|
840
835
|
else if (hasNonNullishProperty(message, 'listReply')) {
|
|
841
|
-
const { listReply } = message; // Lia@Changes 04-02-26 --- Destructured for readability & cleaner access (โ โทโ โฟโ โทโ )
|
|
842
836
|
m.listResponseMessage = {
|
|
843
|
-
description: listReply.description,
|
|
837
|
+
description: message.listReply.description,
|
|
844
838
|
listType: proto.Message.ListResponseMessage.ListType.SINGLE_SELECT,
|
|
845
839
|
singleSelectReply: {
|
|
846
|
-
selectedRowId: listReply.id
|
|
840
|
+
selectedRowId: message.listReply.id
|
|
847
841
|
},
|
|
848
|
-
title: listReply.title
|
|
842
|
+
title: message.listReply.title
|
|
849
843
|
};
|
|
850
844
|
}
|
|
851
845
|
else if (hasOptionalProperty(message, 'ptv') && message.ptv) {
|
|
@@ -856,68 +850,66 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
856
850
|
m.productMessage = await prepareProductMessage(message, options);
|
|
857
851
|
}
|
|
858
852
|
else if (hasNonNullishProperty(message, 'event')) {
|
|
859
|
-
const { event } = message; // Lia@Changes 04-02-26 --- Destructured for readability & cleaner access (โ โทโ โฟโ โทโ )
|
|
860
853
|
m.eventMessage = {};
|
|
861
|
-
const startTime = Math.floor(event.startDate.getTime() / 1000);
|
|
862
|
-
if (event.call && options.getCallLink) {
|
|
863
|
-
const token = await options.getCallLink(event.call, { startTime });
|
|
864
|
-
m.eventMessage.joinLink = (event.call === 'audio' ? CALL_AUDIO_PREFIX : CALL_VIDEO_PREFIX) + token;
|
|
854
|
+
const startTime = Math.floor(message.event.startDate.getTime() / 1000);
|
|
855
|
+
if (message.event.call && options.getCallLink) {
|
|
856
|
+
const token = await options.getCallLink(message.event.call, { startTime });
|
|
857
|
+
m.eventMessage.joinLink = (message.event.call === 'audio' ? CALL_AUDIO_PREFIX : CALL_VIDEO_PREFIX) + token;
|
|
865
858
|
}
|
|
866
859
|
m.messageContextInfo = {
|
|
867
860
|
// encKey
|
|
868
|
-
messageSecret: event.messageSecret || randomBytes(32)
|
|
861
|
+
messageSecret: message.event.messageSecret || randomBytes(32)
|
|
869
862
|
};
|
|
870
|
-
m.eventMessage.name = event.name;
|
|
871
|
-
m.eventMessage.description = event.description;
|
|
863
|
+
m.eventMessage.name = message.event.name;
|
|
864
|
+
m.eventMessage.description = message.event.description;
|
|
872
865
|
m.eventMessage.startTime = startTime;
|
|
873
|
-
m.eventMessage.endTime = event.endDate ? event.endDate.getTime() / 1000 : undefined;
|
|
874
|
-
m.eventMessage.isCanceled = event.isCancelled ?? false;
|
|
875
|
-
m.eventMessage.extraGuestsAllowed = event.extraGuestsAllowed;
|
|
876
|
-
m.eventMessage.isScheduleCall = event.isScheduleCall ?? false;
|
|
877
|
-
m.eventMessage.location = event.location;
|
|
866
|
+
m.eventMessage.endTime = message.event.endDate ? message.event.endDate.getTime() / 1000 : undefined;
|
|
867
|
+
m.eventMessage.isCanceled = message.event.isCancelled ?? false;
|
|
868
|
+
m.eventMessage.extraGuestsAllowed = message.event.extraGuestsAllowed;
|
|
869
|
+
m.eventMessage.isScheduleCall = message.event.isScheduleCall ?? false;
|
|
870
|
+
m.eventMessage.location = message.event.location;
|
|
878
871
|
}
|
|
879
872
|
else if (hasNonNullishProperty(message, 'poll')) {
|
|
880
|
-
|
|
881
|
-
(
|
|
882
|
-
(
|
|
883
|
-
if (!Array.isArray(poll.values)) {
|
|
873
|
+
(_a = message.poll).selectableCount || (_a.selectableCount = 0);
|
|
874
|
+
(_b = message.poll).toAnnouncementGroup || (_b.toAnnouncementGroup = false);
|
|
875
|
+
if (!Array.isArray(message.poll.values)) {
|
|
884
876
|
throw new Boom('Invalid poll values', { statusCode: 400 });
|
|
885
877
|
}
|
|
886
|
-
if (poll.selectableCount < 0 || poll.selectableCount > poll.values.length) {
|
|
887
|
-
throw new Boom(`poll.selectableCount in poll should be >= 0 and <= ${poll.values.length}`, {
|
|
878
|
+
if (message.poll.selectableCount < 0 || message.poll.selectableCount > message.poll.values.length) {
|
|
879
|
+
throw new Boom(`poll.selectableCount in poll should be >= 0 and <= ${message.poll.values.length}`, {
|
|
888
880
|
statusCode: 400
|
|
889
881
|
});
|
|
890
882
|
}
|
|
891
883
|
m.messageContextInfo = {
|
|
892
884
|
// encKey
|
|
893
|
-
messageSecret: poll.messageSecret || randomBytes(32)
|
|
885
|
+
messageSecret: message.poll.messageSecret || randomBytes(32)
|
|
894
886
|
};
|
|
895
887
|
const pollCreationMessage = {
|
|
896
|
-
name: poll.name,
|
|
897
|
-
selectableOptionsCount: poll.selectableCount,
|
|
898
|
-
options: poll.values.map(optionName => ({ optionName }))
|
|
888
|
+
name: message.poll.name,
|
|
889
|
+
selectableOptionsCount: message.poll.selectableCount,
|
|
890
|
+
options: message.poll.values.map(optionName => ({ optionName }))
|
|
899
891
|
};
|
|
900
|
-
if (poll.toAnnouncementGroup) {
|
|
892
|
+
if (message.poll.toAnnouncementGroup) {
|
|
901
893
|
// poll v2 is for community announcement groups (single select and multiple)
|
|
902
894
|
m.pollCreationMessageV2 = pollCreationMessage;
|
|
903
895
|
}
|
|
904
896
|
else {
|
|
905
897
|
// Lia@Changes 08-02-26 --- Add quiz message support
|
|
906
|
-
if (poll.pollType
|
|
907
|
-
if (!poll.correctAnswer) {
|
|
898
|
+
if (message.poll.pollType == 1) {
|
|
899
|
+
if (!message.poll.correctAnswer) {
|
|
908
900
|
throw new Boom('No "correctAnswer" provided for quiz', { statusCode: 400 });
|
|
909
901
|
}
|
|
910
902
|
m.pollCreationMessageV5 = {
|
|
911
903
|
// Lia@Note 08-02-26 --- quiz for newsletter only
|
|
912
904
|
...pollCreationMessage,
|
|
913
905
|
correctAnswer: {
|
|
914
|
-
optionName: poll.correctAnswer.toString()
|
|
906
|
+
optionName: message.poll.correctAnswer.toString()
|
|
915
907
|
},
|
|
916
|
-
pollType: poll.pollType,
|
|
908
|
+
pollType: message.poll.pollType,
|
|
917
909
|
selectableOptionsCount: 1
|
|
918
910
|
};
|
|
919
911
|
}
|
|
920
|
-
else if (poll.selectableCount === 1) {
|
|
912
|
+
else if (message.poll.selectableCount === 1) {
|
|
921
913
|
//poll v3 is for single select polls
|
|
922
914
|
m.pollCreationMessageV3 = pollCreationMessage;
|
|
923
915
|
}
|
|
@@ -929,15 +921,14 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
929
921
|
}
|
|
930
922
|
// Lia@Changes 08-02-26 --- Add poll result snapshot message
|
|
931
923
|
else if (hasNonNullishProperty(message, 'pollResult')) {
|
|
932
|
-
const { pollResult } = message;
|
|
933
924
|
const pollResultSnapshotMessage = {
|
|
934
|
-
name: pollResult.name,
|
|
935
|
-
pollVotes: pollResult.votes.map(vote => ({
|
|
925
|
+
name: message.pollResult.name,
|
|
926
|
+
pollVotes: message.pollResult.votes.map(vote => ({
|
|
936
927
|
optionName: vote.name,
|
|
937
928
|
optionVoteCount: parseInt(vote.voteCount)
|
|
938
929
|
}))
|
|
939
930
|
};
|
|
940
|
-
if (pollResult.pollType
|
|
931
|
+
if (message.pollResult.pollType == 1) {
|
|
941
932
|
pollResultSnapshotMessage.pollType = proto.Message.PollType.QUIZ;
|
|
942
933
|
m.pollResultSnapshotMessageV3 = pollResultSnapshotMessage;
|
|
943
934
|
}
|
|
@@ -948,18 +939,17 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
948
939
|
}
|
|
949
940
|
// Lia@Changes 08-02-26 --- Add poll update message
|
|
950
941
|
else if (hasNonNullishProperty(message, 'pollUpdate')) {
|
|
951
|
-
|
|
952
|
-
if (!pollUpdate.key) {
|
|
942
|
+
if (!message.pollUpdate.key) {
|
|
953
943
|
throw new Boom('Message key is required', { statusCode: 400 });
|
|
954
944
|
}
|
|
955
|
-
if (!pollUpdate.vote) {
|
|
945
|
+
if (!message.pollUpdate.vote) {
|
|
956
946
|
throw new Boom('Encrypted vote payload is required', { statusCode: 400 });
|
|
957
947
|
}
|
|
958
948
|
m.pollUpdateMessage = {
|
|
959
|
-
metadata: pollUpdate.metadata,
|
|
960
|
-
pollCreationMessageKey: pollUpdate.key,
|
|
949
|
+
metadata: message.pollUpdate.metadata,
|
|
950
|
+
pollCreationMessageKey: message.pollUpdate.key,
|
|
961
951
|
senderTimestampMs: Date.now(),
|
|
962
|
-
vote: pollUpdate.vote
|
|
952
|
+
vote: message.pollUpdate.vote
|
|
963
953
|
};
|
|
964
954
|
}
|
|
965
955
|
else if (hasNonNullishProperty(message, 'sharePhoneNumber')) {
|
|
@@ -1009,17 +999,16 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1009
999
|
}
|
|
1010
1000
|
// Lia@Changes 31-01-26 --- Add support for album messages
|
|
1011
1001
|
else if (hasNonNullishProperty(message, 'album')) {
|
|
1012
|
-
|
|
1013
|
-
if (!Array.isArray(album)) {
|
|
1002
|
+
if (!Array.isArray(message.album)) {
|
|
1014
1003
|
throw new Boom('Invalid album type. Expected an array.', { statusCode: 400 });
|
|
1015
1004
|
}
|
|
1016
1005
|
let videoCount = 0;
|
|
1017
|
-
for (let i = 0; i < album.length; i++) {
|
|
1018
|
-
if (album[i].video) videoCount++;
|
|
1006
|
+
for (let i = 0; i < message.album.length; i++) {
|
|
1007
|
+
if (message.album[i].video) videoCount++;
|
|
1019
1008
|
};
|
|
1020
1009
|
let imageCount = 0;
|
|
1021
|
-
for (let i = 0; i < album.length; i++) {
|
|
1022
|
-
if (album[i].image) imageCount++;
|
|
1010
|
+
for (let i = 0; i < message.album.length; i++) {
|
|
1011
|
+
if (message.album[i].image) imageCount++;
|
|
1023
1012
|
};
|
|
1024
1013
|
if ((videoCount + imageCount) < 2) {
|
|
1025
1014
|
throw new Boom('Minimum provide 2 media to upload album message', { statusCode: 400 });
|
|
@@ -1029,6 +1018,16 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1029
1018
|
expectedVideoCount: videoCount
|
|
1030
1019
|
};
|
|
1031
1020
|
}
|
|
1021
|
+
// Lia@Changes 09-04-26 --- Add support for code block and table
|
|
1022
|
+
else if (hasNonNullishProperty(message, 'code')) {
|
|
1023
|
+
m.richResponseMessage = prepareRichCodeBlock(message);
|
|
1024
|
+
}
|
|
1025
|
+
else if (hasNonNullishProperty(message, 'table')) {
|
|
1026
|
+
m.richResponseMessage = prepareRichTable(message);
|
|
1027
|
+
}
|
|
1028
|
+
else if (hasNonNullishProperty(message, 'richResponse')) {
|
|
1029
|
+
m.richResponseMessage = prepareRichResponseMessage(message.richResponse);
|
|
1030
|
+
}
|
|
1032
1031
|
else {
|
|
1033
1032
|
m = await prepareWAMessageMedia(message, options);
|
|
1034
1033
|
}
|
|
@@ -1420,6 +1419,10 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1420
1419
|
m = { viewOnceMessageV2Extension: { message: m } };
|
|
1421
1420
|
delete message.viewOnceV2Extension;
|
|
1422
1421
|
}
|
|
1422
|
+
// Lia@Note 09-04-26 --- Wrap richResponseMessage into botForwardedMessage
|
|
1423
|
+
if (!!m.richResponseMessage) {
|
|
1424
|
+
m = wrapToBotForwardedMessage(m)
|
|
1425
|
+
}
|
|
1423
1426
|
if (hasOptionalProperty(message, 'edit')) {
|
|
1424
1427
|
m = {
|
|
1425
1428
|
protocolMessage: {
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lia@Changes 09-04-26 [WIP]
|
|
3
|
+
* Adds support for tables and code blocks with richResponseMessage (wrapped inside botForwardedMessage).
|
|
4
|
+
*
|
|
5
|
+
* If you use or copy this code, please credit my name or project.
|
|
6
|
+
*/
|
|
7
|
+
import { randomUUID } from 'crypto';
|
|
8
|
+
import { FORWARDED_AI_BOT_INFO, LEXER_REGEX } from '../Defaults/index.js';
|
|
9
|
+
import { CodeHighlightType, RichSubMessageType } from '../Types/RichType.js';
|
|
10
|
+
const textEncoder = new TextEncoder();
|
|
11
|
+
const CPP_KEYWORDS = new Set([
|
|
12
|
+
'alignas', 'alignof', 'and', 'and_eq', 'asm', 'auto', 'bitand', 'bitor', 'bool', 'break', 'case',
|
|
13
|
+
'catch', 'char', 'class', 'compl', 'concept', 'const', 'consteval', 'constexpr', 'constinit',
|
|
14
|
+
'const_cast', 'continue', 'co_await', 'co_return', 'co_yield', 'decltype', 'default', 'delete',
|
|
15
|
+
'do', 'double', 'dynamic_cast', 'else', 'enum', 'explicit', 'export', 'extern', 'false', 'float',
|
|
16
|
+
'for', 'friend', 'goto', 'if', 'inline', 'int', 'long', 'mutable', 'namespace', 'new', 'noexcept',
|
|
17
|
+
'not', 'not_eq', 'nullptr', 'operator', 'or', 'or_eq', 'private', 'protected', 'public', 'register',
|
|
18
|
+
'reinterpret_cast', 'requires', 'return', 'short', 'signed', 'sizeof', 'static', 'static_assert',
|
|
19
|
+
'static_cast', 'struct', 'switch', 'template', 'this', 'thread_local', 'throw', 'true', 'try',
|
|
20
|
+
'typedef', 'typeid', 'typename', 'union', 'unsigned', 'using', 'virtual', 'void', 'volatile',
|
|
21
|
+
'wchar_t', 'while', 'xor', 'xor_eq'
|
|
22
|
+
]);
|
|
23
|
+
const CSS_KEYWORDS = new Set([
|
|
24
|
+
'import', 'media', 'font-face', 'keyframes', 'supports', 'charset',
|
|
25
|
+
'important', 'root', 'hover', 'active', 'focus', 'visited', 'before', 'after',
|
|
26
|
+
'not', 'nth-child', 'first-child', 'last-child', 'only-child',
|
|
27
|
+
'none', 'inherit', 'initial', 'unset', 'auto', 'transparent', 'currentcolor'
|
|
28
|
+
]);
|
|
29
|
+
const GO_KEYWORDS = new Set([
|
|
30
|
+
'break', 'default', 'func', 'interface', 'select', 'case', 'defer', 'go', 'map', 'struct',
|
|
31
|
+
'chan', 'else', 'goto', 'package', 'switch', 'const', 'fallthrough', 'if', 'range', 'type',
|
|
32
|
+
'continue', 'for', 'import', 'return', 'var', 'true', 'false', 'nil'
|
|
33
|
+
]);
|
|
34
|
+
const HTML_KEYWORDS = new Set([
|
|
35
|
+
'html', 'head', 'body', 'title', 'meta', 'link', 'script', 'style',
|
|
36
|
+
'header', 'footer', 'main', 'section', 'article', 'aside', 'nav',
|
|
37
|
+
'div', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'a', 'img',
|
|
38
|
+
'ul', 'ol', 'li', 'table', 'tr', 'td', 'th', 'thead', 'tbody',
|
|
39
|
+
'form', 'input', 'button', 'select', 'textarea', 'label', 'option',
|
|
40
|
+
'canvas', 'svg', 'iframe', 'video', 'audio', 'source'
|
|
41
|
+
]);
|
|
42
|
+
const JS_KEYWORDS = new Set([
|
|
43
|
+
'import', 'export', 'from', 'default', 'as',
|
|
44
|
+
'const', 'let', 'var', 'function', 'class', 'extends', 'new',
|
|
45
|
+
'return', 'if', 'else', 'for', 'while', 'do', 'switch', 'case', 'break', 'continue',
|
|
46
|
+
'try', 'catch', 'finally', 'throw',
|
|
47
|
+
'async', 'await', 'yield',
|
|
48
|
+
'typeof', 'instanceof', 'in', 'of', 'delete', 'void',
|
|
49
|
+
'true', 'false', 'null', 'undefined', 'NaN', 'Infinity',
|
|
50
|
+
'this', 'super', 'static', 'get', 'set',
|
|
51
|
+
'debugger', 'with'
|
|
52
|
+
]);
|
|
53
|
+
const PYTHON_KEYWORDS = new Set([
|
|
54
|
+
'import', 'from', 'as', 'def', 'class', 'return', 'if', 'elif', 'else',
|
|
55
|
+
'for', 'while', 'break', 'continue', 'try', 'except', 'finally', 'raise',
|
|
56
|
+
'with', 'yield', 'lambda', 'pass', 'del', 'global', 'nonlocal', 'assert',
|
|
57
|
+
'True', 'False', 'None', 'and', 'or', 'not', 'in', 'is', 'async', 'await',
|
|
58
|
+
'self', 'print'
|
|
59
|
+
]);
|
|
60
|
+
const RUST_KEYWORDS = new Set([
|
|
61
|
+
'as', 'break', 'const', 'continue', 'crate', 'else', 'enum', 'extern', 'false', 'fn', 'for',
|
|
62
|
+
'if', 'impl', 'in', 'let', 'loop', 'match', 'mod', 'move', 'mut', 'pub', 'ref', 'return',
|
|
63
|
+
'self', 'Self', 'static', 'struct', 'super', 'trait', 'true', 'type', 'unsafe', 'use',
|
|
64
|
+
'where', 'while', 'async', 'await', 'dyn', 'abstract', 'become', 'box', 'do', 'final',
|
|
65
|
+
'macro', 'override', 'priv', 'typeof', 'unsized', 'virtual', 'yield'
|
|
66
|
+
]);
|
|
67
|
+
const NOOP = new Set([])
|
|
68
|
+
export const LANGUAGE_KEYWORDS = {
|
|
69
|
+
css: CSS_KEYWORDS,
|
|
70
|
+
html: HTML_KEYWORDS,
|
|
71
|
+
javascript: JS_KEYWORDS,
|
|
72
|
+
typescript: JS_KEYWORDS,
|
|
73
|
+
js: JS_KEYWORDS,
|
|
74
|
+
ts: JS_KEYWORDS,
|
|
75
|
+
python: PYTHON_KEYWORDS,
|
|
76
|
+
py: PYTHON_KEYWORDS,
|
|
77
|
+
go: GO_KEYWORDS,
|
|
78
|
+
golang: GO_KEYWORDS,
|
|
79
|
+
cpp: CPP_KEYWORDS,
|
|
80
|
+
'c++': CPP_KEYWORDS,
|
|
81
|
+
rust: RUST_KEYWORDS,
|
|
82
|
+
rs: RUST_KEYWORDS,
|
|
83
|
+
};
|
|
84
|
+
export const tokenizeCode = (code, language = 'javascript') => {
|
|
85
|
+
const keywords = LANGUAGE_KEYWORDS[language] || NOOP;
|
|
86
|
+
const blocks = [];
|
|
87
|
+
LEXER_REGEX.lastIndex = 0;
|
|
88
|
+
let match;
|
|
89
|
+
while ((match = LEXER_REGEX.exec(code)) !== null) {
|
|
90
|
+
if (match[1]) {
|
|
91
|
+
blocks.push({ highlightType: CodeHighlightType.COMMENT, codeContent: match[1] });
|
|
92
|
+
}
|
|
93
|
+
else if (match[2]) {
|
|
94
|
+
blocks.push({ highlightType: CodeHighlightType.STRING, codeContent: match[2] });
|
|
95
|
+
}
|
|
96
|
+
else if (match[3]) {
|
|
97
|
+
blocks.push({
|
|
98
|
+
highlightType: keywords.has(match[3]) ? CodeHighlightType.KEYWORD : CodeHighlightType.METHOD,
|
|
99
|
+
codeContent: match[3],
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
else if (match[4]) {
|
|
103
|
+
blocks.push({
|
|
104
|
+
highlightType: keywords.has(match[4]) ? CodeHighlightType.KEYWORD : CodeHighlightType.DEFAULT,
|
|
105
|
+
codeContent: match[4],
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
else if (match[5]) {
|
|
109
|
+
blocks.push({ highlightType: CodeHighlightType.NUMBER, codeContent: match[5] });
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
blocks.push({ highlightType: CodeHighlightType.DEFAULT, codeContent: match[6] });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return blocks;
|
|
116
|
+
};
|
|
117
|
+
// Lia@Changes 09-04-26 --- Inject buffer into unifiedResponse.data to support proper rendering of rich messages (ex: tables and code blocks)
|
|
118
|
+
const toUnified = (submessages) =>
|
|
119
|
+
({
|
|
120
|
+
response_id: randomUUID(),
|
|
121
|
+
sections: submessages.map((submessage) => {
|
|
122
|
+
switch (submessage.messageType) {
|
|
123
|
+
case RichSubMessageType.TEXT:
|
|
124
|
+
return {
|
|
125
|
+
view_model: {
|
|
126
|
+
primitive: { text: submessage.messageText, inline_entities: [], __typename: 'GenAIMarkdownTextUXPrimitive' },
|
|
127
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
case RichSubMessageType.TABLE:
|
|
131
|
+
return {
|
|
132
|
+
view_model: {
|
|
133
|
+
primitive: {
|
|
134
|
+
title: submessage.tableMetadata.title,
|
|
135
|
+
rows: submessage.tableMetadata.rows.map((row) => ({ is_header: row.isHeading, cells: row.items })),
|
|
136
|
+
__typename: 'GenATableUXPrimitive'
|
|
137
|
+
},
|
|
138
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
case RichSubMessageType.CODE:
|
|
142
|
+
return {
|
|
143
|
+
view_model: {
|
|
144
|
+
primitive: {
|
|
145
|
+
language: submessage.codeMetadata.codeLanguage,
|
|
146
|
+
code_blocks: submessage.codeMetadata.codeBlocks.map((block) => ({ content: block.codeContent, type: CodeHighlightType[block.highlightType] })),
|
|
147
|
+
__typename: 'GenAICodeUXPrimitive'
|
|
148
|
+
},
|
|
149
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return submessage;
|
|
154
|
+
})
|
|
155
|
+
});
|
|
156
|
+
export const prepareRichCodeBlock = ({ header, code, footer, language } = {}) => {
|
|
157
|
+
language ??= 'javascript'
|
|
158
|
+
const submessages = [];
|
|
159
|
+
if (header) {
|
|
160
|
+
submessages.push({
|
|
161
|
+
messageType: 2,
|
|
162
|
+
messageText: header
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
submessages.push({
|
|
166
|
+
messageType: 5,
|
|
167
|
+
codeMetadata: {
|
|
168
|
+
codeLanguage: language,
|
|
169
|
+
codeBlocks: tokenizeCode(code, language)
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
if (footer) {
|
|
173
|
+
submessages.push({
|
|
174
|
+
messageType: 2,
|
|
175
|
+
messageText: footer
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
const unified = toUnified(submessages);
|
|
179
|
+
return {
|
|
180
|
+
submessages,
|
|
181
|
+
messageType: 1,
|
|
182
|
+
unifiedResponse: {
|
|
183
|
+
data: textEncoder.encode(JSON.stringify(unified))
|
|
184
|
+
},
|
|
185
|
+
contextInfo: FORWARDED_AI_BOT_INFO
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
export const prepareRichTable = ({ header, title, table, footer } = {}) => {
|
|
189
|
+
const tableRows = table.map((items, index) => ({
|
|
190
|
+
isHeading: index == 0,
|
|
191
|
+
items
|
|
192
|
+
}));
|
|
193
|
+
const submessages = [];
|
|
194
|
+
if (header) {
|
|
195
|
+
submessages.push({
|
|
196
|
+
messageType: 2,
|
|
197
|
+
messageText: header
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
submessages.push({
|
|
201
|
+
messageType: 4,
|
|
202
|
+
tableMetadata: {
|
|
203
|
+
title,
|
|
204
|
+
rows: tableRows
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
if (footer) {
|
|
208
|
+
submessages.push({
|
|
209
|
+
messageType: 2,
|
|
210
|
+
messageText: footer
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
const unified = toUnified(submessages);
|
|
214
|
+
return {
|
|
215
|
+
submessages,
|
|
216
|
+
messageType: 1,
|
|
217
|
+
unifiedResponse: {
|
|
218
|
+
data: textEncoder.encode(JSON.stringify(unified))
|
|
219
|
+
},
|
|
220
|
+
contextInfo: FORWARDED_AI_BOT_INFO
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
export const prepareRichResponseMessage = (content) => {
|
|
224
|
+
const submessages = content.map((submessage) => {
|
|
225
|
+
if (submessage.text) {
|
|
226
|
+
return {
|
|
227
|
+
messageType: 2,
|
|
228
|
+
messageText: submessage.text
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
else if (submessage.code) {
|
|
232
|
+
return {
|
|
233
|
+
messageType: 5,
|
|
234
|
+
codeMetadata: {
|
|
235
|
+
codeLanguage: submessage.language,
|
|
236
|
+
codeBlocks: submessage.code
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
else if (submessage.table) {
|
|
241
|
+
return {
|
|
242
|
+
messageType: 4,
|
|
243
|
+
tableMetadata: {
|
|
244
|
+
title: submessage.title,
|
|
245
|
+
rows: submessage.table
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
return submessage;
|
|
250
|
+
});
|
|
251
|
+
const unified = toUnified(submessages);
|
|
252
|
+
return {
|
|
253
|
+
submessages,
|
|
254
|
+
messageType: 1,
|
|
255
|
+
unifiedResponse: {
|
|
256
|
+
data: textEncoder.encode(JSON.stringify(unified))
|
|
257
|
+
},
|
|
258
|
+
contextInfo: FORWARDED_AI_BOT_INFO
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
export const wrapToBotForwardedMessage = (message) =>
|
|
262
|
+
({
|
|
263
|
+
messageContextInfo: {
|
|
264
|
+
botMetadata: {
|
|
265
|
+
// Lia@Note 09-04-26 --- TODO: Fill verificationMetadata field
|
|
266
|
+
verificationMetadata: {},
|
|
267
|
+
botRenderingConfigMetadata: {
|
|
268
|
+
bloksVersioningId: '0903aa5f7f47de66789d5f4c86d3bd6e05e4bc3ff85e454a9f907d5ed7fef97c',
|
|
269
|
+
pixelDensity: 2.75
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
botForwardedMessage: { message }
|
|
274
|
+
});
|