@vanzxy/baileys 1.3.9 → 1.4.1
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.
|
@@ -1049,7 +1049,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
1049
1049
|
messageRetryManager.clear();
|
|
1050
1050
|
}
|
|
1051
1051
|
});
|
|
1052
|
-
|
|
1052
|
+
const messagesSocket = {
|
|
1053
1053
|
...sock,
|
|
1054
1054
|
userDevicesCache,
|
|
1055
1055
|
devicesMutex,
|
|
@@ -1368,15 +1368,16 @@ export const makeMessagesSocket = (config) => {
|
|
|
1368
1368
|
},
|
|
1369
1369
|
// Vanz@Fix: expose sendReaction as sock method (was missing entirely)
|
|
1370
1370
|
sendReaction: async (jid, reaction, key) => {
|
|
1371
|
-
return
|
|
1371
|
+
return messagesSocket.sendMessage(jid, { react: { text: reaction, key } });
|
|
1372
1372
|
},
|
|
1373
1373
|
// Vanz@Fix: expose downloadMedia as sock method so plugins don't need manual import
|
|
1374
1374
|
downloadMedia: (message, type = 'buffer', options = {}) => downloadMediaMessage(message, type, options),
|
|
1375
1375
|
// Vanz@Fix: expose copyNForward as sock method
|
|
1376
1376
|
copyNForward: async (jid, message, forceForward = false, options = {}) => {
|
|
1377
1377
|
const content = generateForwardMessageContent(message, forceForward);
|
|
1378
|
-
return
|
|
1378
|
+
return messagesSocket.sendMessage(jid, content, options);
|
|
1379
1379
|
},
|
|
1380
1380
|
};
|
|
1381
|
+
return messagesSocket;
|
|
1381
1382
|
};
|
|
1382
1383
|
//# sourceMappingURL=messages-send.js.map
|
|
@@ -738,6 +738,45 @@ class Button extends BaseBuilder {
|
|
|
738
738
|
return this;
|
|
739
739
|
}
|
|
740
740
|
|
|
741
|
+
// Vanz@Fix (bug 43) --- paramsList documented the schema for these 3 message-level native flow
|
|
742
|
+
// params (limited_time_offer / bottom_sheet / tap_target_configuration) but no helper ever wrote
|
|
743
|
+
// them into this._params — only manual setParams() could, with zero validation against the
|
|
744
|
+
// documented schema. Added dedicated setters + a lightweight type check reusing paramsList.
|
|
745
|
+
static #validateAgainstSchema(schema, data, label) {
|
|
746
|
+
for (const [key, type] of Object.entries(schema)) {
|
|
747
|
+
if (data[key] === undefined) continue;
|
|
748
|
+
const expectsArray = Array.isArray(type);
|
|
749
|
+
if (expectsArray) {
|
|
750
|
+
if (!Array.isArray(data[key]) || !data[key].every((v) => typeof v === type[0])) {
|
|
751
|
+
throw new TypeError(`${label}.${key} must be an array of ${type[0]}`);
|
|
752
|
+
}
|
|
753
|
+
} else if (typeof data[key] !== type) {
|
|
754
|
+
throw new TypeError(`${label}.${key} must be a ${type}`);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
setLimitedTimeOffer({ text = '', url = '', copy_code = '', expiration_time } = {}) {
|
|
760
|
+
const data = { text, url, copy_code, expiration_time };
|
|
761
|
+
Button.#validateAgainstSchema(Button.paramsList.limited_time_offer, data, 'limited_time_offer');
|
|
762
|
+
this._params = { ...this._params, limited_time_offer: data };
|
|
763
|
+
return this;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
setBottomSheet({ in_thread_buttons_limit, divider_indices = [], list_title = '', button_title = '' } = {}) {
|
|
767
|
+
const data = { in_thread_buttons_limit, divider_indices, list_title, button_title };
|
|
768
|
+
Button.#validateAgainstSchema(Button.paramsList.bottom_sheet, data, 'bottom_sheet');
|
|
769
|
+
this._params = { ...this._params, bottom_sheet: data };
|
|
770
|
+
return this;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
setTapTargetConfiguration({ title = '', description = '', canonical_url = '', domain = '', buttonIndex = 0 } = {}) {
|
|
774
|
+
const data = { title, description, canonical_url, domain, buttonIndex };
|
|
775
|
+
Button.#validateAgainstSchema(Button.paramsList.tap_target_configuration, data, 'tap_target_configuration');
|
|
776
|
+
this._params = { ...this._params, tap_target_configuration: data };
|
|
777
|
+
return this;
|
|
778
|
+
}
|
|
779
|
+
|
|
741
780
|
static paramsList = {
|
|
742
781
|
limited_time_offer: {
|
|
743
782
|
text: 'string',
|
|
@@ -1016,6 +1055,11 @@ class AIRich extends BaseBuilder {
|
|
|
1016
1055
|
this._submessages = [];
|
|
1017
1056
|
this._sections = [];
|
|
1018
1057
|
this._richResponseSources = [];
|
|
1058
|
+
// Vanz@Fix (bug 42 / inline image fallback): WA rejects rendering AIRichResponseInlineImageMetadata
|
|
1059
|
+
// for third-party bots regardless of URL (confirmed empirically — Meta/WA CDN url with valid
|
|
1060
|
+
// mediaKey still doesn't render, so it's a trust-chain gate, not a domain/encoding issue).
|
|
1061
|
+
// Track every addInlineImage() call here so send() can fall back to a normal imageMessage.
|
|
1062
|
+
this._inlineImages = [];
|
|
1019
1063
|
}
|
|
1020
1064
|
|
|
1021
1065
|
addSubmessage(submessage) {
|
|
@@ -1279,6 +1323,66 @@ class AIRich extends BaseBuilder {
|
|
|
1279
1323
|
return this;
|
|
1280
1324
|
}
|
|
1281
1325
|
|
|
1326
|
+
// Vanz@Fix 15-08-26 (bug 41) --- addImage() only builds GRID_IMAGE (messageType 1).
|
|
1327
|
+
// There was no helper for standalone INLINE_IMAGE (messageType 3): callers were manually
|
|
1328
|
+
// pushing addSubmessage() (correct proto shape) + addSection() (WRONG shape — reused the
|
|
1329
|
+
// GRID_IMAGE/GenAIImaginePrimitive section schema instead of GenAIInlineImageUXPrimitive),
|
|
1330
|
+
// which broke client-side unifiedResponse rendering even though the submessage itself was fine.
|
|
1331
|
+
// Mirrors RichSubMessageType.INLINE_IMAGE handling in rich-message-utils.js's toUnified().
|
|
1332
|
+
addInlineImage(imageUrl, { text = '', alignment = 'center', tapLinkUrl = '', resolveUrl = false } = {}) {
|
|
1333
|
+
if (!(typeof imageUrl === 'string' || Buffer.isBuffer(imageUrl) || (imageUrl && typeof imageUrl === 'object'))) {
|
|
1334
|
+
throw new TypeError('imageUrl must be string | buffer | { imagePreviewUrl, imageHighResUrl, sourceUrl }');
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
const ALIGNMENT_ENUM = { leading: 0, trailing: 1, center: 2 };
|
|
1338
|
+
const ALIGNMENT_NAME = ['AI_RICH_RESPONSE_IMAGE_LAYOUT_LEADING_ALIGNED', 'AI_RICH_RESPONSE_IMAGE_LAYOUT_TRAILING_ALIGNED', 'AI_RICH_RESPONSE_IMAGE_LAYOUT_CENTER_ALIGNED'];
|
|
1339
|
+
const alignmentNum = typeof alignment === 'number' ? alignment : (ALIGNMENT_ENUM[String(alignment).toLowerCase()] ?? ALIGNMENT_ENUM.center);
|
|
1340
|
+
|
|
1341
|
+
const url =
|
|
1342
|
+
imageUrl && typeof imageUrl === 'object'
|
|
1343
|
+
? {
|
|
1344
|
+
imagePreviewUrl: imageUrl.imagePreviewUrl || imageUrl.url,
|
|
1345
|
+
imageHighResUrl: imageUrl.imageHighResUrl || imageUrl.url,
|
|
1346
|
+
sourceUrl: imageUrl.sourceUrl || imageUrl.url,
|
|
1347
|
+
}
|
|
1348
|
+
: (() => {
|
|
1349
|
+
const resolved = Toolkit.resolveMedia(this.#client, imageUrl, 'image', { resolveUrl });
|
|
1350
|
+
return { imagePreviewUrl: resolved, imageHighResUrl: resolved, sourceUrl: resolved };
|
|
1351
|
+
})();
|
|
1352
|
+
|
|
1353
|
+
this._submessages.push({
|
|
1354
|
+
messageType: 3,
|
|
1355
|
+
imageMetadata: {
|
|
1356
|
+
imageUrl: url,
|
|
1357
|
+
imageText: text,
|
|
1358
|
+
alignment: alignmentNum,
|
|
1359
|
+
tapLinkUrl,
|
|
1360
|
+
},
|
|
1361
|
+
});
|
|
1362
|
+
|
|
1363
|
+
this._sections.push(
|
|
1364
|
+
AIRich.newLayout('Single', {
|
|
1365
|
+
image_url: {
|
|
1366
|
+
image_preview_url: url.imagePreviewUrl || '',
|
|
1367
|
+
image_high_res_url: url.imageHighResUrl || '',
|
|
1368
|
+
source_url: url.sourceUrl || '',
|
|
1369
|
+
},
|
|
1370
|
+
image_text: text,
|
|
1371
|
+
alignment: ALIGNMENT_NAME[alignmentNum],
|
|
1372
|
+
tap_link_url: tapLinkUrl,
|
|
1373
|
+
__typename: 'GenAIInlineImageUXPrimitive',
|
|
1374
|
+
})
|
|
1375
|
+
);
|
|
1376
|
+
|
|
1377
|
+
// Vanz@Fix (bug 42): stash for the imageMessage fallback in send()
|
|
1378
|
+
this._inlineImages.push({
|
|
1379
|
+
url: url.sourceUrl || url.imageHighResUrl || url.imagePreviewUrl,
|
|
1380
|
+
caption: text || undefined,
|
|
1381
|
+
});
|
|
1382
|
+
|
|
1383
|
+
return this;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1282
1386
|
// Vanz@Perf 15-08-26 --- autoFill defaults to false (arslan-baileys behavior): skips the
|
|
1283
1387
|
// fetch-full-video + ffmpeg-frame-extraction + duration-parse round trip per video, which
|
|
1284
1388
|
// was the main source of blurose's slower response time. Pass { autoFill: true } to opt
|
|
@@ -1564,8 +1668,30 @@ class AIRich extends BaseBuilder {
|
|
|
1564
1668
|
};
|
|
1565
1669
|
}
|
|
1566
1670
|
|
|
1567
|
-
|
|
1568
|
-
|
|
1671
|
+
// Vanz@Fix (bug 42 / inline image fallback) --- WA won't render AIRichResponseInlineImageMetadata
|
|
1672
|
+
// for bot-sent messages (confirmed: even a valid WA-CDN url with mediaKey stays blank), so any
|
|
1673
|
+
// image added via addInlineImage() is sent here as a normal imageMessage instead. Pass
|
|
1674
|
+
// { skipImageFallback: true } to opt out and send only the (image-less-looking) rich card.
|
|
1675
|
+
// Vanz@Fix (bug 42 / inline image fallback) --- WA won't render AIRichResponseInlineImageMetadata
|
|
1676
|
+
// for bot-sent messages (confirmed: even a valid WA-CDN url with mediaKey stays blank), so any
|
|
1677
|
+
// image added via addInlineImage() is sent here as a normal imageMessage instead. Pass
|
|
1678
|
+
// { skipImageFallback: true } to opt out and send only the (image-less-looking) rich card.
|
|
1679
|
+
// Vanz@Fix: don't spread relayMessage-shaped `options` into sendMessage()'s options param —
|
|
1680
|
+
// the two calls expect different option shapes, so the fallback now only forwards `quoted`
|
|
1681
|
+
// (the one option that clearly applies to both) instead of blindly spreading everything.
|
|
1682
|
+
async send(jid, { forwarded, notification, includesUnifiedResponse, includesSubmessages, skipImageFallback = false, quoted, ...options } = {}) {
|
|
1683
|
+
const msg = await this.build({ forwarded, notification, includesUnifiedResponse, includesSubmessages, quoted, ...options });
|
|
1684
|
+
|
|
1685
|
+
if (!skipImageFallback && this._inlineImages.length) {
|
|
1686
|
+
for (const { url, caption } of this._inlineImages) {
|
|
1687
|
+
try {
|
|
1688
|
+
await this.#client.sendMessage(jid, { image: { url }, caption }, quoted ? { quoted } : {});
|
|
1689
|
+
} catch (err) {
|
|
1690
|
+
// Vanz@Fix: don't let a fallback image failure block the actual rich card from sending
|
|
1691
|
+
this.#client.logger?.warn?.({ err, url }, 'inline image fallback failed, continuing with rich card');
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1569
1695
|
|
|
1570
1696
|
return await this.#client.relayMessage(jid, msg, { ...options });
|
|
1571
1697
|
}
|
package/lib/Utils/messages.js
CHANGED
|
@@ -462,7 +462,10 @@ const prepareStickerPackMessage = async (message, options) => {
|
|
|
462
462
|
const prepareNativeFlowButtons = (message) => {
|
|
463
463
|
const buttons = message.nativeFlow;
|
|
464
464
|
const isButtonsFieldArray = Array.isArray(buttons);
|
|
465
|
-
|
|
465
|
+
// Vanz@Fix (bug 7): buttons can be undefined here (e.g. cards shorthand passes `[]`
|
|
466
|
+
// for a card with no nativeFlow, so `[].nativeFlow` is undefined) — fall back to an
|
|
467
|
+
// empty button list instead of crashing on `undefined.buttons`.
|
|
468
|
+
const correctedField = isButtonsFieldArray ? buttons : (buttons?.buttons ?? []);
|
|
466
469
|
const messageParamsJson = {};
|
|
467
470
|
// Lia@Changes 31-01-26 --- Add offer and options inside interactive message
|
|
468
471
|
if (hasOptionalProperty(message, 'offerText') && !!message.offerText) {
|
|
@@ -863,10 +866,24 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
863
866
|
return message;
|
|
864
867
|
}
|
|
865
868
|
// Lia@Changes 09-04-26 --- Add support for code block and table with richResponseMessage
|
|
869
|
+
// Vanz@Fix (bug 41 / inline image standalone): gate only checked code/links/table/richResponse,
|
|
870
|
+
// so sending { inlineImage } alone (or headerText/contentText/latex/items/etc standalone) never
|
|
871
|
+
// reached prepareRichResponseMessage and silently fell through to another branch. Added every
|
|
872
|
+
// key that prepareRichResponseMessage actually destructures.
|
|
866
873
|
else if (hasNonNullishProperty(message, 'code') ||
|
|
867
874
|
hasNonNullishProperty(message, 'links') ||
|
|
868
875
|
hasNonNullishProperty(message, 'table') ||
|
|
869
|
-
hasNonNullishProperty(message, 'richResponse')
|
|
876
|
+
hasNonNullishProperty(message, 'richResponse') ||
|
|
877
|
+
hasNonNullishProperty(message, 'inlineImage') ||
|
|
878
|
+
hasNonNullishProperty(message, 'inlineVideo') ||
|
|
879
|
+
hasNonNullishProperty(message, 'headerText') ||
|
|
880
|
+
hasNonNullishProperty(message, 'contentText') ||
|
|
881
|
+
hasNonNullishProperty(message, 'footerText') ||
|
|
882
|
+
hasNonNullishProperty(message, 'latex') ||
|
|
883
|
+
hasNonNullishProperty(message, 'items') ||
|
|
884
|
+
hasNonNullishProperty(message, 'posts') ||
|
|
885
|
+
hasNonNullishProperty(message, 'products') ||
|
|
886
|
+
hasNonNullishProperty(message, 'suggested')) {
|
|
870
887
|
m = prepareRichResponseMessage(message);
|
|
871
888
|
}
|
|
872
889
|
else if (hasNonNullishProperty(message, 'text')) {
|
|
@@ -126,7 +126,12 @@ export function binaryNodeToString(node, i = 0) {
|
|
|
126
126
|
const FLOWS_MAP = {
|
|
127
127
|
// Original flow types
|
|
128
128
|
mpm: true,
|
|
129
|
-
|
|
129
|
+
// Vanz@Fix (bug 44): the "catalog" nativeFlow shortcut generates a button
|
|
130
|
+
// named 'catalog_message' (see prepareNativeFlowButtons in messages.js),
|
|
131
|
+
// never 'cta_catalog' — the old key here never matched anything, so
|
|
132
|
+
// catalog_message always fell through to the generic mixed-flow node
|
|
133
|
+
// instead of getting its dedicated native_flow node.
|
|
134
|
+
catalog_message: true,
|
|
130
135
|
send_location: true,
|
|
131
136
|
call_permission_request: true,
|
|
132
137
|
wa_payment_transaction_details: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vanzxy/baileys",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Enhanced Baileys fork by Vanzxy \u2014 based on @itsliaaa/baileys + @whiskeysockets/baileys with fixes for audio group status and clean media without newsletter button.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
package/postinstall-banner.js
CHANGED
|
@@ -13,10 +13,11 @@ const version = (() => {
|
|
|
13
13
|
|
|
14
14
|
const lines = [
|
|
15
15
|
'',
|
|
16
|
-
'\x1b[32m🍃 @vanzxy/baileys' + (version ? ` v${version}` : '') + '\x1b[0m',
|
|
16
|
+
'\x1b[1;32m🍃 @vanzxy/baileys' + (version ? ` v${version}` : '') + '\x1b[0m',
|
|
17
|
+
'\x1b[2m' + '─'.repeat(76) + '\x1b[0m',
|
|
17
18
|
'\x1b[2mNext-gen Baileys fork by Vanzxy — extended interactive messages, native flow',
|
|
18
19
|
'enhancements, status tools & QoL fixes on top of WhiskeySockets/Baileys.\x1b[0m',
|
|
19
|
-
'\x1b[
|
|
20
|
+
'\x1b[36mDocs: https://github.com/vanzxysenpai/vanzxybaileys\x1b[0m',
|
|
20
21
|
''
|
|
21
22
|
];
|
|
22
23
|
|