plogme 2.0.1 → 2.0.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.
|
@@ -5,7 +5,7 @@ import { proto } from '../../WAProto/index.js';
|
|
|
5
5
|
import { BIZ_BOT_SUPPORT_PAYLOAD, DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
|
|
6
6
|
import { aggregateMessageKeysNotFromMe, assertMediaContent, assertMeId, bindWaitForEvent, buildLinkPreview, decryptMediaRetryData, DEF_MEDIA_HOST, delay, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, extractImageThumb, generateMessageIDV2, generateParticipantHashV2, generateWAMessage, generateWAMessageFromContent, getStatusCodeForMediaRetry, makeWhatsAppFlowButton, getUrlFromDirectPath, getWAUploadToServer, hasValidAlbumMedia, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, prepareWAMessageMedia, shouldIncludeBizBinaryNode, unixTimestampSeconds } from '../Utils/index.js';
|
|
7
7
|
import { getUrlInfo } from '../Utils/link-preview.js';
|
|
8
|
-
import { prepareRichMenuMessage, prepareRichResponseMessage, prepareRichGenerationMessage, prepareCopyToClipboardMessage, prepareRichTextMessage, prepareRichQuoteMessage, prepareRichImageMessage, prepareRichLinkMessage, prepareHtmlMessage, prepareRichHtmlMessage } from '../Utils/rich-message-utils.js';
|
|
8
|
+
import { prepareRichMenuMessage, prepareRichResponseMessage, prepareRichGenerationMessage, prepareCopyToClipboardMessage, prepareRichTextMessage, prepareRichQuoteMessage, prepareRichImageMessage, prepareRichLinkMessage, prepareHtmlMessage, prepareRichHtmlMessage, attachBotVerificationProofs, hasVerifiableProofs } from '../Utils/rich-message-utils.js';
|
|
9
9
|
import { generateSlotMachineHtml } from '../Utils/games/slot-machine.js';
|
|
10
10
|
import { generateMiniAppHtml } from '../Utils/games/miniapp.js';
|
|
11
11
|
import { generateWebsitePreviewHtml, generateLinkPreviewHtml } from '../Utils/games/website-preview.js';
|
|
@@ -555,7 +555,18 @@ export const makeMessagesSocket = (config) => {
|
|
|
555
555
|
};
|
|
556
556
|
}
|
|
557
557
|
const applyForwarded = m => {
|
|
558
|
+
// Auto-inject trusted verification proofs configured once on the socket
|
|
559
|
+
// (config.metaAiRendering.verificationMetadata). Per-message proofs win:
|
|
560
|
+
// an envelope that already carries verificationMetadata is left untouched.
|
|
561
|
+
// The second target covers edited rich envelopes (protocolMessage.editedMessage,
|
|
562
|
+
// used by updateRichGeneration) so an in-place rich update keeps its proofs too.
|
|
563
|
+
const edited = m?.botForwardedMessage?.message?.protocolMessage?.editedMessage;
|
|
558
564
|
const rich = m?.botForwardedMessage?.message?.richResponseMessage || m?.richResponseMessage;
|
|
565
|
+
if (!rich && !edited) return m;
|
|
566
|
+
if (hasVerifiableProofs(config?.metaAiRendering?.verificationMetadata)) {
|
|
567
|
+
attachBotVerificationProofs(m, config.metaAiRendering.verificationMetadata);
|
|
568
|
+
attachBotVerificationProofs(edited, config.metaAiRendering.verificationMetadata);
|
|
569
|
+
}
|
|
559
570
|
if (!rich) return m;
|
|
560
571
|
rich.contextInfo = { ...rich.contextInfo, isForwarded: true, forwardOrigin: 4 };
|
|
561
572
|
return m.botForwardedMessage ? m : { botForwardedMessage: { message: m } };
|
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
buildPlainPlaceholder,
|
|
25
25
|
PlanningStepStatus
|
|
26
26
|
} from './meta-compositing.js';
|
|
27
|
-
import { botMetadataSignature, botMetadataCertificate } from './rich-message-utils.js';
|
|
28
27
|
import { BOT_RENDERING_CONFIG_METADATA } from '../Defaults/index.js';
|
|
29
28
|
import { delay } from './generics.js';
|
|
30
29
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* If you use or copy this code, please credit my name or project. AND DO NOT CHANGE THIS NOTE
|
|
6
6
|
*/
|
|
7
7
|
import { getRandomValues, randomUUID, randomBytes } from 'crypto';
|
|
8
|
-
import { DONATE_URL, LEXER_REGEX } from '../Defaults/index.js';
|
|
8
|
+
import { BOT_RENDERING_CONFIG_METADATA, DONATE_URL, LEXER_REGEX } from '../Defaults/index.js';
|
|
9
9
|
import { LANGUAGE_KEYWORDS } from '../WABinary/constants.js';
|
|
10
10
|
import { CodeHighlightType, RichSubMessageType } from '../Types/RichType.js';
|
|
11
11
|
import { proto } from '../../WAProto/index.js';
|
|
@@ -196,7 +196,8 @@ export const prepareRichGenerationMessage = ({
|
|
|
196
196
|
estimatedMs,
|
|
197
197
|
itemId = `imagine_${randomUUID()}`,
|
|
198
198
|
responseId = randomUUID(),
|
|
199
|
-
forwarded = true
|
|
199
|
+
forwarded = true,
|
|
200
|
+
verificationMetadata
|
|
200
201
|
} = {}) => {
|
|
201
202
|
const sections = [];
|
|
202
203
|
if (text) {
|
|
@@ -210,7 +211,7 @@ export const prepareRichGenerationMessage = ({
|
|
|
210
211
|
unifiedResponse: { data: Buffer.from(JSON.stringify({ response_id: responseId, sections })) },
|
|
211
212
|
contextInfo: forwarded ? { isForwarded: true, forwardingScore: 1, forwardedAiBotMessageInfo: { botJid: '867051314767696@bot' }, forwardOrigin: 4 } : {}
|
|
212
213
|
});
|
|
213
|
-
const message = wrapToBotForwardedMessage(richResponseMessage);
|
|
214
|
+
const message = wrapToBotForwardedMessage(richResponseMessage, verificationMetadata);
|
|
214
215
|
message.messageContextInfo = message.messageContextInfo || {};
|
|
215
216
|
message.messageContextInfo.botMetadata = {
|
|
216
217
|
...(message.messageContextInfo.botMetadata || {}),
|
|
@@ -220,56 +221,72 @@ export const prepareRichGenerationMessage = ({
|
|
|
220
221
|
};
|
|
221
222
|
|
|
222
223
|
// Lia@Note 17-04-26 --- WIP
|
|
224
|
+
/**
|
|
225
|
+
* A preview-media descriptor is only meaningful when the client can locate and
|
|
226
|
+
* decrypt the media. A descriptor without a key, hash and direct path describes
|
|
227
|
+
* media that cannot be fetched, so it is dropped rather than shipped
|
|
228
|
+
* present-but-empty (which is what previously produced `''` crypto fields and a
|
|
229
|
+
* hard-coded `image/jpeg` mimetype on every reel).
|
|
230
|
+
*
|
|
231
|
+
* Callers that upload real media supply it as `previewMedia` on the reel item or
|
|
232
|
+
* LaTeX expression: `{ fileSha256, mediaKey, fileEncSha256, directPath, mimetype?, mediaKeyTimestamp?, mediaId? }`.
|
|
233
|
+
*/
|
|
234
|
+
const normalizePreviewMedia = (media) => {
|
|
235
|
+
if (!media || typeof media !== 'object') return null;
|
|
236
|
+
const { fileSha256, mediaKey, fileEncSha256, directPath, mimetype, mediaKeyTimestamp } = media;
|
|
237
|
+
if (!fileSha256 || !mediaKey || !fileEncSha256 || !directPath) return null;
|
|
238
|
+
return {
|
|
239
|
+
fileSha256,
|
|
240
|
+
mediaKey,
|
|
241
|
+
fileEncSha256,
|
|
242
|
+
directPath,
|
|
243
|
+
mediaKeyTimestamp: mediaKeyTimestamp ?? unixTimestampSeconds(),
|
|
244
|
+
mimetype: mimetype || 'image/jpeg'
|
|
245
|
+
};
|
|
246
|
+
};
|
|
247
|
+
|
|
223
248
|
export const buildAdditionalBotMetadataContext = (submessages) => {
|
|
224
249
|
const sources = [];
|
|
225
250
|
const mediaDetailsMetadataList = [];
|
|
226
|
-
for (
|
|
227
|
-
const submessage = submessages[i];
|
|
251
|
+
for (const submessage of submessages) {
|
|
228
252
|
switch (submessage.messageType) {
|
|
229
253
|
case RichSubMessageType.CONTENT_ITEMS: {
|
|
230
254
|
const itemsMetadata = submessage.contentItemsMetadata?.itemsMetadata || [];
|
|
231
|
-
for (
|
|
232
|
-
const reelItem =
|
|
255
|
+
for (const item of itemsMetadata) {
|
|
256
|
+
const reelItem = item?.reelItem || item || {};
|
|
233
257
|
sources.push({
|
|
234
258
|
provider: 0,
|
|
235
259
|
thumbnailCdnUrl: reelItem.thumbnailUrl || reelItem.thumbnail_url || '',
|
|
236
260
|
sourceProviderUrl: reelItem.videoUrl || reelItem.reels_url || reelItem.url || '',
|
|
237
261
|
sourceQuery: '',
|
|
238
262
|
faviconCdnUrl: reelItem.profileIconUrl || reelItem.avatar_url || '',
|
|
239
|
-
|
|
263
|
+
// 1-based source ordinal, not the submessage index.
|
|
264
|
+
citationNumber: sources.length + 1,
|
|
240
265
|
sourceTitle: reelItem.title || reelItem.reels_title || reelItem.creator || ''
|
|
241
266
|
});
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
mediaKeyTimestamp: unixTimestampSeconds(),
|
|
250
|
-
mimetype: 'image/jpeg'
|
|
251
|
-
}
|
|
252
|
-
});
|
|
267
|
+
const previewMedia = normalizePreviewMedia(reelItem.previewMedia);
|
|
268
|
+
if (previewMedia) {
|
|
269
|
+
mediaDetailsMetadataList.push({
|
|
270
|
+
id: reelItem.mediaId || reelItem.previewMedia?.mediaId || randomBytes(32).toString('hex'),
|
|
271
|
+
previewMedia
|
|
272
|
+
});
|
|
273
|
+
}
|
|
253
274
|
}
|
|
254
275
|
break;
|
|
255
276
|
}
|
|
256
|
-
case RichSubMessageType.LATEX:
|
|
257
|
-
const expressions = submessage.latexMetadata
|
|
258
|
-
for (
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
directPath: '',
|
|
267
|
-
mediaKeyTimestamp: unixTimestampSeconds(),
|
|
268
|
-
mimetype: 'image/jpeg'
|
|
269
|
-
}
|
|
270
|
-
});
|
|
277
|
+
case RichSubMessageType.LATEX: {
|
|
278
|
+
const expressions = submessage.latexMetadata?.expressions || [];
|
|
279
|
+
for (const expression of expressions) {
|
|
280
|
+
const previewMedia = normalizePreviewMedia(expression?.previewMedia);
|
|
281
|
+
if (previewMedia) {
|
|
282
|
+
mediaDetailsMetadataList.push({
|
|
283
|
+
id: expression.mediaId || expression.previewMedia?.mediaId || randomBytes(32).toString('hex'),
|
|
284
|
+
previewMedia
|
|
285
|
+
});
|
|
286
|
+
}
|
|
271
287
|
}
|
|
272
288
|
break;
|
|
289
|
+
}
|
|
273
290
|
}
|
|
274
291
|
}
|
|
275
292
|
return { sources, mediaDetailsMetadataList };
|
|
@@ -336,7 +353,7 @@ const richMenuButton = (button, toast = '') => {
|
|
|
336
353
|
* buttonsMessage/nativeFlowMessage payload.
|
|
337
354
|
*/
|
|
338
355
|
export const prepareRichMenuMessage = (content = {}) => {
|
|
339
|
-
const { header = {}, body = {}, footer = {} } = content || {};
|
|
356
|
+
const { header = {}, body = {}, footer = {}, verificationMetadata } = content || {};
|
|
340
357
|
const sections = [];
|
|
341
358
|
const title = header?.title || '';
|
|
342
359
|
if (title) {
|
|
@@ -418,7 +435,7 @@ export const prepareRichMenuMessage = (content = {}) => {
|
|
|
418
435
|
unifiedResponse: { data: Buffer.from(JSON.stringify(unified)) },
|
|
419
436
|
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 },
|
|
420
437
|
});
|
|
421
|
-
return wrapToBotForwardedMessage(richResponseMessage);
|
|
438
|
+
return wrapToBotForwardedMessage(richResponseMessage, verificationMetadata);
|
|
422
439
|
};
|
|
423
440
|
|
|
424
441
|
/**
|
|
@@ -432,7 +449,7 @@ export const prepareRichMenuMessage = (content = {}) => {
|
|
|
432
449
|
* @returns {Object} Wrapped botForwardedMessage ready for relayMessage
|
|
433
450
|
*/
|
|
434
451
|
export const prepareCopyToClipboardMessage = (options = {}) => {
|
|
435
|
-
const { text = '', label, alignment = 'END' } = options;
|
|
452
|
+
const { text = '', label, alignment = 'END', verificationMetadata } = options;
|
|
436
453
|
const displayText = label || text;
|
|
437
454
|
const sections = [
|
|
438
455
|
{
|
|
@@ -458,7 +475,7 @@ export const prepareCopyToClipboardMessage = (options = {}) => {
|
|
|
458
475
|
unifiedResponse: { data: Buffer.from(JSON.stringify(unified)) },
|
|
459
476
|
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 },
|
|
460
477
|
});
|
|
461
|
-
return wrapToBotForwardedMessage(richResponseMessage);
|
|
478
|
+
return wrapToBotForwardedMessage(richResponseMessage, verificationMetadata);
|
|
462
479
|
};
|
|
463
480
|
|
|
464
481
|
/**
|
|
@@ -470,7 +487,7 @@ export const prepareCopyToClipboardMessage = (options = {}) => {
|
|
|
470
487
|
* @returns {Object} Wrapped botForwardedMessage ready for relayMessage
|
|
471
488
|
*/
|
|
472
489
|
export const prepareRichTextMessage = (options = {}) => {
|
|
473
|
-
const { text = '' } = options;
|
|
490
|
+
const { text = '', verificationMetadata } = options;
|
|
474
491
|
const sections = [
|
|
475
492
|
{
|
|
476
493
|
__typename: 'GenAIUnifiedResponseSection',
|
|
@@ -491,12 +508,12 @@ export const prepareRichTextMessage = (options = {}) => {
|
|
|
491
508
|
unifiedResponse: { data: Buffer.from(JSON.stringify(unified)) },
|
|
492
509
|
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 },
|
|
493
510
|
});
|
|
494
|
-
return wrapToBotForwardedMessage(richResponseMessage);
|
|
511
|
+
return wrapToBotForwardedMessage(richResponseMessage, verificationMetadata);
|
|
495
512
|
};
|
|
496
513
|
|
|
497
514
|
/** Builds Markdown text with an optional GenAI COPY_TO_CLIPBOARD action section. */
|
|
498
515
|
export const prepareRichQuoteMessage = (options = {}) => {
|
|
499
|
-
const { text = '', copyText, copyLabel = copyText, alignment = 'END' } = options;
|
|
516
|
+
const { text = '', copyText, copyLabel = copyText, alignment = 'END', verificationMetadata } = options;
|
|
500
517
|
const sections = [{
|
|
501
518
|
__typename: 'GenAIUnifiedResponseSection',
|
|
502
519
|
view_model: {
|
|
@@ -522,7 +539,7 @@ export const prepareRichQuoteMessage = (options = {}) => {
|
|
|
522
539
|
unifiedResponse: { data: Buffer.from(JSON.stringify(unified)) },
|
|
523
540
|
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 },
|
|
524
541
|
});
|
|
525
|
-
return wrapToBotForwardedMessage(richResponseMessage);
|
|
542
|
+
return wrapToBotForwardedMessage(richResponseMessage, verificationMetadata);
|
|
526
543
|
};
|
|
527
544
|
|
|
528
545
|
/**
|
|
@@ -535,7 +552,7 @@ export const prepareRichQuoteMessage = (options = {}) => {
|
|
|
535
552
|
* @returns {Object} Wrapped botForwardedMessage ready for relayMessage
|
|
536
553
|
*/
|
|
537
554
|
export const prepareRichImageMessage = (options = {}) => {
|
|
538
|
-
const { url = '', mimeType = 'image/png' } = options;
|
|
555
|
+
const { url = '', mimeType = 'image/png', verificationMetadata } = options;
|
|
539
556
|
const media = {
|
|
540
557
|
__typename: 'GenAIMediaItem',
|
|
541
558
|
mime_type: mimeType,
|
|
@@ -562,7 +579,7 @@ export const prepareRichImageMessage = (options = {}) => {
|
|
|
562
579
|
unifiedResponse: { data: Buffer.from(JSON.stringify(unified)) },
|
|
563
580
|
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 },
|
|
564
581
|
});
|
|
565
|
-
return wrapToBotForwardedMessage(richResponseMessage);
|
|
582
|
+
return wrapToBotForwardedMessage(richResponseMessage, verificationMetadata);
|
|
566
583
|
};
|
|
567
584
|
|
|
568
585
|
|
|
@@ -575,7 +592,7 @@ export const prepareRichImageMessage = (options = {}) => {
|
|
|
575
592
|
* @returns {Object} Wrapped botForwardedMessage ready for relayMessage
|
|
576
593
|
*/
|
|
577
594
|
export const prepareRichLinkMessage = (options = {}) => {
|
|
578
|
-
const { links = [], text: fallbackText } = options;
|
|
595
|
+
const { links = [], text: fallbackText, verificationMetadata } = options;
|
|
579
596
|
const sections = [];
|
|
580
597
|
const allInlineEntities = [];
|
|
581
598
|
let combinedText = '';
|
|
@@ -629,11 +646,11 @@ export const prepareRichLinkMessage = (options = {}) => {
|
|
|
629
646
|
unifiedResponse: { data: Buffer.from(JSON.stringify(unified)) },
|
|
630
647
|
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 },
|
|
631
648
|
});
|
|
632
|
-
return wrapToBotForwardedMessage(richResponseMessage);
|
|
649
|
+
return wrapToBotForwardedMessage(richResponseMessage, verificationMetadata);
|
|
633
650
|
};
|
|
634
651
|
|
|
635
652
|
export const prepareRichResponseMessage = (content) => {
|
|
636
|
-
const { alignment, code, contentText, disclaimerText, footerText, headerText, imageText, inlineImage, inlineVideo, items, language, latex, links, noDonation, noHeading, posts, products, reels, sources: sourceInputs, suggested, richResponse, table, tapLinkUrl, title } = content;
|
|
653
|
+
const { alignment, code, contentText, disclaimerText, footerText, headerText, imageText, inlineImage, inlineVideo, items, language, latex, links, noDonation, noHeading, posts, products, reels, sources: sourceInputs, suggested, richResponse, table, tapLinkUrl, title, verificationMetadata } = content;
|
|
637
654
|
let submessages = [];
|
|
638
655
|
if (Array.isArray(richResponse)) {
|
|
639
656
|
submessages = richResponse.map((submessage) => {
|
|
@@ -879,7 +896,7 @@ export const prepareRichResponseMessage = (content) => {
|
|
|
879
896
|
forwardOrigin: 4
|
|
880
897
|
}
|
|
881
898
|
});
|
|
882
|
-
const message = wrapToBotForwardedMessage(richResponseMessage);
|
|
899
|
+
const message = wrapToBotForwardedMessage(richResponseMessage, verificationMetadata);
|
|
883
900
|
const botMetadata = message.messageContextInfo.botMetadata;
|
|
884
901
|
// Lia@Note 13-05-26 --- Add disclaimer text on richResponseMessage
|
|
885
902
|
if (disclaimerText) {
|
|
@@ -898,6 +915,11 @@ export const prepareRichResponseMessage = (content) => {
|
|
|
898
915
|
return message;
|
|
899
916
|
};
|
|
900
917
|
// Lia@Note 17-04-26 --- signature and certificateChain for proofs[] field
|
|
918
|
+
/**
|
|
919
|
+
* @deprecated Generates random bytes that verify against nothing. Kept only for
|
|
920
|
+
* experimental tooling; the library no longer attaches generated proofs to
|
|
921
|
+
* messages. Pass real proofs through the `verificationMetadata` option instead.
|
|
922
|
+
*/
|
|
901
923
|
export const botMetadataSignature = () => {
|
|
902
924
|
const signature = new Uint8Array(64);
|
|
903
925
|
getRandomValues(signature);
|
|
@@ -923,7 +945,7 @@ export const botMetadataCertificate = (length = 685) => {
|
|
|
923
945
|
* @returns {Object} Wrapped botForwardedMessage ready for relayMessage
|
|
924
946
|
*/
|
|
925
947
|
export const prepareHtmlMessage = (options = {}) => {
|
|
926
|
-
const { html = '', trustedSources = [] } = options;
|
|
948
|
+
const { html = '', trustedSources = [], verificationMetadata } = options;
|
|
927
949
|
const sections = [
|
|
928
950
|
{
|
|
929
951
|
__typename: 'GenAIUnifiedResponseSection',
|
|
@@ -944,7 +966,7 @@ export const prepareHtmlMessage = (options = {}) => {
|
|
|
944
966
|
unifiedResponse: { data: Buffer.from(JSON.stringify(unified)) },
|
|
945
967
|
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 },
|
|
946
968
|
});
|
|
947
|
-
return wrapToBotForwardedMessage(richResponseMessage);
|
|
969
|
+
return wrapToBotForwardedMessage(richResponseMessage, verificationMetadata);
|
|
948
970
|
};
|
|
949
971
|
|
|
950
972
|
/**
|
|
@@ -959,7 +981,8 @@ export const prepareRichHtmlMessage = (options = {}) => {
|
|
|
959
981
|
url = '',
|
|
960
982
|
title = 'Preview',
|
|
961
983
|
tabHeader = 'HTML',
|
|
962
|
-
tabs
|
|
984
|
+
tabs,
|
|
985
|
+
verificationMetadata
|
|
963
986
|
} = options;
|
|
964
987
|
const tabItems = Array.isArray(tabs) && tabs.length
|
|
965
988
|
? tabs
|
|
@@ -1003,26 +1026,55 @@ export const prepareRichHtmlMessage = (options = {}) => {
|
|
|
1003
1026
|
unifiedResponse: { data: Buffer.from(JSON.stringify(unified)) },
|
|
1004
1027
|
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 }
|
|
1005
1028
|
});
|
|
1006
|
-
return wrapToBotForwardedMessage(richResponseMessage);
|
|
1029
|
+
return wrapToBotForwardedMessage(richResponseMessage, verificationMetadata);
|
|
1007
1030
|
};
|
|
1008
1031
|
|
|
1009
|
-
|
|
1032
|
+
/**
|
|
1033
|
+
* Proofs are forwarded only when the caller supplies real, verifiable proofs.
|
|
1034
|
+
* The library never fabricates a certificate chain or signature: an unverifiable
|
|
1035
|
+
* proof is worse than none, because it asserts provenance the caller cannot back.
|
|
1036
|
+
*/
|
|
1037
|
+
export const hasVerifiableProofs = (verificationMetadata) =>
|
|
1038
|
+
Array.isArray(verificationMetadata?.proofs) && verificationMetadata.proofs.length > 0;
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* Attach trusted verification proofs to an already-built rich envelope.
|
|
1042
|
+
*
|
|
1043
|
+
* Pure, null-safe, and idempotent: returns the envelope untouched when no
|
|
1044
|
+
* verifiable proofs are supplied or when the envelope carries no botMetadata.
|
|
1045
|
+
* Used by the send pipeline (`relayMessage`) to auto-inject proofs configured
|
|
1046
|
+
* once on the socket as `config.metaAiRendering.verificationMetadata`, so every
|
|
1047
|
+
* rich message (menu, reels, rich text/image/link, HTML) is covered without each
|
|
1048
|
+
* send method needing to thread the config through.
|
|
1049
|
+
*/
|
|
1050
|
+
export const attachBotVerificationProofs = (envelope, verificationMetadata) => {
|
|
1051
|
+
if (!envelope || !hasVerifiableProofs(verificationMetadata))
|
|
1052
|
+
return envelope;
|
|
1053
|
+
const botMetadata = envelope?.messageContextInfo?.botMetadata;
|
|
1054
|
+
if (!botMetadata || botMetadata.verificationMetadata)
|
|
1055
|
+
return envelope;
|
|
1056
|
+
botMetadata.verificationMetadata = verificationMetadata;
|
|
1057
|
+
return envelope;
|
|
1058
|
+
};
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
* Wrap a rich response in the bot-forwarded envelope.
|
|
1062
|
+
*
|
|
1063
|
+
* @param {Object} richResponseMessage - proto.AIRichResponseMessage
|
|
1064
|
+
* @param {Object} [verificationMetadata] - Trusted proofs supplied by the caller
|
|
1065
|
+
* (typically `config.metaAiRendering.verificationMetadata`). Omitted when absent
|
|
1066
|
+
* or empty, so no fabricated provenance is ever sent.
|
|
1067
|
+
*/
|
|
1068
|
+
export const wrapToBotForwardedMessage = (richResponseMessage, verificationMetadata) => ({
|
|
1010
1069
|
messageContextInfo: {
|
|
1011
1070
|
botMetadata: {
|
|
1012
|
-
|
|
1013
|
-
verificationMetadata: {
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
],
|
|
1020
|
-
version: 1,
|
|
1021
|
-
useCase: 1,
|
|
1022
|
-
signature: botMetadataSignature()
|
|
1023
|
-
}
|
|
1024
|
-
]
|
|
1025
|
-
}
|
|
1071
|
+
pluginMetadata: {},
|
|
1072
|
+
...(hasVerifiableProofs(verificationMetadata) ? { verificationMetadata } : {}),
|
|
1073
|
+
// Lia@Fix --- The Bloks rendering config is required for the client to resolve
|
|
1074
|
+
// and verify rich media. Without it, rich messages attach media the client
|
|
1075
|
+
// treats as unverified: "WhatsApp can't verify the security of this media",
|
|
1076
|
+
// tapping Download crashes the app, and reel previews stop rendering.
|
|
1077
|
+
botRenderingConfigMetadata: BOT_RENDERING_CONFIG_METADATA
|
|
1026
1078
|
}
|
|
1027
1079
|
},
|
|
1028
1080
|
botForwardedMessage: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plogme",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Production-ready Baileys fork ⚉ with AI groups, Meta AI prompting, safe compositing fallbacks, rich responses, interactive messages, albums, newsletters, and communities — without antiban wrappers.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"type": "module",
|