ishumdz-bail 1.0.14 → 1.0.16
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/lib/Socket/messages-send.js +11 -3
- package/lib/Utils/messages.js +47 -6
- package/package.json +1 -1
|
@@ -492,14 +492,22 @@ export const makeMessagesSocket = (config) => {
|
|
|
492
492
|
if (additionalNodes && additionalNodes.length > 0) {
|
|
493
493
|
binaryNodeContent.push(...additionalNodes)
|
|
494
494
|
}
|
|
495
|
-
|
|
496
|
-
|
|
495
|
+
// Channel updates MUST use an EMPTY plaintext attrs object and stanza
|
|
496
|
+
// type 'text' — verified against 120363427391054075@newsletter:
|
|
497
|
+
// { mediatype: 'image' } + type 'image' -> silently dropped
|
|
498
|
+
// { mediatype: 'image' } + type 'text' -> dropped
|
|
499
|
+
// {} + type 'image' -> dropped
|
|
500
|
+
// {} + type 'text' -> DELIVERED
|
|
501
|
+
// The real type lives inside the encoded newsletter protobuf
|
|
502
|
+
// (imageMessage / documentMessage / ...), so the stanza stays
|
|
503
|
+
// 'text' and no extra plaintext attrs are attached.
|
|
504
|
+
binaryNodeContent.push({ tag: 'plaintext', attrs: {}, content: bytes })
|
|
497
505
|
const stanza = {
|
|
498
506
|
tag: 'message',
|
|
499
507
|
attrs: {
|
|
500
508
|
to: jid,
|
|
501
509
|
id: msgId,
|
|
502
|
-
type:
|
|
510
|
+
type: 'text',
|
|
503
511
|
...(additionalAttributes || {})
|
|
504
512
|
},
|
|
505
513
|
content: binaryNodeContent
|
package/lib/Utils/messages.js
CHANGED
|
@@ -226,25 +226,57 @@ export const prepareWAMessageMedia = async (message, options) => {
|
|
|
226
226
|
}
|
|
227
227
|
const isNewsletter = !!options.jid && isJidNewsletter(options.jid);
|
|
228
228
|
if (isNewsletter) {
|
|
229
|
+
// Channel media follows the @zanta/baileys proven method: the file is
|
|
230
|
+
// uploaded RAW (server-opaque, no mediaKey / AES handshake) and the
|
|
231
|
+
// message carries only url, directPath, fileSha256 and fileLength.
|
|
232
|
+
//
|
|
233
|
+
// The critical detail is that `newsletter: true` is deliberately NOT
|
|
234
|
+
// passed to options.upload(). Passing it selects
|
|
235
|
+
// NEWSLETTER_MEDIA_PATH_MAP (/newsletter/newsletter-audio, plus
|
|
236
|
+
// &server_thumb_gen=1), which returns a /m1/v/t24/... directPath that the
|
|
237
|
+
// channel client cannot use for playback — the post renders but never
|
|
238
|
+
// plays, or the client falls back to the "your version of WhatsApp
|
|
239
|
+
// doesn't support this update" placeholder. Omitting the flag keeps the
|
|
240
|
+
// standard MEDIA_PATH_MAP (/mms/audio) upload, which is what the working
|
|
241
|
+
// channel-media implementation actually does.
|
|
229
242
|
logger?.info({ key: cacheableKey }, 'Preparing raw media for newsletter');
|
|
230
243
|
const { filePath, fileSha256, fileLength } = await getRawMediaUploadData(uploadData.media, options.mediaTypeOverride || mediaType, logger);
|
|
231
244
|
const fileSha256B64 = fileSha256.toString('base64');
|
|
232
|
-
const { mediaUrl, directPath
|
|
245
|
+
const { mediaUrl, directPath } = await options.upload(filePath, {
|
|
233
246
|
fileEncSha256B64: fileSha256B64,
|
|
234
247
|
mediaType: mediaType,
|
|
235
|
-
|
|
236
|
-
|
|
248
|
+
// Channel media MUST go up on the newsletter path (/newsletter/newsletter-*).
|
|
249
|
+
// On the plain /mms/* path a channel post streams for playback but a
|
|
250
|
+
// full download comes back truncated — the channel media service only
|
|
251
|
+
// resolves newsletter-path directPaths. This is also what upstream
|
|
252
|
+
// ishumdz-bail does; the flag was the one thing lost in the port.
|
|
253
|
+
newsletter: true,
|
|
254
|
+
timeoutMs: options.mediaUploadTimeoutMs
|
|
237
255
|
});
|
|
256
|
+
// Additive on top of the @zanta method: build the inline jpegThumbnail
|
|
257
|
+
// from the raw file we still have on disk. Channel clients render the
|
|
258
|
+
// bubble straight from this inline thumbnail, so skipping it makes an
|
|
259
|
+
// otherwise-valid image post look broken. Non-fatal — a failure here
|
|
260
|
+
// just means the client has to fetch the full image.
|
|
261
|
+
if ((mediaType === 'image' || mediaType === 'video') && typeof uploadData.jpegThumbnail === 'undefined') {
|
|
262
|
+
try {
|
|
263
|
+
const { thumbnail, originalImageDimensions } = await generateThumbnail(filePath, mediaType, options);
|
|
264
|
+
uploadData.jpegThumbnail = thumbnail;
|
|
265
|
+
if (!uploadData.width && originalImageDimensions) {
|
|
266
|
+
uploadData.width = originalImageDimensions.width;
|
|
267
|
+
uploadData.height = originalImageDimensions.height;
|
|
268
|
+
}
|
|
269
|
+
} catch (e) {
|
|
270
|
+
logger?.warn({ err: e?.message }, 'newsletter thumbnail generation failed');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
238
273
|
await fs.unlink(filePath);
|
|
239
274
|
const obj = WAProto.Message.fromObject({
|
|
240
|
-
// todo: add more support here
|
|
241
275
|
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
242
276
|
url: mediaUrl,
|
|
243
277
|
directPath,
|
|
244
278
|
fileSha256,
|
|
245
279
|
fileLength,
|
|
246
|
-
thumbnailDirectPath,
|
|
247
|
-
thumbnailSha256,
|
|
248
280
|
...uploadData,
|
|
249
281
|
media: undefined
|
|
250
282
|
})
|
|
@@ -262,6 +294,7 @@ export const prepareWAMessageMedia = async (message, options) => {
|
|
|
262
294
|
}
|
|
263
295
|
return obj;
|
|
264
296
|
}
|
|
297
|
+
|
|
265
298
|
const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
|
|
266
299
|
const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') && typeof uploadData['jpegThumbnail'] === 'undefined';
|
|
267
300
|
const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true && typeof uploadData.waveform === 'undefined';
|
|
@@ -555,6 +588,14 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
555
588
|
applyContextInfoAndMentions(interactiveMessage, message);
|
|
556
589
|
m = { interactiveMessage };
|
|
557
590
|
}
|
|
591
|
+
else if ('buttonsMessage' in message && !!message.buttonsMessage) {
|
|
592
|
+
// PATCH: raw buttonsMessage pass-through — classic horizontal buttons (reference: Case X Plugin case.js).
|
|
593
|
+
// Fully-formed ButtonsMessage with any header (location/image/video/
|
|
594
|
+
// document), contentText, footerText, headerType and buttons[].
|
|
595
|
+
// type:1 buttons render in one horizontal row; nativeFlowInfo
|
|
596
|
+
// single_select opens a list sheet on tap.
|
|
597
|
+
m = { buttonsMessage: proto.Message.ButtonsMessage.create(message.buttonsMessage) };
|
|
598
|
+
}
|
|
558
599
|
else if ('buttons' in message && !!message.buttons) {
|
|
559
600
|
const buttonsMessage = {
|
|
560
601
|
buttons: message.buttons.map(b => ({ ...b, type: proto.Message.ButtonsMessage.Button.Type.RESPONSE }))
|