@nuiisweety/baileys 0.1.0 → 0.1.2
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 +679 -3
- package/README.md.bak +410 -476
- package/lib/Socket/index.js +4 -4
- package/lib/Socket/index.js.bak +6 -6
- package/lib/Types/RichType.js +1 -1
- package/lib/Types/RichType.js.bak +23 -0
- package/lib/Utils/rich-message-utils.js +545 -140
- package/lib/Utils/rich-message-utils.js.bak +246 -0
- package/lib/WABinary/constants.js +102 -0
- package/lib/WABinary/constants.js.bak +1373 -0
- package/package.json +1 -1
|
@@ -4,7 +4,13 @@ import { LANGUAGE_KEYWORDS } from '../WABinary/constants.js';
|
|
|
4
4
|
import { CodeHighlightType, RichSubMessageType } from '../Types/RichType.js';
|
|
5
5
|
import { proto } from '../../WAProto/index.js';
|
|
6
6
|
import { unixTimestampSeconds } from './generics.js';
|
|
7
|
+
|
|
7
8
|
const NOOP = new Set([]);
|
|
9
|
+
|
|
10
|
+
/* ─────────────────────────────────────────────────────────────
|
|
11
|
+
TOKENIZER
|
|
12
|
+
───────────────────────────────────────────────────────────── */
|
|
13
|
+
|
|
8
14
|
export const tokenizeCode = (code, language = 'javascript') => {
|
|
9
15
|
const keywords = LANGUAGE_KEYWORDS[language] || NOOP;
|
|
10
16
|
const blocks = [];
|
|
@@ -13,181 +19,570 @@ export const tokenizeCode = (code, language = 'javascript') => {
|
|
|
13
19
|
while ((match = LEXER_REGEX.exec(code)) !== null) {
|
|
14
20
|
if (match[1]) {
|
|
15
21
|
blocks.push({ highlightType: CodeHighlightType.COMMENT, codeContent: match[1] });
|
|
16
|
-
}
|
|
17
|
-
else if (match[2]) {
|
|
22
|
+
} else if (match[2]) {
|
|
18
23
|
blocks.push({ highlightType: CodeHighlightType.STRING, codeContent: match[2] });
|
|
19
|
-
}
|
|
20
|
-
else if (match[3]) {
|
|
24
|
+
} else if (match[3]) {
|
|
21
25
|
blocks.push({
|
|
22
26
|
highlightType: keywords.has(match[3]) ? CodeHighlightType.KEYWORD : CodeHighlightType.METHOD,
|
|
23
27
|
codeContent: match[3],
|
|
24
28
|
});
|
|
25
|
-
}
|
|
26
|
-
else if (match[4]) {
|
|
29
|
+
} else if (match[4]) {
|
|
27
30
|
blocks.push({
|
|
28
31
|
highlightType: keywords.has(match[4]) ? CodeHighlightType.KEYWORD : CodeHighlightType.DEFAULT,
|
|
29
32
|
codeContent: match[4],
|
|
30
33
|
});
|
|
31
|
-
}
|
|
32
|
-
else if (match[5]) {
|
|
34
|
+
} else if (match[5]) {
|
|
33
35
|
blocks.push({ highlightType: CodeHighlightType.NUMBER, codeContent: match[5] });
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
+
} else {
|
|
36
37
|
blocks.push({ highlightType: CodeHighlightType.DEFAULT, codeContent: match[6] });
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
return blocks;
|
|
40
41
|
};
|
|
42
|
+
|
|
43
|
+
/* ─────────────────────────────────────────────────────────────
|
|
44
|
+
INCOMING DECODER — parse rich message yang diterima
|
|
45
|
+
───────────────────────────────────────────────────────────── */
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Parse sebuah AIRichResponseSubMessage proto menjadi object JS yang mudah dipakai.
|
|
49
|
+
* Return null kalau tipe tidak dikenal.
|
|
50
|
+
*/
|
|
51
|
+
export const parseRichSubMessage = (submessage) => {
|
|
52
|
+
if (!submessage) return null;
|
|
53
|
+
const type = submessage.messageType;
|
|
54
|
+
|
|
55
|
+
switch (type) {
|
|
56
|
+
case RichSubMessageType.TEXT:
|
|
57
|
+
return {
|
|
58
|
+
type: 'text',
|
|
59
|
+
text: submessage.messageText || '',
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
case RichSubMessageType.CODE:
|
|
63
|
+
return {
|
|
64
|
+
type: 'code',
|
|
65
|
+
language: submessage.codeMetadata?.codeLanguage || 'plain',
|
|
66
|
+
blocks: (submessage.codeMetadata?.codeBlocks || []).map(b => ({
|
|
67
|
+
highlight: CodeHighlightType[b.highlightType] ?? 'DEFAULT',
|
|
68
|
+
content: b.codeContent || '',
|
|
69
|
+
})),
|
|
70
|
+
/** Helper: ambil source code mentah tanpa highlight info */
|
|
71
|
+
get raw() {
|
|
72
|
+
return this.blocks.map(b => b.content).join('');
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
case RichSubMessageType.TABLE:
|
|
77
|
+
return {
|
|
78
|
+
type: 'table',
|
|
79
|
+
title: submessage.tableMetadata?.title || '',
|
|
80
|
+
rows: (submessage.tableMetadata?.rows || []).map(row => ({
|
|
81
|
+
isHeading: row.isHeading ?? false,
|
|
82
|
+
items: row.items || [],
|
|
83
|
+
})),
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
case RichSubMessageType.GRID_IMAGE:
|
|
87
|
+
return {
|
|
88
|
+
type: 'gridImage',
|
|
89
|
+
gridImageUrl: submessage.gridImageMetadata?.gridImageUrl || null,
|
|
90
|
+
imageUrls: submessage.gridImageMetadata?.imageUrls || [],
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
case RichSubMessageType.INLINE_IMAGE:
|
|
94
|
+
return {
|
|
95
|
+
type: 'inlineImage',
|
|
96
|
+
imageUrl: submessage.imageMetadata?.imageUrl || null,
|
|
97
|
+
imageText: submessage.imageMetadata?.imageText || '',
|
|
98
|
+
alignment: submessage.imageMetadata?.alignment ?? 0,
|
|
99
|
+
tapLinkUrl: submessage.imageMetadata?.tapLinkUrl || null,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
case RichSubMessageType.DYNAMIC:
|
|
103
|
+
return {
|
|
104
|
+
type: 'dynamic',
|
|
105
|
+
dynamicType: submessage.dynamicMetadata?.type ?? 0,
|
|
106
|
+
version: submessage.dynamicMetadata?.version ?? 0,
|
|
107
|
+
url: submessage.dynamicMetadata?.url || null,
|
|
108
|
+
loopCount: submessage.dynamicMetadata?.loopCount ?? 0,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
case RichSubMessageType.MAP:
|
|
112
|
+
return {
|
|
113
|
+
type: 'map',
|
|
114
|
+
centerLatitude: submessage.mapMetadata?.centerLatitude ?? 0,
|
|
115
|
+
centerLongitude: submessage.mapMetadata?.centerLongitude ?? 0,
|
|
116
|
+
latitudeDelta: submessage.mapMetadata?.latitudeDelta ?? 0,
|
|
117
|
+
longitudeDelta: submessage.mapMetadata?.longitudeDelta ?? 0,
|
|
118
|
+
showInfoList: submessage.mapMetadata?.showInfoList ?? false,
|
|
119
|
+
annotations: (submessage.mapMetadata?.annotations || []).map(a => ({
|
|
120
|
+
number: a.annotationNumber ?? 0,
|
|
121
|
+
latitude: a.latitude ?? 0,
|
|
122
|
+
longitude: a.longitude ?? 0,
|
|
123
|
+
title: a.title || '',
|
|
124
|
+
body: a.body || '',
|
|
125
|
+
})),
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
case RichSubMessageType.LATEX:
|
|
129
|
+
return {
|
|
130
|
+
type: 'latex',
|
|
131
|
+
text: submessage.latexMetadata?.text || '',
|
|
132
|
+
expressions: (submessage.latexMetadata?.expressions || []).map(e => ({
|
|
133
|
+
expression: e.latexExpression || '',
|
|
134
|
+
url: e.url || null,
|
|
135
|
+
width: e.width ?? 0,
|
|
136
|
+
height: e.height ?? 0,
|
|
137
|
+
})),
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
case RichSubMessageType.CONTENT_ITEMS:
|
|
141
|
+
return {
|
|
142
|
+
type: 'contentItems',
|
|
143
|
+
contentType: submessage.contentItemsMetadata?.contentType ?? 0,
|
|
144
|
+
items: (submessage.contentItemsMetadata?.itemsMetadata || []).map(item => {
|
|
145
|
+
if (item.reelItem) {
|
|
146
|
+
return {
|
|
147
|
+
kind: 'reel',
|
|
148
|
+
title: item.reelItem.title || '',
|
|
149
|
+
profileIconUrl: item.reelItem.profileIconUrl || null,
|
|
150
|
+
thumbnailUrl: item.reelItem.thumbnailUrl || null,
|
|
151
|
+
videoUrl: item.reelItem.videoUrl || null,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return { kind: 'unknown' };
|
|
155
|
+
}),
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
default:
|
|
159
|
+
return { type: 'unknown', raw: submessage };
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Parse seluruh AIRichResponseMessage menjadi array parsed submessages.
|
|
165
|
+
* Bisa dipanggil langsung dari handler messages.upsert:
|
|
166
|
+
*
|
|
167
|
+
* const inner = normalizeMessageContent(msg.message)
|
|
168
|
+
* const parsed = parseRichMessage(inner?.richResponseMessage)
|
|
169
|
+
*/
|
|
170
|
+
export const parseRichMessage = (richResponseMessage) => {
|
|
171
|
+
if (!richResponseMessage) return null;
|
|
172
|
+
|
|
173
|
+
const submessages = (richResponseMessage.submessages || [])
|
|
174
|
+
.map(parseRichSubMessage)
|
|
175
|
+
.filter(Boolean);
|
|
176
|
+
|
|
177
|
+
let unifiedData = null;
|
|
178
|
+
if (richResponseMessage.unifiedResponse?.data) {
|
|
179
|
+
try {
|
|
180
|
+
const buf = richResponseMessage.unifiedResponse.data;
|
|
181
|
+
unifiedData = JSON.parse(Buffer.isBuffer(buf) ? buf.toString('utf-8') : Buffer.from(buf).toString('utf-8'));
|
|
182
|
+
} catch (_) { /* ignore parse error */ }
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
messageType: richResponseMessage.messageType ?? 0,
|
|
187
|
+
submessages,
|
|
188
|
+
unifiedData,
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
/* ─────────────────────────────────────────────────────────────
|
|
193
|
+
OUTGOING BUILDER — unified response JSON per subtype
|
|
194
|
+
───────────────────────────────────────────────────────────── */
|
|
195
|
+
|
|
196
|
+
const buildUnifiedSection = (submessage) => {
|
|
197
|
+
switch (submessage.messageType) {
|
|
198
|
+
case RichSubMessageType.TEXT:
|
|
199
|
+
return {
|
|
200
|
+
view_model: {
|
|
201
|
+
primitive: {
|
|
202
|
+
text: submessage.messageText,
|
|
203
|
+
inline_entities: submessage.inlineEntities || [],
|
|
204
|
+
__typename: 'GenAIMarkdownTextUXPrimitive'
|
|
205
|
+
},
|
|
206
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
case RichSubMessageType.CODE: {
|
|
211
|
+
const cm = submessage.codeMetadata;
|
|
212
|
+
return {
|
|
213
|
+
view_model: {
|
|
214
|
+
primitive: {
|
|
215
|
+
language: cm.codeLanguage,
|
|
216
|
+
code_blocks: cm.codeBlocks.map(b => ({
|
|
217
|
+
content: b.codeContent,
|
|
218
|
+
type: CodeHighlightType[b.highlightType]
|
|
219
|
+
})),
|
|
220
|
+
__typename: 'GenAICodeUXPrimitive'
|
|
221
|
+
},
|
|
222
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
case RichSubMessageType.TABLE: {
|
|
228
|
+
const tm = submessage.tableMetadata;
|
|
229
|
+
return {
|
|
230
|
+
view_model: {
|
|
231
|
+
primitive: {
|
|
232
|
+
title: tm.title,
|
|
233
|
+
rows: tm.rows.map(row => ({
|
|
234
|
+
is_header: row.isHeading,
|
|
235
|
+
cells: row.items,
|
|
236
|
+
markdown_cells: row.items.map(item => ({ text: item }))
|
|
237
|
+
})),
|
|
238
|
+
__typename: 'GenATableUXPrimitive'
|
|
239
|
+
},
|
|
240
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
case RichSubMessageType.GRID_IMAGE: {
|
|
246
|
+
const gm = submessage.gridImageMetadata;
|
|
247
|
+
return {
|
|
248
|
+
view_model: {
|
|
249
|
+
primitive: {
|
|
250
|
+
grid_image_url: gm.gridImageUrl,
|
|
251
|
+
image_urls: gm.imageUrls,
|
|
252
|
+
__typename: 'GenAIGridImageUXPrimitive'
|
|
253
|
+
},
|
|
254
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
case RichSubMessageType.INLINE_IMAGE: {
|
|
260
|
+
const im = submessage.imageMetadata;
|
|
261
|
+
return {
|
|
262
|
+
view_model: {
|
|
263
|
+
primitive: {
|
|
264
|
+
image_url: im.imageUrl,
|
|
265
|
+
image_text: im.imageText,
|
|
266
|
+
alignment: im.alignment ?? 0,
|
|
267
|
+
tap_link_url: im.tapLinkUrl || null,
|
|
268
|
+
__typename: 'GenAIInlineImageUXPrimitive'
|
|
269
|
+
},
|
|
270
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
case RichSubMessageType.DYNAMIC: {
|
|
276
|
+
const dm = submessage.dynamicMetadata;
|
|
277
|
+
return {
|
|
278
|
+
view_model: {
|
|
279
|
+
primitive: {
|
|
280
|
+
type: dm.type ?? 0,
|
|
281
|
+
version: dm.version ?? 0,
|
|
282
|
+
url: dm.url,
|
|
283
|
+
loop_count: dm.loopCount ?? 0,
|
|
284
|
+
__typename: 'GenAIDynamicUXPrimitive'
|
|
285
|
+
},
|
|
286
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
case RichSubMessageType.MAP: {
|
|
292
|
+
const mm = submessage.mapMetadata;
|
|
293
|
+
return {
|
|
294
|
+
view_model: {
|
|
295
|
+
primitive: {
|
|
296
|
+
center_latitude: mm.centerLatitude,
|
|
297
|
+
center_longitude: mm.centerLongitude,
|
|
298
|
+
latitude_delta: mm.latitudeDelta,
|
|
299
|
+
longitude_delta: mm.longitudeDelta,
|
|
300
|
+
show_info_list: mm.showInfoList ?? false,
|
|
301
|
+
annotations: (mm.annotations || []).map(a => ({
|
|
302
|
+
annotation_number: a.annotationNumber,
|
|
303
|
+
latitude: a.latitude,
|
|
304
|
+
longitude: a.longitude,
|
|
305
|
+
title: a.title,
|
|
306
|
+
body: a.body
|
|
307
|
+
})),
|
|
308
|
+
__typename: 'GenAIMapUXPrimitive'
|
|
309
|
+
},
|
|
310
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
case RichSubMessageType.LATEX: {
|
|
316
|
+
const lm = submessage.latexMetadata;
|
|
317
|
+
return {
|
|
318
|
+
view_model: {
|
|
319
|
+
primitive: {
|
|
320
|
+
text: lm.text,
|
|
321
|
+
expressions: (lm.expressions || []).map(e => ({
|
|
322
|
+
latex_expression: e.latexExpression,
|
|
323
|
+
url: e.url,
|
|
324
|
+
width: e.width,
|
|
325
|
+
height: e.height,
|
|
326
|
+
font_height: e.fontHeight,
|
|
327
|
+
image_top_padding: e.imageTopPadding,
|
|
328
|
+
image_leading_padding: e.imageLeadingPadding,
|
|
329
|
+
image_bottom_padding: e.imageBottomPadding,
|
|
330
|
+
image_trailing_padding: e.imageTrailingPadding
|
|
331
|
+
})),
|
|
332
|
+
__typename: 'GenAILatexUXPrimitive'
|
|
333
|
+
},
|
|
334
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
case RichSubMessageType.CONTENT_ITEMS: {
|
|
340
|
+
const ci = submessage.contentItemsMetadata;
|
|
341
|
+
return {
|
|
342
|
+
view_model: {
|
|
343
|
+
primitive: {
|
|
344
|
+
content_type: ci.contentType ?? 0,
|
|
345
|
+
items_metadata: (ci.itemsMetadata || []).map(item => {
|
|
346
|
+
if (item.reelItem) {
|
|
347
|
+
return {
|
|
348
|
+
reel_item: {
|
|
349
|
+
title: item.reelItem.title,
|
|
350
|
+
profile_icon_url: item.reelItem.profileIconUrl,
|
|
351
|
+
thumbnail_url: item.reelItem.thumbnailUrl,
|
|
352
|
+
video_url: item.reelItem.videoUrl
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
return {};
|
|
357
|
+
}),
|
|
358
|
+
__typename: 'GenAIContentItemsUXPrimitive'
|
|
359
|
+
},
|
|
360
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
default:
|
|
366
|
+
return submessage;
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
|
|
41
370
|
export const toUnified = (submessages) => ({
|
|
42
371
|
response_id: randomUUID(),
|
|
43
|
-
sections: submessages.map(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
372
|
+
sections: submessages.map(buildUnifiedSection)
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
/* ─────────────────────────────────────────────────────────────
|
|
376
|
+
PREPARE HELPERS — builder per tipe submessage
|
|
377
|
+
───────────────────────────────────────────────────────────── */
|
|
378
|
+
|
|
379
|
+
/** Buat submessage TEXT */
|
|
380
|
+
const makeTextSub = (text, inlineEntities) => ({
|
|
381
|
+
messageType: RichSubMessageType.TEXT,
|
|
382
|
+
messageText: text,
|
|
383
|
+
...(inlineEntities ? { inlineEntities } : {})
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
/** Buat submessage CODE dengan auto-tokenize */
|
|
387
|
+
const makeCodeSub = (code, language = 'javascript') => ({
|
|
388
|
+
messageType: RichSubMessageType.CODE,
|
|
389
|
+
codeMetadata: {
|
|
390
|
+
codeLanguage: language,
|
|
391
|
+
codeBlocks: tokenizeCode(code, language)
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
/** Buat submessage TABLE */
|
|
396
|
+
const makeTableSub = (rows, title, noHeading) => ({
|
|
397
|
+
messageType: RichSubMessageType.TABLE,
|
|
398
|
+
tableMetadata: {
|
|
399
|
+
title: title || '',
|
|
400
|
+
rows: rows.map((items, i) => ({
|
|
401
|
+
isHeading: !noHeading && i === 0,
|
|
402
|
+
items
|
|
403
|
+
}))
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
/** Buat submessage GRID_IMAGE */
|
|
408
|
+
const makeGridImageSub = (gridImageUrl, imageUrls = []) => ({
|
|
409
|
+
messageType: RichSubMessageType.GRID_IMAGE,
|
|
410
|
+
gridImageMetadata: { gridImageUrl, imageUrls }
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
/** Buat submessage INLINE_IMAGE */
|
|
414
|
+
const makeInlineImageSub = (imageUrl, imageText = '', alignment = 0, tapLinkUrl = null) => ({
|
|
415
|
+
messageType: RichSubMessageType.INLINE_IMAGE,
|
|
416
|
+
imageMetadata: { imageUrl, imageText, alignment, tapLinkUrl }
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
/** Buat submessage DYNAMIC (animated image/GIF) */
|
|
420
|
+
const makeDynamicSub = (url, dynamicType = 1, version = 1, loopCount = 0) => ({
|
|
421
|
+
messageType: RichSubMessageType.DYNAMIC,
|
|
422
|
+
dynamicMetadata: { type: dynamicType, version, url, loopCount }
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
/** Buat submessage MAP */
|
|
426
|
+
const makeMapSub = (centerLatitude, centerLongitude, options = {}) => ({
|
|
427
|
+
messageType: RichSubMessageType.MAP,
|
|
428
|
+
mapMetadata: {
|
|
429
|
+
centerLatitude,
|
|
430
|
+
centerLongitude,
|
|
431
|
+
latitudeDelta: options.latitudeDelta ?? 0.05,
|
|
432
|
+
longitudeDelta: options.longitudeDelta ?? 0.05,
|
|
433
|
+
showInfoList: options.showInfoList ?? false,
|
|
434
|
+
annotations: (options.annotations || []).map((a, i) => ({
|
|
435
|
+
annotationNumber: a.number ?? i + 1,
|
|
436
|
+
latitude: a.latitude,
|
|
437
|
+
longitude: a.longitude,
|
|
438
|
+
title: a.title || '',
|
|
439
|
+
body: a.body || ''
|
|
440
|
+
}))
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
/** Buat submessage LATEX */
|
|
445
|
+
const makeLatexSub = (text, expressions = []) => ({
|
|
446
|
+
messageType: RichSubMessageType.LATEX,
|
|
447
|
+
latexMetadata: {
|
|
448
|
+
text,
|
|
449
|
+
expressions: expressions.map(e => ({
|
|
450
|
+
latexExpression: e.expression || e.latexExpression || '',
|
|
451
|
+
url: e.url || null,
|
|
452
|
+
width: e.width ?? 0,
|
|
453
|
+
height: e.height ?? 0,
|
|
454
|
+
fontHeight: e.fontHeight ?? 0,
|
|
455
|
+
imageTopPadding: e.imageTopPadding ?? 0,
|
|
456
|
+
imageLeadingPadding: e.imageLeadingPadding ?? 0,
|
|
457
|
+
imageBottomPadding: e.imageBottomPadding ?? 0,
|
|
458
|
+
imageTrailingPadding: e.imageTrailingPadding ?? 0
|
|
459
|
+
}))
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
/** Buat submessage CONTENT_ITEMS (carousel reel) */
|
|
464
|
+
const makeContentItemsSub = (items, contentType = 0) => ({
|
|
465
|
+
messageType: RichSubMessageType.CONTENT_ITEMS,
|
|
466
|
+
contentItemsMetadata: {
|
|
467
|
+
contentType,
|
|
468
|
+
itemsMetadata: items.map(item => {
|
|
469
|
+
if (item.reelItem || item.kind === 'reel') {
|
|
470
|
+
const r = item.reelItem || item;
|
|
74
471
|
return {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
},
|
|
81
|
-
__typename: 'GenAISingleLayoutViewModel'
|
|
472
|
+
reelItem: {
|
|
473
|
+
title: r.title || '',
|
|
474
|
+
profileIconUrl: r.profileIconUrl || null,
|
|
475
|
+
thumbnailUrl: r.thumbnailUrl || null,
|
|
476
|
+
videoUrl: r.videoUrl || null
|
|
82
477
|
}
|
|
83
478
|
};
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
479
|
+
}
|
|
480
|
+
return {};
|
|
481
|
+
})
|
|
482
|
+
}
|
|
87
483
|
});
|
|
484
|
+
|
|
485
|
+
/* ─────────────────────────────────────────────────────────────
|
|
486
|
+
MAIN BUILDER — prepareRichResponseMessage
|
|
487
|
+
───────────────────────────────────────────────────────────── */
|
|
488
|
+
|
|
88
489
|
export const prepareRichResponseMessage = (content) => {
|
|
89
|
-
const {
|
|
490
|
+
const {
|
|
491
|
+
code, contentText, disclaimerText, footerText, headerText,
|
|
492
|
+
language, links, noHeading, richResponse, table, title,
|
|
493
|
+
// sub-types baru
|
|
494
|
+
gridImage, inlineImage, dynamic: dynamicContent,
|
|
495
|
+
map: mapContent, latex, contentItems
|
|
496
|
+
} = content;
|
|
497
|
+
|
|
90
498
|
let submessages = [];
|
|
499
|
+
|
|
500
|
+
/* ── mode array (richResponse) — multi-section campuran ── */
|
|
91
501
|
if (Array.isArray(richResponse)) {
|
|
92
|
-
submessages = richResponse.map(
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
tableMetadata: {
|
|
113
|
-
title: submessage.title,
|
|
114
|
-
rows: submessage.table
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
return submessage;
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
if (headerText) {
|
|
123
|
-
submessages.push({
|
|
124
|
-
messageType: RichSubMessageType.TEXT,
|
|
125
|
-
messageText: headerText
|
|
126
|
-
});
|
|
502
|
+
submessages = richResponse.map(sub => {
|
|
503
|
+
if (sub.text != null) return makeTextSub(sub.text, sub.inlineEntities);
|
|
504
|
+
if (sub.code != null) return makeCodeSub(sub.code, sub.language || 'javascript');
|
|
505
|
+
if (sub.table != null) return makeTableSub(sub.table, sub.title, sub.noHeading);
|
|
506
|
+
if (sub.gridImage != null) return makeGridImageSub(sub.gridImage.gridImageUrl, sub.gridImage.imageUrls);
|
|
507
|
+
if (sub.inlineImage != null) return makeInlineImageSub(sub.inlineImage.imageUrl, sub.inlineImage.imageText, sub.inlineImage.alignment, sub.inlineImage.tapLinkUrl);
|
|
508
|
+
if (sub.dynamic != null) return makeDynamicSub(sub.dynamic.url, sub.dynamic.type, sub.dynamic.version, sub.dynamic.loopCount);
|
|
509
|
+
if (sub.map != null) return makeMapSub(sub.map.centerLatitude, sub.map.centerLongitude, sub.map);
|
|
510
|
+
if (sub.latex != null) return makeLatexSub(sub.latex.text, sub.latex.expressions);
|
|
511
|
+
if (sub.contentItems != null) return makeContentItemsSub(sub.contentItems.items, sub.contentItems.contentType);
|
|
512
|
+
return sub; // passthrough kalau sudah bentuk proto
|
|
513
|
+
}).filter(Boolean);
|
|
514
|
+
|
|
515
|
+
/* ── mode flat (convenience fields) ── */
|
|
516
|
+
} else {
|
|
517
|
+
if (headerText) submessages.push(makeTextSub(headerText));
|
|
518
|
+
if (contentText) submessages.push(makeTextSub(contentText));
|
|
519
|
+
|
|
520
|
+
if (code) {
|
|
521
|
+
submessages.push(makeCodeSub(code, language || 'javascript'));
|
|
127
522
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
messageText: contentText
|
|
132
|
-
});
|
|
523
|
+
|
|
524
|
+
if (table) {
|
|
525
|
+
submessages.push(makeTableSub(table, title, noHeading));
|
|
133
526
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
submessages.push(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
});
|
|
527
|
+
|
|
528
|
+
if (gridImage) {
|
|
529
|
+
submessages.push(makeGridImageSub(gridImage.gridImageUrl, gridImage.imageUrls));
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (inlineImage) {
|
|
533
|
+
submessages.push(makeInlineImageSub(inlineImage.imageUrl, inlineImage.imageText, inlineImage.alignment, inlineImage.tapLinkUrl));
|
|
143
534
|
}
|
|
144
|
-
|
|
535
|
+
|
|
536
|
+
if (dynamicContent) {
|
|
537
|
+
submessages.push(makeDynamicSub(dynamicContent.url, dynamicContent.type, dynamicContent.version, dynamicContent.loopCount));
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (mapContent) {
|
|
541
|
+
submessages.push(makeMapSub(mapContent.centerLatitude, mapContent.centerLongitude, mapContent));
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
if (latex) {
|
|
545
|
+
submessages.push(makeLatexSub(latex.text, latex.expressions));
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (contentItems) {
|
|
549
|
+
submessages.push(makeContentItemsSub(contentItems.items, contentItems.contentType));
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/* links — bisa dikombinasi dengan tipe lain di atas */
|
|
553
|
+
if (links && Array.isArray(links)) {
|
|
145
554
|
links.forEach((linkField, index) => {
|
|
146
555
|
const prefix = 'SS_' + index;
|
|
147
556
|
const url = linkField.url || DONATE_URL;
|
|
148
|
-
const sources = linkField.sources
|
|
557
|
+
const sources = (linkField.sources || []).map(s => ({
|
|
149
558
|
source_type: 'THIRD_PARTY',
|
|
150
|
-
source_display_name:
|
|
151
|
-
source_subtitle:
|
|
152
|
-
source_url:
|
|
559
|
+
source_display_name: s.displayName || 'Source',
|
|
560
|
+
source_subtitle: s.subtitle || '',
|
|
561
|
+
source_url: s.url || url
|
|
153
562
|
}));
|
|
154
|
-
submessages.push(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
else if (table) {
|
|
172
|
-
submessages.push({
|
|
173
|
-
messageType: RichSubMessageType.TABLE,
|
|
174
|
-
tableMetadata: {
|
|
175
|
-
title,
|
|
176
|
-
rows: table.map((items, index) => ({
|
|
177
|
-
isHeading: !noHeading && index == 0,
|
|
178
|
-
items
|
|
179
|
-
}))
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
if (footerText) {
|
|
184
|
-
submessages.push({
|
|
185
|
-
messageType: RichSubMessageType.TEXT,
|
|
186
|
-
messageText: footerText
|
|
563
|
+
submessages.push(makeTextSub(
|
|
564
|
+
linkField.text + ` {{${prefix}}}¹{{/${prefix}}} `,
|
|
565
|
+
[{
|
|
566
|
+
key: prefix,
|
|
567
|
+
metadata: {
|
|
568
|
+
reference_id: index + 1,
|
|
569
|
+
reference_url: url,
|
|
570
|
+
reference_title: linkField.title || url,
|
|
571
|
+
reference_display_name: linkField.displayName || url,
|
|
572
|
+
sources,
|
|
573
|
+
__typename: 'GenAISearchCitationItem'
|
|
574
|
+
}
|
|
575
|
+
}]
|
|
576
|
+
));
|
|
187
577
|
});
|
|
188
578
|
}
|
|
579
|
+
|
|
580
|
+
if (footerText) submessages.push(makeTextSub(footerText));
|
|
189
581
|
}
|
|
582
|
+
|
|
583
|
+
/* build unifiedResponse JSON */
|
|
190
584
|
const unified = toUnified(submessages);
|
|
585
|
+
|
|
191
586
|
const richResponseMessage = proto.AIRichResponseMessage.create({
|
|
192
587
|
submessages,
|
|
193
588
|
messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
|
|
@@ -201,19 +596,28 @@ export const prepareRichResponseMessage = (content) => {
|
|
|
201
596
|
forwardOrigin: 4
|
|
202
597
|
}
|
|
203
598
|
});
|
|
599
|
+
|
|
204
600
|
const message = wrapToBotForwardedMessage(richResponseMessage);
|
|
205
601
|
const botMetadata = message.messageContextInfo.botMetadata;
|
|
602
|
+
|
|
206
603
|
if (disclaimerText) {
|
|
207
604
|
botMetadata.messageDisclaimerText = disclaimerText;
|
|
208
605
|
}
|
|
209
606
|
botMetadata.botResponseId = unified.response_id;
|
|
607
|
+
|
|
210
608
|
return message;
|
|
211
609
|
};
|
|
610
|
+
|
|
611
|
+
/* ─────────────────────────────────────────────────────────────
|
|
612
|
+
BOT WRAPPER HELPERS
|
|
613
|
+
───────────────────────────────────────────────────────────── */
|
|
614
|
+
|
|
212
615
|
export const botMetadataSignature = () => {
|
|
213
616
|
const signature = new Uint8Array(64);
|
|
214
617
|
getRandomValues(signature);
|
|
215
618
|
return signature;
|
|
216
619
|
};
|
|
620
|
+
|
|
217
621
|
export const botMetadataCertificate = (length = 685) => {
|
|
218
622
|
const certificate = new Uint8Array(length);
|
|
219
623
|
certificate[0] = 48;
|
|
@@ -221,6 +625,7 @@ export const botMetadataCertificate = (length = 685) => {
|
|
|
221
625
|
getRandomValues(certificate.subarray(2));
|
|
222
626
|
return certificate;
|
|
223
627
|
};
|
|
628
|
+
|
|
224
629
|
export const wrapToBotForwardedMessage = (richResponseMessage) => ({
|
|
225
630
|
messageContextInfo: {
|
|
226
631
|
botMetadata: {
|
|
@@ -243,4 +648,4 @@ export const wrapToBotForwardedMessage = (richResponseMessage) => ({
|
|
|
243
648
|
message: { richResponseMessage }
|
|
244
649
|
}
|
|
245
650
|
});
|
|
246
|
-
//# sourceMappingURL=rich-message-utils.js.map
|
|
651
|
+
//# sourceMappingURL=rich-message-utils.js.map
|