plogme 2.0.7 → 2.0.9
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 +583 -36
- package/WAProto/WAProto.proto +934 -3
- package/WAProto/index.d.ts +33887 -21445
- package/WAProto/index.js +114447 -78804
- package/lib/Defaults/index.js +1 -1
- package/lib/Socket/messages-send.js +135 -113
- package/lib/Types/Message.js +2 -1
- package/lib/Utils/bot-planning-replay.js +6 -9
- package/lib/Utils/chat-utils.js +8 -0
- package/lib/Utils/history.js +21 -1
- package/lib/Utils/messages.js +84 -11
- package/lib/Utils/meta-ai-msmsg.js +75 -2
- package/lib/Utils/meta-compositing.js +38 -9
- package/lib/Utils/rich-message-utils.js +123 -13
- package/lib/Utils/validate-connection.js +4 -2
- package/lib/index.d.ts +45 -0
- package/package.json +1 -1
|
@@ -65,10 +65,10 @@ const decodeDecryptedMsmsgMessage = (decrypted) => {
|
|
|
65
65
|
const unpadded = Buffer.from(unpadRandomMax16(buf));
|
|
66
66
|
const decoded = proto.Message.decode(unpadded);
|
|
67
67
|
const hasContent = Object.keys(decoded).some(k => k !== 'messageContextInfo' && decoded[k] != null);
|
|
68
|
-
if (hasContent) return decoded;
|
|
68
|
+
if (hasContent) return decodeUnifiedResponseInPlace(decoded);
|
|
69
69
|
}
|
|
70
70
|
catch {}
|
|
71
|
-
return proto.Message.decode(buf);
|
|
71
|
+
return decodeUnifiedResponseInPlace(proto.Message.decode(buf));
|
|
72
72
|
};
|
|
73
73
|
|
|
74
74
|
/**
|
|
@@ -127,4 +127,77 @@ export const decryptMsmsgBotMessage = async (messageSecret, messageKey, msMsg) =
|
|
|
127
127
|
throw err;
|
|
128
128
|
};
|
|
129
129
|
|
|
130
|
+
// unifiedResponse.data is base64/bytes-wrapped JSON, not encrypted. Keep the
|
|
131
|
+
// original data and expose both the decoded object and flattened text.
|
|
132
|
+
export const parseUnifiedResponseData = (data) => {
|
|
133
|
+
if (!data)
|
|
134
|
+
return null;
|
|
135
|
+
try {
|
|
136
|
+
let buf;
|
|
137
|
+
if (Buffer.isBuffer(data))
|
|
138
|
+
buf = data;
|
|
139
|
+
else if (data instanceof Uint8Array)
|
|
140
|
+
buf = Buffer.from(data);
|
|
141
|
+
else if (typeof data === 'string')
|
|
142
|
+
buf = Buffer.from(data, 'base64');
|
|
143
|
+
else if (data.type === 'Buffer' && Array.isArray(data.data))
|
|
144
|
+
buf = Buffer.from(data.data);
|
|
145
|
+
else
|
|
146
|
+
return null;
|
|
147
|
+
return JSON.parse(buf.toString('utf8'));
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
export const textFromUnifiedResponse = (data) => {
|
|
154
|
+
const json = parseUnifiedResponseData(data);
|
|
155
|
+
if (!json)
|
|
156
|
+
return null;
|
|
157
|
+
const parts = [];
|
|
158
|
+
for (const section of json.sections || []) {
|
|
159
|
+
const text = section?.view_model?.primitive?.text;
|
|
160
|
+
if (text)
|
|
161
|
+
parts.push(text);
|
|
162
|
+
}
|
|
163
|
+
return parts.length ? parts.join('\n') : null;
|
|
164
|
+
};
|
|
165
|
+
export const textFromRichResponse = (richResponse) => {
|
|
166
|
+
if (!richResponse)
|
|
167
|
+
return null;
|
|
168
|
+
if (Array.isArray(richResponse.submessages)) {
|
|
169
|
+
const parts = richResponse.submessages
|
|
170
|
+
.map(submessage => submessage?.messageText)
|
|
171
|
+
.filter(text => typeof text === 'string' && text.length);
|
|
172
|
+
if (parts.length)
|
|
173
|
+
return parts.join('\n');
|
|
174
|
+
}
|
|
175
|
+
return textFromUnifiedResponse(richResponse.unifiedResponse?.data);
|
|
176
|
+
};
|
|
177
|
+
export const extractMetaAiText = (message) => {
|
|
178
|
+
if (!message)
|
|
179
|
+
return null;
|
|
180
|
+
const body = message.protocolMessage?.editedMessage || message;
|
|
181
|
+
return body.extendedTextMessage?.text ?? body.conversation ?? textFromRichResponse(body.richResponseMessage) ?? null;
|
|
182
|
+
};
|
|
183
|
+
export const decodeUnifiedResponseInPlace = (message) => {
|
|
184
|
+
if (!message || typeof message !== 'object')
|
|
185
|
+
return message;
|
|
186
|
+
const bodies = [
|
|
187
|
+
message,
|
|
188
|
+
message.protocolMessage?.editedMessage,
|
|
189
|
+
message.editedMessage
|
|
190
|
+
].filter(Boolean);
|
|
191
|
+
for (const body of bodies) {
|
|
192
|
+
const unifiedResponse = body.richResponseMessage?.unifiedResponse;
|
|
193
|
+
if (unifiedResponse && unifiedResponse.data != null && unifiedResponse.decodedData === undefined) {
|
|
194
|
+
unifiedResponse.decodedData = parseUnifiedResponseData(unifiedResponse.data);
|
|
195
|
+
const text = textFromUnifiedResponse(unifiedResponse.data);
|
|
196
|
+
if (text != null)
|
|
197
|
+
unifiedResponse.text = text;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return message;
|
|
201
|
+
};
|
|
202
|
+
|
|
130
203
|
export { decodeDecryptedMsmsgMessage };
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - Plain text fallback is used unless the native payload can be authenticated
|
|
8
8
|
*
|
|
9
9
|
* metaTyping() — shows the "typing..." / planning steps indicator.
|
|
10
|
-
* sendMetaComposited() — full flow:
|
|
10
|
+
* sendMetaComposited() — full flow: initial message → streaming MESSAGE_EDIT frames → final edit.
|
|
11
11
|
*
|
|
12
12
|
* If you use or copy this code, please credit @crysnovax/bailey.
|
|
13
13
|
*/
|
|
@@ -161,12 +161,21 @@ export const metaTyping = async (sock, jid, {
|
|
|
161
161
|
return sock.sendMessage(jid, placeholder);
|
|
162
162
|
};
|
|
163
163
|
|
|
164
|
+
/** Send a streaming MESSAGE_EDIT frame without changing the original key. */
|
|
165
|
+
export const editMetaMessage = async (sock, jid, key, content, sendOptions = {}, streamContext) => {
|
|
166
|
+
if (!key)
|
|
167
|
+
return undefined;
|
|
168
|
+
const frame = streamContext
|
|
169
|
+
? { ...content, messageContextInfo: { ...streamContext, ...content.messageContextInfo } }
|
|
170
|
+
: content;
|
|
171
|
+
return sock.sendMessage(jid, { ...frame, edit: key }, sendOptions);
|
|
172
|
+
};
|
|
173
|
+
|
|
164
174
|
/**
|
|
165
|
-
* sendMetaComposited — full Meta AI flow (UNIVERSAL).
|
|
166
|
-
* 1. Send progress indicator
|
|
167
|
-
* 2.
|
|
168
|
-
* 3.
|
|
169
|
-
* 4. Send final message fresh
|
|
175
|
+
* sendMetaComposited — full Meta AI-style flow (UNIVERSAL).
|
|
176
|
+
* 1. Send initial progress indicator
|
|
177
|
+
* 2. Optionally emit streamUpdates as MESSAGE_EDIT frames
|
|
178
|
+
* 3. Edit the same message into the final response
|
|
170
179
|
*/
|
|
171
180
|
export const sendMetaComposited = async (sock, jid, content, {
|
|
172
181
|
thinkingMs = 2000,
|
|
@@ -174,7 +183,10 @@ export const sendMetaComposited = async (sock, jid, content, {
|
|
|
174
183
|
steps = [],
|
|
175
184
|
placeholderText = '',
|
|
176
185
|
sendOptions = {},
|
|
177
|
-
useNativeMeta = false
|
|
186
|
+
useNativeMeta = false,
|
|
187
|
+
streamUpdates = [],
|
|
188
|
+
streamUpdateDelayMs = 0,
|
|
189
|
+
streamContext
|
|
178
190
|
} = {}) => {
|
|
179
191
|
const placeholder = await metaTyping(sock, jid, {
|
|
180
192
|
description, steps, estimatedMs: thinkingMs, placeholderText, useNativeMeta
|
|
@@ -183,12 +195,29 @@ export const sendMetaComposited = async (sock, jid, content, {
|
|
|
183
195
|
try {
|
|
184
196
|
await delay(thinkingMs);
|
|
185
197
|
if (placeholder?.key) {
|
|
186
|
-
|
|
198
|
+
for (const update of streamUpdates) {
|
|
199
|
+
const frame = typeof update === 'string' ? { text: update } : update;
|
|
200
|
+
try {
|
|
201
|
+
await editMetaMessage(sock, jid, placeholder.key, frame, sendOptions, streamContext);
|
|
202
|
+
}
|
|
203
|
+
catch (_) {}
|
|
204
|
+
if (streamUpdateDelayMs > 0)
|
|
205
|
+
await delay(streamUpdateDelayMs);
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
await editMetaMessage(sock, jid, placeholder.key, content, sendOptions, streamContext);
|
|
209
|
+
}
|
|
210
|
+
catch (_) {
|
|
211
|
+
await sock.sendMessage(jid, content, sendOptions);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
await sock.sendMessage(jid, content, sendOptions);
|
|
187
216
|
}
|
|
188
217
|
} catch (_) {}
|
|
189
218
|
|
|
190
219
|
await sock.sendPresenceUpdate('paused', jid);
|
|
191
|
-
return
|
|
220
|
+
return placeholder;
|
|
192
221
|
};
|
|
193
222
|
|
|
194
223
|
/**
|
|
@@ -48,7 +48,7 @@ export const tokenizeCode = (code, language = 'javascript') => {
|
|
|
48
48
|
const firstImageValue = (...values) => values.find(value => value !== undefined && value !== null && String(value).length > 0);
|
|
49
49
|
|
|
50
50
|
/** Normalize album image variants without downgrading full-size URLs to previews. */
|
|
51
|
-
const buildRichImagePrimitive = (image = {}, expiration = String(Date.now() + 30 * 24 * 60 * 60 * 1000)) => {
|
|
51
|
+
const buildRichImagePrimitive = (image = {}, expiration = String(Date.now() + 30 * 24 * 60 * 60 * 1000), { fullOnly = false } = {}) => {
|
|
52
52
|
const previewUrl = firstImageValue(image.imagePreviewUrl, image.previewUrl, image.preview_url, image.sourceUrl, image.source_url, image.url) || '';
|
|
53
53
|
const fullUrl = firstImageValue(image.imageHighResUrl, image.highResUrl, image.high_res_url, image.fullUrl, image.full_url, image.sourceUrl, image.source_url, image.url, previewUrl);
|
|
54
54
|
const darkPreviewUrl = firstImageValue(image.darkModePreviewUrl, image.dark_mode_preview_url, previewUrl);
|
|
@@ -59,7 +59,13 @@ const buildRichImagePrimitive = (image = {}, expiration = String(Date.now() + 30
|
|
|
59
59
|
const fullHeight = Number(image.fullHeight || image.full_height || image.highResHeight || image.high_res_height || image.height || height);
|
|
60
60
|
const darkWidth = Number(image.darkWidth || image.dark_width || fullWidth);
|
|
61
61
|
const darkHeight = Number(image.darkHeight || image.dark_height || fullHeight);
|
|
62
|
-
const mimeType = image.mimeType || image.mime_type ||
|
|
62
|
+
const mimeType = image.mimeType || image.mime_type || (() => {
|
|
63
|
+
const value = String(fullUrl || previewUrl).split('?')[0].toLowerCase();
|
|
64
|
+
if (value.endsWith('.jpg') || value.endsWith('.jpeg')) return 'image/jpeg';
|
|
65
|
+
if (value.endsWith('.webp')) return 'image/webp';
|
|
66
|
+
if (value.endsWith('.gif')) return 'image/gif';
|
|
67
|
+
return 'image/png';
|
|
68
|
+
})();
|
|
63
69
|
const media = (url, mediaWidth, mediaHeight) => ({
|
|
64
70
|
url,
|
|
65
71
|
url_fallback: url,
|
|
@@ -68,14 +74,17 @@ const buildRichImagePrimitive = (image = {}, expiration = String(Date.now() + 30
|
|
|
68
74
|
width: mediaWidth,
|
|
69
75
|
height: mediaHeight
|
|
70
76
|
});
|
|
71
|
-
|
|
72
|
-
preview_image: media(previewUrl, width, height),
|
|
77
|
+
const primitive = {
|
|
73
78
|
full_image: media(fullUrl, fullWidth, fullHeight),
|
|
74
|
-
dark_mode_preview_image: media(darkPreviewUrl, darkWidth, darkHeight),
|
|
75
|
-
dark_mode_full_image: media(darkFullUrl, darkWidth, darkHeight),
|
|
76
79
|
asset_query_status: 'FETCHED',
|
|
77
80
|
__typename: 'GenAIImagePrimitive'
|
|
78
81
|
};
|
|
82
|
+
if (!fullOnly) {
|
|
83
|
+
primitive.preview_image = media(previewUrl, width, height);
|
|
84
|
+
primitive.dark_mode_preview_image = media(darkPreviewUrl, darkWidth, darkHeight);
|
|
85
|
+
primitive.dark_mode_full_image = media(darkFullUrl, darkWidth, darkHeight);
|
|
86
|
+
}
|
|
87
|
+
return primitive;
|
|
79
88
|
};
|
|
80
89
|
// Lia@Changes 09-04-26 --- Inject buffer into unifiedResponse.data to support proper rendering of rich messages (ex: tables and code blocks)
|
|
81
90
|
export const toUnified = (submessages, uuid) => ({
|
|
@@ -974,13 +983,33 @@ export const prepareVerticalAlbumMessage = ({ items = [], verificationMetadata }
|
|
|
974
983
|
if (!url) throw new Error('Each video album item requires a video URL');
|
|
975
984
|
return buildImaginePrimitive({ mediaType: 'video', url, thumbnail: video?.thumbnail || video?.thumbnailUrl, mimeType: video?.mimeType || video?.mime_type || 'video/mp4', fileLength: video?.fileLength || video?.file_length || 0, duration: video?.duration || 0, status: 'READY' });
|
|
976
985
|
}
|
|
977
|
-
const
|
|
978
|
-
const
|
|
986
|
+
const rawImage = item?.image || item?.data || item;
|
|
987
|
+
const image = typeof rawImage === 'string' ? { url: rawImage } : (rawImage || {});
|
|
988
|
+
const sourceUrl = firstImageValue(
|
|
979
989
|
image?.imageHighResUrl, image?.highResUrl, image?.fullUrl,
|
|
980
990
|
image?.imagePreviewUrl, image?.previewUrl, image?.sourceUrl, image?.url
|
|
981
991
|
) || '';
|
|
982
992
|
if (!sourceUrl) throw new Error('Each image album item requires an image URL');
|
|
983
|
-
|
|
993
|
+
// Unlike a compact image grid, vertical albums are intended to render
|
|
994
|
+
// the actual media at full size. Some clients choose preview_image and
|
|
995
|
+
// never follow full_image, so expose the selected full URL/dimensions
|
|
996
|
+
// in both slots instead of allowing a thumbnail URL to win.
|
|
997
|
+
const fullUrl = firstImageValue(
|
|
998
|
+
image?.imageHighResUrl, image?.highResUrl, image?.high_res_url,
|
|
999
|
+
image?.fullUrl, image?.full_url, image?.sourceUrl, image?.source_url, image?.url
|
|
1000
|
+
) || sourceUrl;
|
|
1001
|
+
const fullWidth = Number(image?.fullWidth || image?.full_width || image?.highResWidth || image?.high_res_width || image?.width || item?.width || 0);
|
|
1002
|
+
const fullHeight = Number(image?.fullHeight || image?.full_height || image?.highResHeight || image?.high_res_height || image?.height || item?.height || 0);
|
|
1003
|
+
const primitive = buildRichImagePrimitive({
|
|
1004
|
+
...image,
|
|
1005
|
+
imagePreviewUrl: fullUrl,
|
|
1006
|
+
previewUrl: fullUrl,
|
|
1007
|
+
sourceUrl: fullUrl,
|
|
1008
|
+
imageHighResUrl: fullUrl,
|
|
1009
|
+
fullUrl,
|
|
1010
|
+
...(fullWidth > 0 ? { width: fullWidth, fullWidth } : {}),
|
|
1011
|
+
...(fullHeight > 0 ? { height: fullHeight, fullHeight } : {})
|
|
1012
|
+
}, expiration, { fullOnly: true });
|
|
984
1013
|
return { ...primitive, display_mode: 'FULL_WIDTH', full_width: true };
|
|
985
1014
|
});
|
|
986
1015
|
const richResponseMessage = proto.AIRichResponseMessage.create({
|
|
@@ -1152,11 +1181,13 @@ export const prepareUnifiedResponseMessage = ({ sections = [], submessages = [],
|
|
|
1152
1181
|
};
|
|
1153
1182
|
|
|
1154
1183
|
/** Build a protocol-backed AIRich map card with optional numbered annotations. */
|
|
1155
|
-
export const prepareRichMapMessage = ({ centerLatitude, centerLongitude, latitudeDelta, longitudeDelta, annotations = [], showInfoList = false, verificationMetadata } = {}) => {
|
|
1184
|
+
export const prepareRichMapMessage = ({ text = 'Map location', centerLatitude, centerLongitude, latitudeDelta, longitudeDelta, annotations = [], showInfoList = false, verificationMetadata } = {}) => {
|
|
1156
1185
|
if (!Number.isFinite(Number(centerLatitude)) || !Number.isFinite(Number(centerLongitude))) {
|
|
1157
1186
|
throw new Boom('prepareRichMapMessage requires centerLatitude and centerLongitude', { statusCode: 400 });
|
|
1158
1187
|
}
|
|
1159
|
-
const submessages = [
|
|
1188
|
+
const submessages = [
|
|
1189
|
+
...(text ? [{ messageType: RichSubMessageType.TEXT, messageText: String(text) }] : []),
|
|
1190
|
+
{
|
|
1160
1191
|
messageType: RichSubMessageType.MAP,
|
|
1161
1192
|
mapMetadata: {
|
|
1162
1193
|
centerLatitude: Number(centerLatitude),
|
|
@@ -1172,7 +1203,8 @@ export const prepareRichMapMessage = ({ centerLatitude, centerLongitude, latitud
|
|
|
1172
1203
|
body: String(annotation.body || '')
|
|
1173
1204
|
}))
|
|
1174
1205
|
}
|
|
1175
|
-
|
|
1206
|
+
}
|
|
1207
|
+
];
|
|
1176
1208
|
const richResponseMessage = proto.AIRichResponseMessage.create({
|
|
1177
1209
|
messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
|
|
1178
1210
|
submessages,
|
|
@@ -1205,9 +1237,36 @@ export const prepareBotSourcesMessage = ({ text = '', sources = [], verification
|
|
|
1205
1237
|
if (!Array.isArray(sources) || sources.length === 0) {
|
|
1206
1238
|
throw new Boom('prepareBotSourcesMessage requires at least one source', { statusCode: 400 });
|
|
1207
1239
|
}
|
|
1240
|
+
const submessages = [{
|
|
1241
|
+
messageType: RichSubMessageType.TEXT,
|
|
1242
|
+
messageText: String(text || 'Sources')
|
|
1243
|
+
}];
|
|
1244
|
+
const sourceCards = sources.map((source, index) => ({
|
|
1245
|
+
source_type: 'THIRD_PARTY',
|
|
1246
|
+
source_display_name: source.sourceTitle || source.title || '',
|
|
1247
|
+
source_subtitle: source.sourceQuery || source.query || 'Source',
|
|
1248
|
+
source_url: source.sourceProviderUrl || source.url || '',
|
|
1249
|
+
favicon: {
|
|
1250
|
+
url: source.faviconCdnUrl || source.faviconUrl || source.thumbnailCdnUrl || source.thumbnailUrl || '',
|
|
1251
|
+
mime_type: 'image/jpeg',
|
|
1252
|
+
width: 16,
|
|
1253
|
+
height: 16
|
|
1254
|
+
},
|
|
1255
|
+
citation_number: source.citationNumber ?? index + 1
|
|
1256
|
+
})).filter((source) => source.source_url || source.source_display_name);
|
|
1257
|
+
const sections = toUnified(submessages, randomUUID()).sections;
|
|
1258
|
+
if (sourceCards.length) {
|
|
1259
|
+
sections.push({
|
|
1260
|
+
view_model: {
|
|
1261
|
+
primitive: { sources: sourceCards, __typename: 'GenAISearchResultPrimitive' },
|
|
1262
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
1263
|
+
}
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1208
1266
|
const envelope = wrapToBotForwardedMessage(proto.AIRichResponseMessage.create({
|
|
1209
1267
|
messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
|
|
1210
|
-
submessages
|
|
1268
|
+
submessages,
|
|
1269
|
+
unifiedResponse: { data: Buffer.from(JSON.stringify({ response_id: randomUUID(), sections })) },
|
|
1211
1270
|
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 }
|
|
1212
1271
|
}), verificationMetadata);
|
|
1213
1272
|
envelope.messageContextInfo.botMetadata.richResponseSourcesMetadata = {
|
|
@@ -1758,6 +1817,57 @@ export const attachBotVerificationProofs = (envelope, verificationMetadata) => {
|
|
|
1758
1817
|
return envelope;
|
|
1759
1818
|
};
|
|
1760
1819
|
|
|
1820
|
+
/**
|
|
1821
|
+
* Build a forwarded AIRich label message.
|
|
1822
|
+
*
|
|
1823
|
+
* This is the small single-label surface used by WhatsApp clients for a
|
|
1824
|
+
* colored forwarded bubble. The unified response is intentionally serialized
|
|
1825
|
+
* as base64 text because that is the wire shape accepted by the raw
|
|
1826
|
+
* `relayMessage` API.
|
|
1827
|
+
*/
|
|
1828
|
+
export const buildRichLabelMessage = ({
|
|
1829
|
+
text = '',
|
|
1830
|
+
variant = 'POSITIVE',
|
|
1831
|
+
backgroundColor = '#FF0000FF',
|
|
1832
|
+
textColor = '#000000FF',
|
|
1833
|
+
responseId = randomUUID(),
|
|
1834
|
+
} = {}) => {
|
|
1835
|
+
const unified = {
|
|
1836
|
+
__typename: 'GenAIUnifiedResponse',
|
|
1837
|
+
response_id: responseId,
|
|
1838
|
+
sections: [{
|
|
1839
|
+
__typename: 'GenAIUnifiedResponseSection',
|
|
1840
|
+
view_model: {
|
|
1841
|
+
__typename: 'GenAISingleLayoutViewModel',
|
|
1842
|
+
primitive: {
|
|
1843
|
+
__typename: 'GenAILabelPrimitive',
|
|
1844
|
+
text: String(text),
|
|
1845
|
+
variant,
|
|
1846
|
+
background_color_override: backgroundColor,
|
|
1847
|
+
text_color_override: textColor,
|
|
1848
|
+
},
|
|
1849
|
+
},
|
|
1850
|
+
}],
|
|
1851
|
+
};
|
|
1852
|
+
|
|
1853
|
+
return {
|
|
1854
|
+
botForwardedMessage: {
|
|
1855
|
+
message: {
|
|
1856
|
+
richResponseMessage: {
|
|
1857
|
+
messageType: 1,
|
|
1858
|
+
unifiedResponse: {
|
|
1859
|
+
data: Buffer.from(JSON.stringify(unified)).toString('base64'),
|
|
1860
|
+
},
|
|
1861
|
+
contextInfo: {
|
|
1862
|
+
isForwarded: true,
|
|
1863
|
+
forwardOrigin: 4,
|
|
1864
|
+
},
|
|
1865
|
+
},
|
|
1866
|
+
},
|
|
1867
|
+
},
|
|
1868
|
+
};
|
|
1869
|
+
};
|
|
1870
|
+
|
|
1761
1871
|
/**
|
|
1762
1872
|
* Wrap a rich response in the bot-forwarded envelope.
|
|
1763
1873
|
*
|
|
@@ -96,7 +96,9 @@ export const generateRegistrationNode = ({ registrationId, signedPreKey, signedI
|
|
|
96
96
|
supportMessageAssociation: true,
|
|
97
97
|
supportGroupHistory: false,
|
|
98
98
|
onDemandReady: undefined,
|
|
99
|
-
supportGuestChat: undefined
|
|
99
|
+
supportGuestChat: undefined,
|
|
100
|
+
supportOmittedConversationIndex: true,
|
|
101
|
+
supportUniversalReachChat: true
|
|
100
102
|
},
|
|
101
103
|
version: {
|
|
102
104
|
primary: 10,
|
|
@@ -203,4 +205,4 @@ export const encodeSignedDeviceIdentity = (account, includeSignatureKey) => {
|
|
|
203
205
|
account.accountSignatureKey = null;
|
|
204
206
|
}
|
|
205
207
|
return proto.ADVSignedDeviceIdentity.encode(account).finish();
|
|
206
|
-
};
|
|
208
|
+
};
|
package/lib/index.d.ts
CHANGED
|
@@ -132,6 +132,25 @@ export interface AIPromptOptions {
|
|
|
132
132
|
/** Extra options forwarded to `sendMessage` (quoted, linkPreview, ...). */
|
|
133
133
|
[key: string]: unknown;
|
|
134
134
|
}
|
|
135
|
+
/** Options for the verified Meta AI (Hatch) send path. */
|
|
136
|
+
export interface MetaAISendOptions {
|
|
137
|
+
/** Destination JID; defaults to `867051314767696@bot` for a direct prompt. */
|
|
138
|
+
jid?: string;
|
|
139
|
+
invokerJid?: string;
|
|
140
|
+
sessionId?: string;
|
|
141
|
+
messageSecret?: Buffer;
|
|
142
|
+
capabilities?: number[];
|
|
143
|
+
/** F-BID used when invoking Meta AI in a group. */
|
|
144
|
+
botFbid?: string;
|
|
145
|
+
/** Add a visible Meta AI mention to a group prompt. */
|
|
146
|
+
mention?: boolean;
|
|
147
|
+
personaType?: string;
|
|
148
|
+
agentEngagementType?: string;
|
|
149
|
+
modeSelected?: string;
|
|
150
|
+
conversationContext?: Uint8Array | Buffer;
|
|
151
|
+
quoted?: unknown;
|
|
152
|
+
links?: unknown;
|
|
153
|
+
}
|
|
135
154
|
|
|
136
155
|
export interface RichMenuButton {
|
|
137
156
|
id?: string;
|
|
@@ -351,6 +370,26 @@ export interface AIRichCommandMenuContent {
|
|
|
351
370
|
footer?: string;
|
|
352
371
|
}
|
|
353
372
|
|
|
373
|
+
export declare function parseUnifiedResponseData(data: unknown): Record<string, unknown> | null;
|
|
374
|
+
export declare function textFromUnifiedResponse(data: unknown): string | null;
|
|
375
|
+
export declare function textFromRichResponse(message: unknown): string | null;
|
|
376
|
+
export declare function extractMetaAiText(message: unknown): string | null;
|
|
377
|
+
export declare function decodeUnifiedResponseInPlace<T extends Record<string, unknown>>(message: T): T;
|
|
378
|
+
export interface MetaCompositedOptions {
|
|
379
|
+
thinkingMs?: number;
|
|
380
|
+
description?: string;
|
|
381
|
+
steps?: Array<Record<string, unknown>>;
|
|
382
|
+
estimatedMs?: number;
|
|
383
|
+
placeholderText?: string;
|
|
384
|
+
sendOptions?: Record<string, unknown>;
|
|
385
|
+
useNativeMeta?: boolean;
|
|
386
|
+
streamUpdates?: Array<string | Record<string, unknown>>;
|
|
387
|
+
streamUpdateDelayMs?: number;
|
|
388
|
+
streamContext?: Record<string, unknown>;
|
|
389
|
+
}
|
|
390
|
+
export declare function editMetaMessage(sock: WASocket, jid: string, key: WAMessageKey, content: Record<string, unknown>, sendOptions?: Record<string, unknown>, streamContext?: Record<string, unknown>): Promise<unknown>;
|
|
391
|
+
export declare function sendMetaComposited(sock: WASocket, jid: string, content: Record<string, unknown>, options?: MetaCompositedOptions): Promise<unknown>;
|
|
392
|
+
|
|
354
393
|
export interface WASocket {
|
|
355
394
|
sendMessage(jid: string | string[], content: StatusContent | GroupStatusContent | Record<string, unknown>, options?: Partial<StatusOptions> & Record<string, unknown>): Promise<unknown>;
|
|
356
395
|
/** Send at least two image/video URL items as a full-width AIRich vertical album. */
|
|
@@ -427,6 +466,12 @@ export interface WASocket {
|
|
|
427
466
|
sendBotToolResult(jid: string, content?: { text?: string; toolCallId?: string; resolutionData?: unknown; resolutionDataSerialized?: string; botJid?: string }, options?: Record<string, unknown>): Promise<unknown>;
|
|
428
467
|
/** Send one tolerant AIRich response containing every supported section supplied in content. */
|
|
429
468
|
sendPlogmeMessage(jid: string, content?: Record<string, unknown>, quoted?: unknown, options?: Record<string, unknown>): Promise<unknown>;
|
|
469
|
+
/** Send a compact forwarded AIRich label bubble with optional colors and variant. */
|
|
470
|
+
sendRichLabelMessage(jid: string, content?: { text?: string; variant?: string; backgroundColor?: string; textColor?: string; responseId?: string }, options?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
471
|
+
/** Send a prompt through the verified Meta AI/Hatch route and return its message ID. */
|
|
472
|
+
sendMetaAI(text: string, options?: MetaAISendOptions): Promise<string>;
|
|
473
|
+
/** Backward-compatible destination-first signature. */
|
|
474
|
+
sendMetaAI(jid: string, text: string, options?: Omit<MetaAISendOptions, 'jid'>): Promise<string>;
|
|
430
475
|
/** Resolve a WhatsApp Channel invite code or invite URL to channel metadata. */
|
|
431
476
|
newsletterGetInviteInfo(inviteCodeOrUrl: string): Promise<Record<string, unknown> | null>;
|
|
432
477
|
/** React to a Channel post; pass an empty string, null, or undefined to remove the reaction. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plogme",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.9",
|
|
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",
|