@pontalabs/baileys 1.2.4 → 1.2.5
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 +468 -696
- package/lib/Socket/messages-send.js +129 -41
- package/lib/Utils/rich-message-utils.js +31 -1
- package/package.json +1 -1
|
@@ -14,7 +14,7 @@ import { USyncQuery, USyncUser } from '../WAUSync/index.js';
|
|
|
14
14
|
import { makeNewsletterSocket } from './newsletter.js';
|
|
15
15
|
import kikyy from './dugong.js';
|
|
16
16
|
import { generateTableContent, generateTableContentV2, generateListContent, generateCodeBlockContent, generateCodeBlockContentV2, generateLinkContent, generateLinkContentV2, generateRichMessageContent, generateUnifiedResponseContent, captureUnifiedResponse, generateLatexContent, generateLatexImageContent, generateLatexInlineImageContent } from '../Utils/rich-message-utils.js';
|
|
17
|
-
import { Button, ButtonV2, Carousel } from '../Utils/mbuilder.js';
|
|
17
|
+
import { AIRich, Button, ButtonV2, Carousel } from '../Utils/mbuilder.js';
|
|
18
18
|
export const makeMessagesSocket = (config) => {
|
|
19
19
|
const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: httpRequestOptions, patchMessageBeforeSending, cachedGroupMetadata, enableRecentMessageCache, maxMsgRetryCount } = config;
|
|
20
20
|
const sock = makeNewsletterSocket(config);
|
|
@@ -1134,67 +1134,155 @@ export const makeMessagesSocket = (config) => {
|
|
|
1134
1134
|
const userJid = authState.creds.me.id;
|
|
1135
1135
|
|
|
1136
1136
|
// `items` may contain Rich AI build descriptors as well as the
|
|
1137
|
-
// interactive builders exported by mbuilder.js.
|
|
1138
|
-
//
|
|
1139
|
-
//
|
|
1140
|
-
// are not valid Rich AI primitives.
|
|
1137
|
+
// interactive builders exported by mbuilder.js. When buildDelay is
|
|
1138
|
+
// enabled, keep ONE WhatsApp message id and progressively edit that
|
|
1139
|
+
// message instead of sending a new bubble for every item.
|
|
1141
1140
|
if (content && !Array.isArray(jid) && Array.isArray(content.items) && content.items.length > 0) {
|
|
1142
1141
|
const items = content.items;
|
|
1143
1142
|
const buildDelay = Number(options.buildDelay ?? content.buildDelay ?? 0);
|
|
1144
1143
|
const hasDelay = Number.isFinite(buildDelay) && buildDelay > 0;
|
|
1145
1144
|
const isInteractiveBuilder = (item) => item instanceof Button || item instanceof ButtonV2 || item instanceof Carousel;
|
|
1145
|
+
const isAIRichBuilder = (item) => item instanceof AIRich;
|
|
1146
1146
|
const hasInteractiveBuilder = items.some(isInteractiveBuilder);
|
|
1147
1147
|
|
|
1148
1148
|
if (hasDelay || hasInteractiveBuilder) {
|
|
1149
1149
|
const sendOptions = { ...options };
|
|
1150
1150
|
delete sendOptions.buildDelay;
|
|
1151
1151
|
delete sendOptions.additionalNodes;
|
|
1152
|
-
const results = [];
|
|
1153
1152
|
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
],
|
|
1153
|
+
// One target id for the entire progressive sequence. If the
|
|
1154
|
+
// caller supplied messageId, it is used; otherwise the first
|
|
1155
|
+
// generated message id becomes the target for all edits.
|
|
1156
|
+
let targetMessageId = options.messageId;
|
|
1157
|
+
let lastMessage;
|
|
1158
|
+
|
|
1159
|
+
const buildItemMessage = async (item) => {
|
|
1160
|
+
if (isInteractiveBuilder(item)) {
|
|
1161
|
+
item.setClient({ waUploadToServer });
|
|
1162
|
+
return await item.build(jid, { ...sendOptions, messageId: targetMessageId });
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
if (isAIRichBuilder(item)) {
|
|
1166
|
+
return await item.build(jid, { ...sendOptions, messageId: targetMessageId });
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
// Send Rich AI descriptors through the normal Rich AI
|
|
1170
|
+
// generator, but force the same message id.
|
|
1171
|
+
return await generateWAMessage(jid, { items: [item] }, {
|
|
1172
|
+
logger,
|
|
1173
|
+
userJid,
|
|
1174
|
+
upload: waUploadToServer,
|
|
1175
|
+
mediaCache: config.mediaCache,
|
|
1176
|
+
options: config.options,
|
|
1179
1177
|
...sendOptions,
|
|
1178
|
+
messageId: targetMessageId || generateMessageIDV2(userJid)
|
|
1179
|
+
});
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1182
|
+
const isRichAiMessage = (msg) => !!(
|
|
1183
|
+
msg?.message?.botForwardedMessage?.message?.richResponseMessage ||
|
|
1184
|
+
msg?.message?.richResponseMessage
|
|
1185
|
+
);
|
|
1186
|
+
|
|
1187
|
+
const relayEdit = async (msg, targetId) => {
|
|
1188
|
+
const editedMessage = msg.message;
|
|
1189
|
+
const editMessage = await generateWAMessageFromContent(jid, {
|
|
1190
|
+
botForwardedMessage: { message: { protocolMessage: {
|
|
1191
|
+
key: { remoteJid: jid, fromMe: true, id: targetId },
|
|
1192
|
+
type: 14,
|
|
1193
|
+
editedMessage
|
|
1194
|
+
} } }
|
|
1195
|
+
}, { messageId: generateMessageIDV2(userJid) });
|
|
1196
|
+
|
|
1197
|
+
await relayMessage(jid, editMessage.message, {
|
|
1198
|
+
messageId: editMessage.key.id,
|
|
1199
|
+
additionalNodes: options.additionalNodes || []
|
|
1180
1200
|
});
|
|
1181
|
-
return
|
|
1201
|
+
return editMessage;
|
|
1182
1202
|
};
|
|
1183
1203
|
|
|
1204
|
+
// Build a cumulative snapshot on every step. This is the
|
|
1205
|
+
// important part of buildDelay: each edit contains everything
|
|
1206
|
+
// built so far, rather than replacing the previous message
|
|
1207
|
+
// with only the newest item.
|
|
1208
|
+
const cumulativeItems = [];
|
|
1209
|
+
|
|
1184
1210
|
for (let index = 0; index < items.length; index++) {
|
|
1185
|
-
if (index > 0 && hasDelay)
|
|
1211
|
+
if (index > 0 && hasDelay) {
|
|
1212
|
+
await delay(buildDelay);
|
|
1213
|
+
}
|
|
1186
1214
|
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1215
|
+
cumulativeItems.push(items[index]);
|
|
1216
|
+
|
|
1217
|
+
// AIRich instances represent an already assembled rich
|
|
1218
|
+
// response. For these, use their own build() directly.
|
|
1219
|
+
// For ordinary descriptors we rebuild the cumulative set.
|
|
1220
|
+
let msg;
|
|
1221
|
+
if (cumulativeItems.length === 1 && isAIRichBuilder(cumulativeItems[0])) {
|
|
1222
|
+
msg = await buildItemMessage(cumulativeItems[0]);
|
|
1223
|
+
} else if (cumulativeItems.every(isInteractiveBuilder) && cumulativeItems.length === 1) {
|
|
1224
|
+
msg = await buildItemMessage(cumulativeItems[0]);
|
|
1225
|
+
} else {
|
|
1226
|
+
const hasAirich = cumulativeItems.some(isAIRichBuilder);
|
|
1227
|
+
if (hasAirich) {
|
|
1228
|
+
// Mixed AIRich + descriptor items are flattened by
|
|
1229
|
+
// taking the AIRich message as the current snapshot
|
|
1230
|
+
// and are intentionally not sent as media.
|
|
1231
|
+
const ai = cumulativeItems.find(isAIRichBuilder);
|
|
1232
|
+
msg = await ai.build(jid, { ...sendOptions, messageId: targetMessageId });
|
|
1233
|
+
} else {
|
|
1234
|
+
msg = await generateWAMessage(jid, { items: cumulativeItems }, {
|
|
1235
|
+
logger,
|
|
1236
|
+
userJid,
|
|
1237
|
+
upload: waUploadToServer,
|
|
1238
|
+
mediaCache: config.mediaCache,
|
|
1239
|
+
options: config.options,
|
|
1240
|
+
...sendOptions,
|
|
1241
|
+
messageId: targetMessageId || generateMessageIDV2(userJid)
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
if (!targetMessageId) {
|
|
1247
|
+
targetMessageId = msg.key.id;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
if (index === 0) {
|
|
1251
|
+
const additionalNodes = isInteractiveBuilder(items[index])
|
|
1252
|
+
? [
|
|
1253
|
+
{
|
|
1254
|
+
tag: 'biz',
|
|
1255
|
+
attrs: {},
|
|
1256
|
+
content: [{
|
|
1257
|
+
tag: 'interactive',
|
|
1258
|
+
attrs: { type: 'native_flow', v: '1' },
|
|
1259
|
+
content: [{ tag: 'native_flow', attrs: { v: '9', name: 'mixed' } }],
|
|
1260
|
+
}],
|
|
1261
|
+
},
|
|
1262
|
+
...(options.additionalNodes || []),
|
|
1263
|
+
]
|
|
1264
|
+
: (options.additionalNodes || []);
|
|
1265
|
+
|
|
1266
|
+
await relayMessage(jid, msg.message, {
|
|
1267
|
+
messageId: targetMessageId,
|
|
1268
|
+
additionalNodes,
|
|
1269
|
+
...sendOptions,
|
|
1270
|
+
});
|
|
1271
|
+
|
|
1272
|
+
if (isRichAiMessage(msg) && options.bypassDownload !== false) {
|
|
1273
|
+
await relayEdit(msg, targetMessageId);
|
|
1274
|
+
}
|
|
1190
1275
|
} else {
|
|
1191
|
-
|
|
1192
|
-
// the regular shortcut, preventing build descriptors
|
|
1193
|
-
// from reaching prepareWAMessageMedia().
|
|
1194
|
-
results.push(await sendMessageImpl(jid, { items: [item] }, sendOptions));
|
|
1276
|
+
await relayEdit(msg, targetMessageId);
|
|
1195
1277
|
}
|
|
1278
|
+
|
|
1279
|
+
lastMessage = msg;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
if (lastMessage) {
|
|
1283
|
+
lastMessage.key.id = targetMessageId;
|
|
1196
1284
|
}
|
|
1197
|
-
return
|
|
1285
|
+
return lastMessage;
|
|
1198
1286
|
}
|
|
1199
1287
|
}
|
|
1200
1288
|
// Update rahmi's userJid in case it changed after login
|
|
@@ -826,6 +826,34 @@ const normalizeTableInput = (t, fallbackTitle, fallbackNoHeading) => {
|
|
|
826
826
|
return { rows: [], title: fallbackTitle, noHeading: fallbackNoHeading };
|
|
827
827
|
};
|
|
828
828
|
|
|
829
|
+
/** Buat unified section untuk RICH CARD / ENTITY */
|
|
830
|
+
const makeRichCardSection = (data) => {
|
|
831
|
+
const item = data || {};
|
|
832
|
+
const thumbnailUrl = item.thumbnail_url ?? item.thumbnailUrl ?? item.thumbnail ?? '';
|
|
833
|
+
const profileUrl = item.profile_url ?? item.profileUrl ?? thumbnailUrl;
|
|
834
|
+
|
|
835
|
+
return {
|
|
836
|
+
view_model: {
|
|
837
|
+
primitive: {
|
|
838
|
+
__typename: 'GenAICompactEntityPrimitive',
|
|
839
|
+
title: item.title ?? '',
|
|
840
|
+
subtitle: item.subtitle ?? '',
|
|
841
|
+
secondary_subtitle: item.description ?? '',
|
|
842
|
+
entity_id: item.entity_id ?? item.entityId ?? '',
|
|
843
|
+
entity_url: item.entity_url ?? item.entityUrl ?? '',
|
|
844
|
+
entity_type: item.entity_type ?? 'PAGE',
|
|
845
|
+
action_type: item.action_type ?? 'FOLLOW',
|
|
846
|
+
is_verified: !!item.verification,
|
|
847
|
+
image: {
|
|
848
|
+
url: thumbnailUrl,
|
|
849
|
+
url_fallback: profileUrl
|
|
850
|
+
}
|
|
851
|
+
},
|
|
852
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
};
|
|
856
|
+
|
|
829
857
|
/* ─────────────────────────────────────────────────────────────
|
|
830
858
|
MAIN BUILDER — prepareRichResponseMessage
|
|
831
859
|
───────────────────────────────────────────────────────────── */
|
|
@@ -839,7 +867,7 @@ export const prepareRichResponseMessage = (content) => {
|
|
|
839
867
|
map: mapContent, latex, contentItems,
|
|
840
868
|
// sub-types baru (prefixed 'rich' agar tidak konflik dengan media biasa)
|
|
841
869
|
richImage, richVideo, reels, source, richProduct, richPost, tip, suggest,
|
|
842
|
-
richWidget, widget, richFooterAction, footerAction, richMetadata, metadata, richFOAText, foaText, richHtml,
|
|
870
|
+
richWidget, widget, richFooterAction, footerAction, richMetadata, metadata, richFOAText, foaText, richHtml, richCard,
|
|
843
871
|
// opsi tambahan (belum ada di versi ponta.zip semula)
|
|
844
872
|
aiForwarded
|
|
845
873
|
} = content;
|
|
@@ -928,6 +956,7 @@ export const prepareRichResponseMessage = (content) => {
|
|
|
928
956
|
if (sub.footerAction != null) return push(null, makeFooterActionSection(sub.footerAction));
|
|
929
957
|
if (sub.metadata != null) { const built = makeMetadataSub(sub.metadata); return push(built.sub, built.section); }
|
|
930
958
|
if (sub.foaText != null) { const built = makeMetadataSub(sub.foaText, 'FOATextPrimitive'); return push(built.sub, built.section); }
|
|
959
|
+
if (sub.richCard != null) return push(null, makeRichCardSection(sub.richCard));
|
|
931
960
|
if (sub.richHtml != null) return push(null, makeHtmlSection(sub.richHtml));
|
|
932
961
|
// passthrough — kalau sudah bentuk proto submessage manual
|
|
933
962
|
return push(sub, buildUnifiedSection(sub));
|
|
@@ -1538,6 +1567,7 @@ const translateReadmeItem = (item) => {
|
|
|
1538
1567
|
if (item.richText != null) { out.text = item.richText; }
|
|
1539
1568
|
if (item.richFOAText != null) { out.foaText = item.richFOAText; }
|
|
1540
1569
|
if (item.richHtml != null) { out.richHtml = item.richHtml; }
|
|
1570
|
+
if (item.richCard != null) { out.richCard = item.richCard; }
|
|
1541
1571
|
if (item.richCode != null) { out.code = item.richCode; out.language = item.language; }
|
|
1542
1572
|
if (item.richTable != null) { out.table = item.richTable; }
|
|
1543
1573
|
if (item.richSource != null) { out.source = item.richSource; }
|
package/package.json
CHANGED