@crysnovax/baileys 2.6.1 → 2.6.3
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 +305 -68
- package/lib/Socket/chats.js +30 -14
- package/lib/Socket/{chats.js[past] → chats.js[old]} +16 -2
- package/lib/Socket/messages-send.js +30 -0
- package/lib/Socket/messages-send.js[old] +1367 -0
- package/lib/Utils/bot-planning-replay.js +57 -92
- package/lib/Utils/chat-utils.js +14 -0
- package/lib/Utils/chat-utils.js[old] +871 -0
- package/lib/Utils/messages-media.js +74 -0
- package/lib/Utils/meta-compositing.js +61 -77
- package/package.json +1 -1
- package/README.md[old] +0 -1612
|
@@ -220,6 +220,80 @@ export const generateProfilePicture = async (mediaUpload, dimensions) => {
|
|
|
220
220
|
img: await img
|
|
221
221
|
};
|
|
222
222
|
};
|
|
223
|
+
// crysnovax@HD-Profile --- Like generateProfilePicture but skips resize/crop.
|
|
224
|
+
// Re-encodes to JPEG so WA always gets valid image bytes.
|
|
225
|
+
// crysnovax@HD-Profile --- HD mode: preserves original aspect ratio, no crop.
|
|
226
|
+
// WhatsApp server accepts max 720px on any side. Images under 720px pass through
|
|
227
|
+
// unchanged. Larger images are scaled down proportionally to fit within 720px.
|
|
228
|
+
export const generateProfilePictureHD = async (mediaUpload) => {
|
|
229
|
+
let buffer;
|
|
230
|
+
if (Buffer.isBuffer(mediaUpload)) {
|
|
231
|
+
buffer = mediaUpload;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
const { stream } = await getStream(mediaUpload);
|
|
235
|
+
buffer = await toBuffer(stream);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const lib = await getImageProcessingLibrary();
|
|
239
|
+
let img;
|
|
240
|
+
|
|
241
|
+
if ('sharp' in lib && lib.sharp?.default) {
|
|
242
|
+
const metadata = await lib.sharp.default(buffer).metadata();
|
|
243
|
+
const origWidth = metadata.width || 720;
|
|
244
|
+
const origHeight = metadata.height || 720;
|
|
245
|
+
const maxDim = Math.max(origWidth, origHeight);
|
|
246
|
+
|
|
247
|
+
// WhatsApp server limit: 720px max dimension
|
|
248
|
+
// If already under 720, send as-is. If larger, scale down proportionally.
|
|
249
|
+
const needsResize = maxDim > 720;
|
|
250
|
+
|
|
251
|
+
let pipeline = lib.sharp.default(buffer);
|
|
252
|
+
|
|
253
|
+
if (needsResize) {
|
|
254
|
+
pipeline = pipeline.resize(720, 720, {
|
|
255
|
+
fit: 'inside',
|
|
256
|
+
withoutEnlargement: true
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
img = pipeline
|
|
261
|
+
.jpeg({ quality: 85, mozjpeg: true })
|
|
262
|
+
.toBuffer();
|
|
263
|
+
}
|
|
264
|
+
else if ('image' in lib && lib.image?.Transformer) {
|
|
265
|
+
// @napi-rs/image — cap at 720 via resize
|
|
266
|
+
img = new lib.image
|
|
267
|
+
.Transformer(buffer)
|
|
268
|
+
.resize(720, 720)
|
|
269
|
+
.jpeg(85);
|
|
270
|
+
}
|
|
271
|
+
else if ('jimp' in lib && lib.jimp?.Jimp) {
|
|
272
|
+
const jimp = await lib.jimp.Jimp.read(buffer);
|
|
273
|
+
const origWidth = jimp.width;
|
|
274
|
+
const origHeight = jimp.height;
|
|
275
|
+
const maxDim = Math.max(origWidth, origHeight);
|
|
276
|
+
|
|
277
|
+
let processed = jimp;
|
|
278
|
+
if (maxDim > 720) {
|
|
279
|
+
const scale = 720 / maxDim;
|
|
280
|
+
processed = jimp.resize({
|
|
281
|
+
w: Math.round(origWidth * scale),
|
|
282
|
+
h: Math.round(origHeight * scale),
|
|
283
|
+
mode: lib.jimp.ResizeStrategy.BILINEAR
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
img = processed.getBuffer('image/jpeg', { quality: 85 });
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
throw new Boom('No image processing library available');
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const result = await img;
|
|
294
|
+
console.log(`[HD-Profile] Output: ${result.length} bytes, dims preserved (max 720px)`);
|
|
295
|
+
return { img: result };
|
|
296
|
+
};
|
|
223
297
|
/** gets the SHA256 of the given media message */
|
|
224
298
|
export const mediaMessageSHA256B64 = (message) => {
|
|
225
299
|
const media = Object.values(message)[0];
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Lia@Changes [WIP]
|
|
3
|
-
* Meta Compositing — send rich messages
|
|
4
|
-
* Meta AI-style progress indicator that appears BEFORE the final message.
|
|
3
|
+
* Meta Compositing — send rich messages with Meta AI-style progress indicator.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* UNIVERSAL VERSION: Works on ALL WhatsApp clients.
|
|
6
|
+
* - Native Meta AI rendering for compatible clients (Beta, AI-enabled)
|
|
7
|
+
* - Plain text fallback for regular clients (no "Update WhatsApp")
|
|
9
8
|
*
|
|
10
|
-
* metaTyping() — shows the "typing..." / planning steps indicator
|
|
9
|
+
* metaTyping() — shows the "typing..." / planning steps indicator.
|
|
11
10
|
* sendMetaComposited() — full flow: typing → delete → final message.
|
|
12
11
|
*
|
|
13
12
|
* If you use or copy this code, please credit @crysnovax/bailey.
|
|
@@ -19,18 +18,23 @@ import { BOT_RENDERING_CONFIG_METADATA } from '../Defaults/index.js';
|
|
|
19
18
|
import { generateWAMessageFromContent } from './messages.js';
|
|
20
19
|
import { unixTimestampSeconds, delay } from './generics.js';
|
|
21
20
|
|
|
22
|
-
// ─── Step status enum
|
|
21
|
+
// ─── Step status enum ───
|
|
23
22
|
export const PlanningStepStatus = {
|
|
24
23
|
IN_PROGRESS: 0,
|
|
25
24
|
DONE: 1,
|
|
26
25
|
FAILED: 2
|
|
27
26
|
};
|
|
28
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Check if recipient supports native Meta AI rendering.
|
|
30
|
+
* Always false for now — WhatsApp hasn't opened this to third-party bots.
|
|
31
|
+
*/
|
|
32
|
+
export const supportsMetaRendering = (jid, config = {}) => {
|
|
33
|
+
return config.forceMetaRendering === true;
|
|
34
|
+
};
|
|
35
|
+
|
|
29
36
|
/**
|
|
30
37
|
* Build a BotProgressIndicatorMetadata object.
|
|
31
|
-
* @param {string} description - Top-level label shown while "thinking"
|
|
32
|
-
* @param {Array} steps - Array of { title, body?, status?, isReasoning? }
|
|
33
|
-
* @param {number} estimatedMs - Optional estimated completion time in ms
|
|
34
38
|
*/
|
|
35
39
|
export const buildProgressIndicator = (description, steps = [], estimatedMs) => {
|
|
36
40
|
const stepsMetadata = steps.map(step => {
|
|
@@ -51,27 +55,16 @@ export const buildProgressIndicator = (description, steps = [], estimatedMs) =>
|
|
|
51
55
|
};
|
|
52
56
|
|
|
53
57
|
/**
|
|
54
|
-
* Build the
|
|
55
|
-
* "Meta AI is thinking..." / planning steps indicator in the chat bubble.
|
|
56
|
-
*
|
|
57
|
-
* This is a botForwardedMessage with richResponseMessage = null content
|
|
58
|
-
* but with progressIndicatorMetadata on the botMetadata.
|
|
59
|
-
*
|
|
60
|
-
* @param {object} options
|
|
61
|
-
* @param {string} options.description - "Thinking…" label
|
|
62
|
-
* @param {Array} options.steps - Planning steps array
|
|
63
|
-
* @param {number} [options.estimatedMs] - Estimated completion ms
|
|
64
|
-
* @param {string} [options.placeholderText] - Text shown in the bubble body while loading
|
|
58
|
+
* Build the native Meta AI compositing placeholder (for compatible clients only).
|
|
65
59
|
*/
|
|
66
60
|
export const buildCompositingPlaceholder = ({
|
|
67
61
|
description = 'Thinking…',
|
|
68
62
|
steps = [],
|
|
69
63
|
estimatedMs,
|
|
70
64
|
placeholderText = ''
|
|
71
|
-
}) => {
|
|
65
|
+
} = {}) => {
|
|
72
66
|
const progressIndicatorMetadata = buildProgressIndicator(description, steps, estimatedMs);
|
|
73
67
|
|
|
74
|
-
// Minimal richResponseMessage so the bubble renders in Bot mode
|
|
75
68
|
const textEncoder = new TextEncoder();
|
|
76
69
|
const unifiedData = textEncoder.encode(JSON.stringify({
|
|
77
70
|
response_id: crypto.randomUUID(),
|
|
@@ -119,90 +112,81 @@ export const buildCompositingPlaceholder = ({
|
|
|
119
112
|
};
|
|
120
113
|
|
|
121
114
|
/**
|
|
122
|
-
*
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
115
|
+
* Build a plain-text placeholder that works on ALL WhatsApp clients.
|
|
116
|
+
*/
|
|
117
|
+
export const buildPlainPlaceholder = (description = 'Thinking…', steps = [], placeholderText = '') => {
|
|
118
|
+
const stepLines = steps.map(step => {
|
|
119
|
+
const icon = step.status === PlanningStepStatus.DONE ? '✓' :
|
|
120
|
+
step.status === PlanningStepStatus.FAILED ? '✗' : '○';
|
|
121
|
+
return `${icon} ${step.title}`;
|
|
122
|
+
}).join('\n');
|
|
123
|
+
|
|
124
|
+
let text = `_${description}_`;
|
|
125
|
+
if (stepLines) text += `\n\n${stepLines}`;
|
|
126
|
+
if (placeholderText) text += `\n\n${placeholderText}`;
|
|
127
|
+
|
|
128
|
+
return { text };
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* metaTyping — sends the progress/compositing indicator.
|
|
133
|
+
* UNIVERSAL: Uses plain text for regular clients, native Meta AI for compatible ones.
|
|
131
134
|
*/
|
|
132
135
|
export const metaTyping = async (sock, jid, {
|
|
133
136
|
description = 'Thinking…',
|
|
134
137
|
steps = [],
|
|
135
138
|
estimatedMs,
|
|
136
|
-
placeholderText = ''
|
|
139
|
+
placeholderText = '',
|
|
140
|
+
useNativeMeta = false
|
|
137
141
|
} = {}) => {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
// Show typing indicator
|
|
143
|
+
await sock.sendPresenceUpdate('composing', jid);
|
|
144
|
+
|
|
145
|
+
if (useNativeMeta && supportsMetaRendering(jid, sock.config)) {
|
|
146
|
+
const placeholder = buildCompositingPlaceholder({
|
|
147
|
+
description, steps, estimatedMs, placeholderText
|
|
148
|
+
});
|
|
149
|
+
return sock.sendMessage(jid, { raw: true, ...placeholder });
|
|
150
|
+
}
|
|
144
151
|
|
|
145
|
-
|
|
152
|
+
// Universal fallback: plain text placeholder
|
|
153
|
+
const plainSteps = steps.map(s => ({ ...s, status: PlanningStepStatus.IN_PROGRESS }));
|
|
154
|
+
const placeholder = buildPlainPlaceholder(description, plainSteps, placeholderText);
|
|
155
|
+
return sock.sendMessage(jid, placeholder);
|
|
146
156
|
};
|
|
147
157
|
|
|
148
158
|
/**
|
|
149
|
-
* sendMetaComposited — full Meta AI flow
|
|
150
|
-
* 1. Send progress indicator
|
|
151
|
-
* 2. Wait
|
|
152
|
-
* 3. Delete
|
|
153
|
-
* 4. Send
|
|
154
|
-
*
|
|
155
|
-
* Supports all existing richResponse content types: text, code, table,
|
|
156
|
-
* expressions (LaTeX), items (reels carousel), or the richResponse array.
|
|
157
|
-
*
|
|
158
|
-
* @param {object} sock - Baileys socket
|
|
159
|
-
* @param {string} jid - Destination JID
|
|
160
|
-
* @param {object} content - Same content object as sendMessage richResponse
|
|
161
|
-
* @param {object} [options]
|
|
162
|
-
* @param {number} [options.thinkingMs=2000] - How long placeholder shows
|
|
163
|
-
* @param {string} [options.description='Thinking…'] - Placeholder label
|
|
164
|
-
* @param {Array} [options.steps=[]] - Planning steps to show
|
|
165
|
-
* @param {string} [options.placeholderText=''] - Body text while loading
|
|
166
|
-
* @param {object} [options.sendOptions={}] - Extra options for final sendMessage
|
|
167
|
-
* @returns {Promise<object>} - The final sent WAMessage
|
|
159
|
+
* sendMetaComposited — full Meta AI flow (UNIVERSAL).
|
|
160
|
+
* 1. Send progress indicator
|
|
161
|
+
* 2. Wait thinkingMs
|
|
162
|
+
* 3. Delete placeholder
|
|
163
|
+
* 4. Send final message fresh
|
|
168
164
|
*/
|
|
169
165
|
export const sendMetaComposited = async (sock, jid, content, {
|
|
170
166
|
thinkingMs = 2000,
|
|
171
167
|
description = 'Thinking…',
|
|
172
168
|
steps = [],
|
|
173
169
|
placeholderText = '',
|
|
174
|
-
sendOptions = {}
|
|
170
|
+
sendOptions = {},
|
|
171
|
+
useNativeMeta = false
|
|
175
172
|
} = {}) => {
|
|
176
|
-
// 1. Send the compositing placeholder
|
|
177
173
|
const placeholder = await metaTyping(sock, jid, {
|
|
178
|
-
description,
|
|
179
|
-
steps,
|
|
180
|
-
placeholderText
|
|
174
|
+
description, steps, estimatedMs: thinkingMs, placeholderText, useNativeMeta
|
|
181
175
|
});
|
|
182
176
|
|
|
183
177
|
try {
|
|
184
|
-
// 2. Wait — this is the "thinking" window
|
|
185
178
|
await delay(thinkingMs);
|
|
186
|
-
|
|
187
|
-
// 3. Delete the placeholder silently
|
|
188
179
|
if (placeholder?.key) {
|
|
189
180
|
await sock.sendMessage(jid, { delete: placeholder.key });
|
|
190
181
|
}
|
|
191
|
-
} catch (_) {
|
|
192
|
-
// Non-fatal — always attempt final send
|
|
193
|
-
}
|
|
182
|
+
} catch (_) {}
|
|
194
183
|
|
|
195
|
-
|
|
184
|
+
await sock.sendPresenceUpdate('paused', jid);
|
|
196
185
|
return sock.sendMessage(jid, content, sendOptions);
|
|
197
186
|
};
|
|
198
187
|
|
|
199
188
|
/**
|
|
200
|
-
* Convenience: build a steps array from plain strings
|
|
201
|
-
* Use PlanningStepStatus.DONE to mark a step complete.
|
|
202
|
-
*
|
|
203
|
-
* @example
|
|
204
|
-
* buildSteps(['Searching…', 'Reading sources…', 'Writing response…'])
|
|
189
|
+
* Convenience: build a steps array from plain strings.
|
|
205
190
|
*/
|
|
206
191
|
export const buildSteps = (titles, status = PlanningStepStatus.IN_PROGRESS) =>
|
|
207
192
|
titles.map(title => ({ title, status }));
|
|
208
|
-
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crysnovax/baileys",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.3",
|
|
4
4
|
"description": "Premium Baileys fork ⚉ Meta compositing, bot planning replay, welcome flow, rich messages (code, table, LaTeX, reels), interactive messages, albums, and more.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"type": "module",
|