plogme 2.0.8 → 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 +565 -18
- 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 +99 -66
- 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 +89 -9
- package/lib/Utils/validate-connection.js +4 -2
- package/lib/index.d.ts +45 -0
- package/package.json +1 -1
|
@@ -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({
|
|
@@ -1788,6 +1817,57 @@ export const attachBotVerificationProofs = (envelope, verificationMetadata) => {
|
|
|
1788
1817
|
return envelope;
|
|
1789
1818
|
};
|
|
1790
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
|
+
|
|
1791
1871
|
/**
|
|
1792
1872
|
* Wrap a rich response in the bot-forwarded envelope.
|
|
1793
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",
|