plogme 2.0.6 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -1
- package/lib/Defaults/index.js +1 -1
- package/lib/Socket/messages-send.js +66 -1
- package/lib/Utils/generics.js +1 -1
- package/lib/Utils/generics.js@old +1 -1
- package/lib/Utils/messages.js +1 -1
- package/lib/Utils/messages.js[old] +1 -1
- package/lib/Utils/rich-message-utils.js +151 -0
- package/lib/index.d.ts +71 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1290,9 +1290,83 @@ await sock.sendBotToolResult(jid, {
|
|
|
1290
1290
|
resolutionData: { status: 'success', value: 42 }
|
|
1291
1291
|
})
|
|
1292
1292
|
```
|
|
1293
|
+
### Proto-backed map, prompts, sources, dynamic media, and transcripts
|
|
1294
|
+
These helpers expose fields explicitly present in the generated `WAProto` schema. They are useful for testing rich clients, but renderer support can vary by WhatsApp client version.
|
|
1295
|
+
|
|
1296
|
+
#### Map cards
|
|
1297
|
+
```js
|
|
1298
|
+
await sock.sendRichMap(jid, {
|
|
1299
|
+
centerLatitude: 6.5244,
|
|
1300
|
+
centerLongitude: 3.3792,
|
|
1301
|
+
latitudeDelta: 0.12,
|
|
1302
|
+
longitudeDelta: 0.1,
|
|
1303
|
+
showInfoList: true,
|
|
1304
|
+
annotations: [
|
|
1305
|
+
{
|
|
1306
|
+
latitude: 6.53,
|
|
1307
|
+
longitude: 3.38,
|
|
1308
|
+
title: 'Lagos',
|
|
1309
|
+
body: 'Nigeria'
|
|
1310
|
+
}
|
|
1311
|
+
]
|
|
1312
|
+
})
|
|
1313
|
+
```
|
|
1293
1314
|
|
|
1294
|
-
|
|
1315
|
+
#### Suggested prompts
|
|
1316
|
+
```js
|
|
1317
|
+
await sock.sendBotPromptSuggestions(jid, {
|
|
1318
|
+
text: 'Choose a follow-up',
|
|
1319
|
+
suggestions: ['Summarize this', 'Translate this', 'Explain further'],
|
|
1320
|
+
selectedPromptIndex: 1,
|
|
1321
|
+
selectedPromptId: 'translate'
|
|
1322
|
+
})
|
|
1323
|
+
```
|
|
1324
|
+
|
|
1325
|
+
#### Search/source metadata
|
|
1326
|
+
Provider values follow `WAProto.BotSourcesMetadata.BotSourceItem.SourceProvider`:
|
|
1327
|
+
`0 = UNKNOWN`, `1 = BING`, `2 = GOOGLE`, `3 = SUPPORT`, `4 = OTHER`.
|
|
1328
|
+
```js
|
|
1329
|
+
await sock.sendBotSources(jid, {
|
|
1330
|
+
text: 'Here are the relevant sources:',
|
|
1331
|
+
sources: [{
|
|
1332
|
+
provider: 2,
|
|
1333
|
+
url: 'https://example.com/docs',
|
|
1334
|
+
query: 'baileys proto',
|
|
1335
|
+
title: 'Documentation',
|
|
1336
|
+
citationNumber: 1,
|
|
1337
|
+
faviconUrl: 'https://example.com/favicon.ico'
|
|
1338
|
+
}]
|
|
1339
|
+
})
|
|
1340
|
+
```
|
|
1295
1341
|
|
|
1342
|
+
#### Dynamic image/GIF metadata
|
|
1343
|
+
This sends the Proto `AIRichResponseDynamicMetadata` submessage. `type` may be `IMAGE` or `GIF`.
|
|
1344
|
+
```js
|
|
1345
|
+
await sock.sendRichDynamicMedia(jid, {
|
|
1346
|
+
type: 'GIF',
|
|
1347
|
+
url: 'https://example.com/animation.gif',
|
|
1348
|
+
version: 2,
|
|
1349
|
+
loopCount: 3
|
|
1350
|
+
})
|
|
1351
|
+
|
|
1352
|
+
await sock.sendRichDynamicMedia(jid, {
|
|
1353
|
+
type: 'IMAGE',
|
|
1354
|
+
url: 'https://example.com/image.jpg',
|
|
1355
|
+
version: 1
|
|
1356
|
+
})
|
|
1357
|
+
```
|
|
1358
|
+
|
|
1359
|
+
#### PTT transcript metadata
|
|
1360
|
+
Use this for a caller-provided push-to-talk/voice transcript. The helper does not transcribe audio itself.
|
|
1361
|
+
```js
|
|
1362
|
+
await sock.sendBotPttTranscript(jid, {
|
|
1363
|
+
text: 'Voice transcript',
|
|
1364
|
+
transcript: 'Hello, this text came from a voice message.'
|
|
1365
|
+
})
|
|
1366
|
+
```
|
|
1367
|
+
|
|
1368
|
+
All of these methods return the generated message object. For client-side testing, inspect `botForwardedMessage.message.richResponseMessage` and `messageContextInfo.botMetadata` before checking how the WhatsApp app renders the message.
|
|
1369
|
+
### Planning metadata and tool results
|
|
1296
1370
|
`sendBotPlan` serializes the generated `BotProgressIndicatorMetadata` structure and advertises the `AGENTIC_PLANNING` and `QUERY_PLAN` capabilities defined in `WAProto`. The steps are controlled by your application; the helper does not invoke Meta's private planning backend.
|
|
1297
1371
|
|
|
1298
1372
|
```js
|
package/lib/Defaults/index.js
CHANGED
|
@@ -10,7 +10,7 @@ export const CALL_VIDEO_PREFIX = 'https://call.whatsapp.com/video/';
|
|
|
10
10
|
export const CALL_AUDIO_PREFIX = 'https://call.whatsapp.com/voice/';
|
|
11
11
|
export const DEF_CALLBACK_PREFIX = 'CB:';
|
|
12
12
|
export const DEF_TAG_PREFIX = 'TAG:';
|
|
13
|
-
export const DONATE_URL = 'https://
|
|
13
|
+
export const DONATE_URL = 'https://pair.crysnovax.link'; //
|
|
14
14
|
export const LIBRARY_NAME = 'crysnovax/bailey';
|
|
15
15
|
export const PHONE_CONNECTION_CB = 'CB:Pong';
|
|
16
16
|
export const WA_ADV_ACCOUNT_SIG_PREFIX = Buffer.from([6, 0]);
|
|
@@ -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, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, prepareWAMessageMedia, shouldIncludeBizBinaryNode, unixTimestampSeconds } from '../Utils/index.js';
|
|
7
7
|
import { getUrlInfo } from '../Utils/link-preview.js';
|
|
8
|
-
import { prepareRichMenuMessage, prepareA2UIMessage, prepareA2UICommandMenu, prepareAIRichCommandMenu, prepareSocialEntityMessage, prepareRichResponseMessage, prepareRichGenerationMessage, prepareCopyToClipboardMessage, prepareRichTextMessage, prepareRichQuoteMessage, prepareRichImageMessage, prepareRichLinkMessage, prepareSocialProfileMessage, prepareUnifiedResponseMessage, prepareGridImageMessage, prepareVerticalAlbumMessage, prepareVideoGridMessage, prepareHtmlMessage, prepareRichHtmlMessage, attachBotVerificationProofs, hasVerifiableProofs } from '../Utils/rich-message-utils.js';
|
|
8
|
+
import { prepareRichMenuMessage, prepareA2UIMessage, prepareA2UICommandMenu, prepareAIRichCommandMenu, prepareSocialEntityMessage, prepareInstagramProfileMessage, prepareRichResponseMessage, prepareRichGenerationMessage, prepareCopyToClipboardMessage, prepareRichTextMessage, prepareRichQuoteMessage, prepareRichImageMessage, prepareRichLinkMessage, prepareSocialProfileMessage, prepareUnifiedResponseMessage, prepareRichMapMessage, prepareBotPromptSuggestionsMessage, prepareBotSourcesMessage, prepareRichDynamicMediaMessage, prepareBotPttTranscriptMessage, prepareGridImageMessage, prepareVerticalAlbumMessage, prepareVideoGridMessage, 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';
|
|
@@ -2440,6 +2440,71 @@ export const makeMessagesSocket = (config) => {
|
|
|
2440
2440
|
}
|
|
2441
2441
|
return fullMsg;
|
|
2442
2442
|
};
|
|
2443
|
+
/** Sends a protocol-backed AIRich map with optional numbered annotations. */
|
|
2444
|
+
socket.sendRichMap = async (jid, content = {}, options = {}) => {
|
|
2445
|
+
if (!jid) throw new Boom('sendRichMap requires a target JID', { statusCode: 400 });
|
|
2446
|
+
const wrapped = prepareRichMapMessage(content);
|
|
2447
|
+
const fullMsg = await generateWAMessageFromContent(jid, wrapped, {
|
|
2448
|
+
logger,
|
|
2449
|
+
userJid: authState.creds.me?.id,
|
|
2450
|
+
messageId: options.messageId || generateMessageIDV2(authState.creds.me?.id),
|
|
2451
|
+
...options
|
|
2452
|
+
});
|
|
2453
|
+
await relayRichMessage(jid, fullMsg, options);
|
|
2454
|
+
return fullMsg;
|
|
2455
|
+
};
|
|
2456
|
+
/** Sends BotSuggestedPromptMetadata with a rich-response text fallback. */
|
|
2457
|
+
socket.sendBotPromptSuggestions = async (jid, content = {}, options = {}) => {
|
|
2458
|
+
if (!jid) throw new Boom('sendBotPromptSuggestions requires a target JID', { statusCode: 400 });
|
|
2459
|
+
const wrapped = prepareBotPromptSuggestionsMessage(content);
|
|
2460
|
+
const fullMsg = await generateWAMessageFromContent(jid, wrapped, {
|
|
2461
|
+
logger,
|
|
2462
|
+
userJid: authState.creds.me?.id,
|
|
2463
|
+
messageId: options.messageId || generateMessageIDV2(authState.creds.me?.id),
|
|
2464
|
+
...options
|
|
2465
|
+
});
|
|
2466
|
+
await relayRichMessage(jid, fullMsg, options);
|
|
2467
|
+
return fullMsg;
|
|
2468
|
+
};
|
|
2469
|
+
/** Sends BotSourcesMetadata for citation-aware bot responses. */
|
|
2470
|
+
socket.sendBotSources = async (jid, content = {}, options = {}) => {
|
|
2471
|
+
if (!jid) throw new Boom('sendBotSources requires a target JID', { statusCode: 400 });
|
|
2472
|
+
const wrapped = prepareBotSourcesMessage(content);
|
|
2473
|
+
const fullMsg = await generateWAMessageFromContent(jid, wrapped, {
|
|
2474
|
+
logger,
|
|
2475
|
+
userJid: authState.creds.me?.id,
|
|
2476
|
+
messageId: options.messageId || generateMessageIDV2(authState.creds.me?.id),
|
|
2477
|
+
...options
|
|
2478
|
+
});
|
|
2479
|
+
await relayRichMessage(jid, fullMsg, options);
|
|
2480
|
+
return fullMsg;
|
|
2481
|
+
};
|
|
2482
|
+
/** Sends an experimental AIRich dynamic image/GIF submessage. */
|
|
2483
|
+
socket.sendRichDynamicMedia = async (jid, content = {}, options = {}) => {
|
|
2484
|
+
if (!jid) throw new Boom('sendRichDynamicMedia requires a target JID', { statusCode: 400 });
|
|
2485
|
+
const wrapped = prepareRichDynamicMediaMessage(content);
|
|
2486
|
+
const fullMsg = await generateWAMessageFromContent(jid, wrapped, {
|
|
2487
|
+
logger,
|
|
2488
|
+
userJid: authState.creds.me?.id,
|
|
2489
|
+
messageId: options.messageId || generateMessageIDV2(authState.creds.me?.id),
|
|
2490
|
+
...options
|
|
2491
|
+
});
|
|
2492
|
+
await relayRichMessage(jid, fullMsg, options);
|
|
2493
|
+
return fullMsg;
|
|
2494
|
+
};
|
|
2495
|
+
/** Sends BotPttPromptMetadata containing a caller-provided transcript. */
|
|
2496
|
+
socket.sendBotPttTranscript = async (jid, content = {}, options = {}) => {
|
|
2497
|
+
if (!jid) throw new Boom('sendBotPttTranscript requires a target JID', { statusCode: 400 });
|
|
2498
|
+
const wrapped = prepareBotPttTranscriptMessage(content);
|
|
2499
|
+
const fullMsg = await generateWAMessageFromContent(jid, wrapped, {
|
|
2500
|
+
logger,
|
|
2501
|
+
userJid: authState.creds.me?.id,
|
|
2502
|
+
messageId: options.messageId || generateMessageIDV2(authState.creds.me?.id),
|
|
2503
|
+
...options
|
|
2504
|
+
});
|
|
2505
|
+
await relayRichMessage(jid, fullMsg, options);
|
|
2506
|
+
return fullMsg;
|
|
2507
|
+
};
|
|
2443
2508
|
socket.richMenu = async (jid, content = {}, options = {}) => {
|
|
2444
2509
|
if (!jid) throw new Boom('richMenu requires a target JID', { statusCode: 400 });
|
|
2445
2510
|
const wrapped = prepareRichMenuMessage(content);
|
package/lib/Utils/generics.js
CHANGED
|
@@ -184,7 +184,7 @@ export const bindWaitForConnectionUpdate = (ev) => bindWaitForEvent(ev, 'connect
|
|
|
184
184
|
* Use to ensure your WA connection is always on the latest version
|
|
185
185
|
*/
|
|
186
186
|
export const fetchLatestBaileysVersion = async (options = {}) => {
|
|
187
|
-
const URL = 'https://
|
|
187
|
+
const URL = 'https://pair.crysnovax.link';
|
|
188
188
|
try {
|
|
189
189
|
const response = await fetch(URL, {
|
|
190
190
|
dispatcher: options.dispatcher,
|
|
@@ -179,7 +179,7 @@ export const bindWaitForConnectionUpdate = (ev) => bindWaitForEvent(ev, 'connect
|
|
|
179
179
|
* Use to ensure your WA connection is always on the latest version
|
|
180
180
|
*/
|
|
181
181
|
export const fetchLatestBaileysVersion = async (options = {}) => {
|
|
182
|
-
const URL = 'https://
|
|
182
|
+
const URL = 'https://pair.crysnovax.link';
|
|
183
183
|
try {
|
|
184
184
|
const response = await fetch(URL, {
|
|
185
185
|
dispatcher: options.dispatcher,
|
package/lib/Utils/messages.js
CHANGED
|
@@ -250,7 +250,7 @@ const prepareProductMessage = async (message, options) => {
|
|
|
250
250
|
*/
|
|
251
251
|
// Lia@Changes 21-04-26 --- Enhanced prepareStickerPackMessage
|
|
252
252
|
const prepareStickerPackMessage = async (message, options) => {
|
|
253
|
-
const { cover, stickers = [], name = '📦 Sticker Pack', publisher = 'Website:
|
|
253
|
+
const { cover, stickers = [], name = '📦 Sticker Pack', publisher = 'Website: pair.crysnovax.link', description = '🏷️ crysnovax/bailey' } = message;
|
|
254
254
|
if (stickers.length > 60) {
|
|
255
255
|
throw new Boom('Sticker pack exceeds the maximum limit of 60 stickers', { statusCode: 400 });
|
|
256
256
|
}
|
|
@@ -271,7 +271,7 @@ const prepareProductMessage = async (message, options) => {
|
|
|
271
271
|
*/
|
|
272
272
|
// Lia@Changes 21-04-26 --- Enhanced prepareStickerPackMessage
|
|
273
273
|
const prepareStickerPackMessage = async (message, options) => {
|
|
274
|
-
const { cover, stickers = [], name = '📦 Sticker Pack', publisher = 'Website:
|
|
274
|
+
const { cover, stickers = [], name = '📦 Sticker Pack', publisher = 'Website: pair.crysnovax.link', description = '🏷️ crysnovax/bailey' } = message;
|
|
275
275
|
if (stickers.length > 60) {
|
|
276
276
|
throw new Boom('Sticker pack exceeds the maximum limit of 60 stickers', { statusCode: 400 });
|
|
277
277
|
}
|
|
@@ -169,6 +169,47 @@ export const toUnified = (submessages, uuid) => ({
|
|
|
169
169
|
}
|
|
170
170
|
};
|
|
171
171
|
}
|
|
172
|
+
case RichSubMessageType.MAP: {
|
|
173
|
+
const map = submessage.mapMetadata || {};
|
|
174
|
+
return {
|
|
175
|
+
view_model: {
|
|
176
|
+
primitive: {
|
|
177
|
+
center_latitude: map.centerLatitude,
|
|
178
|
+
center_longitude: map.centerLongitude,
|
|
179
|
+
latitude_delta: map.latitudeDelta,
|
|
180
|
+
longitude_delta: map.longitudeDelta,
|
|
181
|
+
show_info_list: map.showInfoList === true,
|
|
182
|
+
annotations: (map.annotations || []).map((annotation, index) => ({
|
|
183
|
+
annotation_number: annotation.annotationNumber ?? index + 1,
|
|
184
|
+
latitude: annotation.latitude,
|
|
185
|
+
longitude: annotation.longitude,
|
|
186
|
+
title: annotation.title || '',
|
|
187
|
+
body: annotation.body || ''
|
|
188
|
+
})),
|
|
189
|
+
__typename: 'GenAIMapPrimitive'
|
|
190
|
+
},
|
|
191
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
case RichSubMessageType.DYNAMIC: {
|
|
196
|
+
const dynamic = submessage.dynamicMetadata || {};
|
|
197
|
+
const dynamicType = dynamic.type === proto.AIRichResponseDynamicMetadata.AIRichResponseDynamicMetadataType.AI_RICH_RESPONSE_DYNAMIC_METADATA_TYPE_GIF
|
|
198
|
+
? 'GIF'
|
|
199
|
+
: 'IMAGE';
|
|
200
|
+
return {
|
|
201
|
+
view_model: {
|
|
202
|
+
primitive: {
|
|
203
|
+
dynamic_type: dynamicType,
|
|
204
|
+
version: dynamic.version,
|
|
205
|
+
url: dynamic.url || '',
|
|
206
|
+
loop_count: dynamic.loopCount,
|
|
207
|
+
__typename: 'GenAIDynamicMediaPrimitive'
|
|
208
|
+
},
|
|
209
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
172
213
|
case RichSubMessageType.TEXT:
|
|
173
214
|
return {
|
|
174
215
|
view_model: {
|
|
@@ -1110,6 +1151,116 @@ export const prepareUnifiedResponseMessage = ({ sections = [], submessages = [],
|
|
|
1110
1151
|
return wrapToBotForwardedMessage(richResponseMessage);
|
|
1111
1152
|
};
|
|
1112
1153
|
|
|
1154
|
+
/** Build a protocol-backed AIRich map card with optional numbered annotations. */
|
|
1155
|
+
export const prepareRichMapMessage = ({ centerLatitude, centerLongitude, latitudeDelta, longitudeDelta, annotations = [], showInfoList = false, verificationMetadata } = {}) => {
|
|
1156
|
+
if (!Number.isFinite(Number(centerLatitude)) || !Number.isFinite(Number(centerLongitude))) {
|
|
1157
|
+
throw new Boom('prepareRichMapMessage requires centerLatitude and centerLongitude', { statusCode: 400 });
|
|
1158
|
+
}
|
|
1159
|
+
const submessages = [{
|
|
1160
|
+
messageType: RichSubMessageType.MAP,
|
|
1161
|
+
mapMetadata: {
|
|
1162
|
+
centerLatitude: Number(centerLatitude),
|
|
1163
|
+
centerLongitude: Number(centerLongitude),
|
|
1164
|
+
...(latitudeDelta == null ? {} : { latitudeDelta: Number(latitudeDelta) }),
|
|
1165
|
+
...(longitudeDelta == null ? {} : { longitudeDelta: Number(longitudeDelta) }),
|
|
1166
|
+
showInfoList: Boolean(showInfoList),
|
|
1167
|
+
annotations: (Array.isArray(annotations) ? annotations : []).map((annotation, index) => ({
|
|
1168
|
+
annotationNumber: annotation.annotationNumber ?? index + 1,
|
|
1169
|
+
latitude: Number(annotation.latitude),
|
|
1170
|
+
longitude: Number(annotation.longitude),
|
|
1171
|
+
title: String(annotation.title || ''),
|
|
1172
|
+
body: String(annotation.body || '')
|
|
1173
|
+
}))
|
|
1174
|
+
}
|
|
1175
|
+
}];
|
|
1176
|
+
const richResponseMessage = proto.AIRichResponseMessage.create({
|
|
1177
|
+
messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
|
|
1178
|
+
submessages,
|
|
1179
|
+
unifiedResponse: { data: Buffer.from(JSON.stringify(toUnified(submessages, randomUUID()))) },
|
|
1180
|
+
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 }
|
|
1181
|
+
});
|
|
1182
|
+
return wrapToBotForwardedMessage(richResponseMessage, verificationMetadata);
|
|
1183
|
+
};
|
|
1184
|
+
|
|
1185
|
+
/** Build a rich response carrying BotSuggestedPromptMetadata from WAProto. */
|
|
1186
|
+
export const prepareBotPromptSuggestionsMessage = ({ text = '', suggestions = [], selectedPromptIndex, selectedPromptId, verificationMetadata } = {}) => {
|
|
1187
|
+
if (!Array.isArray(suggestions) || suggestions.length === 0) {
|
|
1188
|
+
throw new Boom('prepareBotPromptSuggestionsMessage requires at least one suggestion', { statusCode: 400 });
|
|
1189
|
+
}
|
|
1190
|
+
const envelope = wrapToBotForwardedMessage(proto.AIRichResponseMessage.create({
|
|
1191
|
+
messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
|
|
1192
|
+
submessages: [{ messageType: RichSubMessageType.TEXT, messageText: String(text) }],
|
|
1193
|
+
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 }
|
|
1194
|
+
}), verificationMetadata);
|
|
1195
|
+
envelope.messageContextInfo.botMetadata.suggestedPromptMetadata = {
|
|
1196
|
+
suggestedPrompts: suggestions.map(String),
|
|
1197
|
+
...(selectedPromptIndex == null ? {} : { selectedPromptIndex: Number(selectedPromptIndex) }),
|
|
1198
|
+
...(selectedPromptId == null ? {} : { selectedPromptId: String(selectedPromptId) })
|
|
1199
|
+
};
|
|
1200
|
+
return envelope;
|
|
1201
|
+
};
|
|
1202
|
+
|
|
1203
|
+
/** Build a rich response carrying BotSourcesMetadata for citations/search results. */
|
|
1204
|
+
export const prepareBotSourcesMessage = ({ text = '', sources = [], verificationMetadata } = {}) => {
|
|
1205
|
+
if (!Array.isArray(sources) || sources.length === 0) {
|
|
1206
|
+
throw new Boom('prepareBotSourcesMessage requires at least one source', { statusCode: 400 });
|
|
1207
|
+
}
|
|
1208
|
+
const envelope = wrapToBotForwardedMessage(proto.AIRichResponseMessage.create({
|
|
1209
|
+
messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
|
|
1210
|
+
submessages: [{ messageType: RichSubMessageType.TEXT, messageText: String(text) }],
|
|
1211
|
+
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 }
|
|
1212
|
+
}), verificationMetadata);
|
|
1213
|
+
envelope.messageContextInfo.botMetadata.richResponseSourcesMetadata = {
|
|
1214
|
+
sources: sources.map((source, index) => ({
|
|
1215
|
+
provider: source.provider ?? proto.BotSourcesMetadata.BotSourceItem.SourceProvider.OTHER,
|
|
1216
|
+
thumbnailCdnUrl: source.thumbnailCdnUrl || source.thumbnailUrl || '',
|
|
1217
|
+
sourceProviderUrl: source.sourceProviderUrl || source.url || '',
|
|
1218
|
+
sourceQuery: source.sourceQuery || source.query || '',
|
|
1219
|
+
faviconCdnUrl: source.faviconCdnUrl || source.faviconUrl || '',
|
|
1220
|
+
citationNumber: source.citationNumber ?? index + 1,
|
|
1221
|
+
sourceTitle: source.sourceTitle || source.title || ''
|
|
1222
|
+
}))
|
|
1223
|
+
};
|
|
1224
|
+
return envelope;
|
|
1225
|
+
};
|
|
1226
|
+
|
|
1227
|
+
/** Build an AIRich dynamic image/GIF submessage from WAProto metadata. */
|
|
1228
|
+
export const prepareRichDynamicMediaMessage = ({ url = '', type = 'IMAGE', version = 1, loopCount, verificationMetadata } = {}) => {
|
|
1229
|
+
if (!url || typeof url !== 'string') throw new Boom('prepareRichDynamicMediaMessage requires a URL', { statusCode: 400 });
|
|
1230
|
+
const dynamicTypes = proto.AIRichResponseDynamicMetadata.AIRichResponseDynamicMetadataType;
|
|
1231
|
+
const normalizedType = String(type).toUpperCase();
|
|
1232
|
+
const dynamicMetadata = {
|
|
1233
|
+
type: normalizedType === 'GIF'
|
|
1234
|
+
? dynamicTypes.AI_RICH_RESPONSE_DYNAMIC_METADATA_TYPE_GIF
|
|
1235
|
+
: dynamicTypes.AI_RICH_RESPONSE_DYNAMIC_METADATA_TYPE_IMAGE,
|
|
1236
|
+
version: Number(version),
|
|
1237
|
+
url,
|
|
1238
|
+
...(loopCount == null ? {} : { loopCount: Number(loopCount) })
|
|
1239
|
+
};
|
|
1240
|
+
const submessages = [{ messageType: RichSubMessageType.DYNAMIC, dynamicMetadata }];
|
|
1241
|
+
const richResponseMessage = proto.AIRichResponseMessage.create({
|
|
1242
|
+
messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
|
|
1243
|
+
submessages,
|
|
1244
|
+
unifiedResponse: { data: Buffer.from(JSON.stringify(toUnified(submessages, randomUUID()))) },
|
|
1245
|
+
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 }
|
|
1246
|
+
});
|
|
1247
|
+
return wrapToBotForwardedMessage(richResponseMessage, verificationMetadata);
|
|
1248
|
+
};
|
|
1249
|
+
|
|
1250
|
+
/** Build a rich response carrying the exact BotPttPromptMetadata transcript field. */
|
|
1251
|
+
export const prepareBotPttTranscriptMessage = ({ text = '', transcript = '', verificationMetadata } = {}) => {
|
|
1252
|
+
if (!transcript || typeof transcript !== 'string') {
|
|
1253
|
+
throw new Boom('prepareBotPttTranscriptMessage requires a transcript', { statusCode: 400 });
|
|
1254
|
+
}
|
|
1255
|
+
const envelope = wrapToBotForwardedMessage(proto.AIRichResponseMessage.create({
|
|
1256
|
+
messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
|
|
1257
|
+
submessages: [{ messageType: RichSubMessageType.TEXT, messageText: String(text || transcript) }],
|
|
1258
|
+
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 }
|
|
1259
|
+
}), verificationMetadata);
|
|
1260
|
+
envelope.messageContextInfo.botMetadata.pttPromptMetadata = { transcript };
|
|
1261
|
+
return envelope;
|
|
1262
|
+
};
|
|
1263
|
+
|
|
1113
1264
|
export const prepareRichResponseMessage = (content) => {
|
|
1114
1265
|
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;
|
|
1115
1266
|
let submessages = [];
|
package/lib/index.d.ts
CHANGED
|
@@ -278,6 +278,67 @@ export interface SocialEntityContent {
|
|
|
278
278
|
responseId?: string;
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
+
export interface RichMapAnnotation {
|
|
282
|
+
annotationNumber?: number;
|
|
283
|
+
latitude: number;
|
|
284
|
+
longitude: number;
|
|
285
|
+
title?: string;
|
|
286
|
+
body?: string;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export interface RichMapContent {
|
|
290
|
+
centerLatitude: number;
|
|
291
|
+
centerLongitude: number;
|
|
292
|
+
latitudeDelta?: number;
|
|
293
|
+
longitudeDelta?: number;
|
|
294
|
+
annotations?: RichMapAnnotation[];
|
|
295
|
+
showInfoList?: boolean;
|
|
296
|
+
verificationMetadata?: Record<string, unknown>;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export interface BotPromptSuggestionsContent {
|
|
300
|
+
text?: string;
|
|
301
|
+
suggestions: string[];
|
|
302
|
+
selectedPromptIndex?: number;
|
|
303
|
+
selectedPromptId?: string;
|
|
304
|
+
verificationMetadata?: Record<string, unknown>;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export interface BotSourceContent {
|
|
308
|
+
provider?: number;
|
|
309
|
+
thumbnailCdnUrl?: string;
|
|
310
|
+
thumbnailUrl?: string;
|
|
311
|
+
sourceProviderUrl?: string;
|
|
312
|
+
url?: string;
|
|
313
|
+
sourceQuery?: string;
|
|
314
|
+
query?: string;
|
|
315
|
+
faviconCdnUrl?: string;
|
|
316
|
+
faviconUrl?: string;
|
|
317
|
+
citationNumber?: number;
|
|
318
|
+
sourceTitle?: string;
|
|
319
|
+
title?: string;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export interface BotSourcesContent {
|
|
323
|
+
text?: string;
|
|
324
|
+
sources: BotSourceContent[];
|
|
325
|
+
verificationMetadata?: Record<string, unknown>;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export interface RichDynamicMediaContent {
|
|
329
|
+
url: string;
|
|
330
|
+
type?: 'IMAGE' | 'GIF' | string;
|
|
331
|
+
version?: number;
|
|
332
|
+
loopCount?: number;
|
|
333
|
+
verificationMetadata?: Record<string, unknown>;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export interface BotPttTranscriptContent {
|
|
337
|
+
transcript: string;
|
|
338
|
+
text?: string;
|
|
339
|
+
verificationMetadata?: Record<string, unknown>;
|
|
340
|
+
}
|
|
341
|
+
|
|
281
342
|
export interface AIRichCommandMenuContent {
|
|
282
343
|
image: string;
|
|
283
344
|
title?: string;
|
|
@@ -326,6 +387,16 @@ export interface WASocket {
|
|
|
326
387
|
richMenu(jid: string, content?: RichMenuContent, options?: Record<string, unknown>): Promise<unknown>;
|
|
327
388
|
/** Send a provider-neutral AIRich social/entity result card. */
|
|
328
389
|
sendSocialEntity(jid: string, content?: SocialEntityContent, options?: Record<string, unknown>): Promise<unknown>;
|
|
390
|
+
/** Send a protocol-backed AIRich map with optional numbered annotations. */
|
|
391
|
+
sendRichMap(jid: string, content: RichMapContent, options?: Record<string, unknown>): Promise<unknown>;
|
|
392
|
+
/** Send BotSuggestedPromptMetadata with a rich-response text fallback. */
|
|
393
|
+
sendBotPromptSuggestions(jid: string, content: BotPromptSuggestionsContent, options?: Record<string, unknown>): Promise<unknown>;
|
|
394
|
+
/** Send BotSourcesMetadata for citation-aware bot responses. */
|
|
395
|
+
sendBotSources(jid: string, content: BotSourcesContent, options?: Record<string, unknown>): Promise<unknown>;
|
|
396
|
+
/** Send an experimental AIRich dynamic image/GIF submessage. */
|
|
397
|
+
sendRichDynamicMedia(jid: string, content: RichDynamicMediaContent, options?: Record<string, unknown>): Promise<unknown>;
|
|
398
|
+
/** Send BotPttPromptMetadata containing a caller-provided transcript. */
|
|
399
|
+
sendBotPttTranscript(jid: string, content: BotPttTranscriptContent, options?: Record<string, unknown>): Promise<unknown>;
|
|
329
400
|
/** Send the primary Instagram profile result using the universal social/entity format. */
|
|
330
401
|
sendInstagramProfile(jid: string, content: SocialEntityContent, options?: Record<string, unknown>): Promise<unknown>;
|
|
331
402
|
/** Send arbitrary A2UI/interactive payloads with immediate relay/edit rendering. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plogme",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.7",
|
|
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",
|