plogme 1.0.5 → 2.0.0
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 +113 -1
- package/engine-requirements.js +0 -36
- package/lib/Socket/chats.js +73 -0
- package/lib/Socket/index.js +0 -34
- package/lib/Socket/messages-send.js +85 -110
- package/lib/Socket/socket.js +0 -33
- package/lib/Utils/games/miniapp.js +5 -0
- package/lib/Utils/index.js +2 -0
- package/lib/Utils/message-composer.js +2 -2
- package/lib/Utils/messages.js +145 -76
- package/lib/Utils/meta-compositing.js +0 -11
- package/lib/Utils/rich-message-utils.js +59 -0
- package/lib/Utils/source-grep.js +45 -0
- package/lib/Utils/welcome-flow.js +2 -6
- package/package.json +1 -1
- package/lib/Socket/messages-send.js[latest working] +0 -1759
- package/lib/Utils/integrity.js +0 -296
package/lib/Utils/messages.js
CHANGED
|
@@ -8,8 +8,7 @@ import { AssociationType, ButtonHeaderType, ButtonType, CarouselCardType, ListTy
|
|
|
8
8
|
import { isLidUser, isPnUser, isJidGroup, isJidNewsletter, isJidStatusBroadcast, jidEncode, jidNormalizedUser } from '../WABinary/index.js';
|
|
9
9
|
import { sha256 } from './crypto.js';
|
|
10
10
|
import { generateMessageIDV2, getKeyAuthor, unixTimestampSeconds } from './generics.js';
|
|
11
|
-
import { downloadContentFromMessage, encryptedStream, generateThumbnail, getAudioDuration, getAudioWaveform, getImageProcessingLibrary, getRawMediaUploadData, getStream, toBuffer } from './messages-media.js';
|
|
12
|
-
import { premiumEnabled } from './integrity.js';
|
|
11
|
+
import { downloadContentFromMessage, encryptedStream, extractImageThumb, generateThumbnail, getAudioDuration, getAudioWaveform, getImageProcessingLibrary, getRawMediaUploadData, getStream, toBuffer } from './messages-media.js';
|
|
13
12
|
import { prepareRichResponseMessage } from './rich-message-utils.js';
|
|
14
13
|
import { shouldIncludeReportingToken } from './reporting-utils.js';
|
|
15
14
|
import { getMediaChannelAnnotations } from './channel-policy.js';
|
|
@@ -588,50 +587,7 @@ export const hasOptionalProperty = (obj, key) => {
|
|
|
588
587
|
key in obj &&
|
|
589
588
|
obj[key] != null;
|
|
590
589
|
};
|
|
591
|
-
//
|
|
592
|
-
// Keys the fork added on top of plain Baileys messaging. On an unlicensed
|
|
593
|
-
// copy these are stripped so the message degrades to plain messaging; if
|
|
594
|
-
// nothing plain remains, a visible notice is sent instead (a watermark the
|
|
595
|
-
// stolen bot's own users see).
|
|
596
|
-
const PREMIUM_KEYS = [
|
|
597
|
-
'code', 'table', 'links', 'richResponse', // rich messages
|
|
598
|
-
'richPreview', 'previewTitle', 'previewDescription', 'previewImage', // rich preview
|
|
599
|
-
'verifiedMe', // verified badge
|
|
600
|
-
'secureMetaServiceLabel', // meta service label
|
|
601
|
-
'gifPlayback', 'ptv', 'isLottie', // media extras
|
|
602
|
-
'album', 'cards', 'audioFooter', // albums / carousels
|
|
603
|
-
'likeThis', 'raw', // raw relay
|
|
604
|
-
'followMe', // auto-follow
|
|
605
|
-
'groupStatus', 'status', // status / group status
|
|
606
|
-
'paymentInviteServiceType', 'orderText', 'requestPaymentFrom', // payments
|
|
607
|
-
'pollResult', // poll result snapshot
|
|
608
|
-
'interactiveAsTemplate', // template wrapper
|
|
609
|
-
'offerText', 'offerCode', 'offerUrl', 'offerExpiration', // native flow offers
|
|
610
|
-
'optionText', 'optionTitle' // native flow options
|
|
611
|
-
];
|
|
612
|
-
const PLAIN_KEYS = [
|
|
613
|
-
'text',
|
|
614
|
-
'image', 'video', 'audio', 'document', 'sticker',
|
|
615
|
-
'contacts', 'location',
|
|
616
|
-
'poll', 'pollUpdate', 'event', 'groupInvite',
|
|
617
|
-
'react', 'delete', 'forward', 'edit', 'pin', 'keep',
|
|
618
|
-
'disappearingMessagesInChat',
|
|
619
|
-
'sharePhoneNumber', 'requestPhoneNumber', 'limitSharing',
|
|
620
|
-
'buttonReply', 'listReply', 'flowReply'
|
|
621
|
-
];
|
|
622
|
-
export const downgradePremiumContent = (message) => {
|
|
623
|
-
for (const key of PREMIUM_KEYS) {
|
|
624
|
-
delete message[key];
|
|
625
|
-
}
|
|
626
|
-
const hasMedia = ['image', 'video', 'audio', 'document', 'sticker']
|
|
627
|
-
.some(key => hasNonNullishProperty(message, key));
|
|
628
|
-
const hasPlain = hasMedia || PLAIN_KEYS.some(key => hasNonNullishProperty(message, key));
|
|
629
|
-
if (!hasPlain) {
|
|
630
|
-
message.text = '⚠️ This bot is running an unlicensed copy of @crysnovax/baileys — premium features are disabled.';
|
|
631
|
-
}
|
|
632
|
-
return message;
|
|
633
|
-
};
|
|
634
|
-
// Lia@Changes 06-02-26 --- Validate album message media to avoid bug 👀
|
|
590
|
+
// Lia@Changes 06-02-26 --- Validate album message media to avoid bug
|
|
635
591
|
export const hasValidAlbumMedia = (message) => {
|
|
636
592
|
return !!(message.imageMessage ||
|
|
637
593
|
message.videoMessage);
|
|
@@ -643,7 +599,7 @@ export const hasValidInteractiveHeader = (message) => {
|
|
|
643
599
|
message.productMessage ||
|
|
644
600
|
message.locationMessage);
|
|
645
601
|
};
|
|
646
|
-
// Lia@Changes 30-01-26 --- Validate carousel cards header to avoid bug
|
|
602
|
+
// Lia@Changes 30-01-26 --- Validate carousel cards header to avoid bug
|
|
647
603
|
export const hasValidCarouselHeader = (message) => {
|
|
648
604
|
return !!(message.imageMessage ||
|
|
649
605
|
message.videoMessage ||
|
|
@@ -651,21 +607,49 @@ export const hasValidCarouselHeader = (message) => {
|
|
|
651
607
|
};
|
|
652
608
|
export const generateWAMessageContent = async (message, options) => {
|
|
653
609
|
var _a, _b;
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
610
|
+
const fixupExternalAdReply = async (externalAdReply) => {
|
|
611
|
+
if (!externalAdReply || typeof externalAdReply !== 'object') {
|
|
612
|
+
return externalAdReply;
|
|
613
|
+
}
|
|
614
|
+
const thumbUrl = externalAdReply.originalImageUrl || externalAdReply.thumbnailUrl;
|
|
615
|
+
const currentThumb = externalAdReply.thumbnail;
|
|
616
|
+
const currentThumbLength = currentThumb && typeof currentThumb.length === 'number' ? currentThumb.length : 0;
|
|
617
|
+
if (thumbUrl && (!currentThumb || currentThumbLength < 2000)) {
|
|
618
|
+
try {
|
|
619
|
+
const response = await fetch(thumbUrl, { signal: AbortSignal.timeout(7000) });
|
|
620
|
+
if (response.ok) {
|
|
621
|
+
const downloaded = Buffer.from(await response.arrayBuffer());
|
|
622
|
+
if (downloaded.length) {
|
|
623
|
+
const { buffer } = await extractImageThumb(downloaded, 192);
|
|
624
|
+
if (buffer?.length) {
|
|
625
|
+
externalAdReply.thumbnail = buffer;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
catch (error) {
|
|
631
|
+
options?.logger?.warn?.({ err: error?.message, url: thumbUrl }, 'failed to download externalAdReply thumbnail');
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
const thumbnail = externalAdReply.thumbnail;
|
|
635
|
+
const hasThumbnail = !!(thumbnail && (thumbnail.length || thumbnail.byteLength));
|
|
636
|
+
const isPrivateUrl = (value) => typeof value === 'string' && /(?:^|[/.])[a-z0-9-]*\.?whatsapp\.net\//i.test(value);
|
|
637
|
+
if (hasThumbnail) {
|
|
638
|
+
if (isPrivateUrl(externalAdReply.thumbnailUrl)) delete externalAdReply.thumbnailUrl;
|
|
639
|
+
if (isPrivateUrl(externalAdReply.originalImageUrl)) delete externalAdReply.originalImageUrl;
|
|
640
|
+
}
|
|
641
|
+
if (externalAdReply.mediaType == null) externalAdReply.mediaType = hasThumbnail ? 1 : 0;
|
|
642
|
+
if (externalAdReply.showAdAttribution === undefined) externalAdReply.showAdAttribution = false;
|
|
643
|
+
if (externalAdReply.renderLargerThumbnail === undefined) externalAdReply.renderLargerThumbnail = hasThumbnail;
|
|
644
|
+
return externalAdReply;
|
|
645
|
+
};
|
|
646
|
+
if (message.contextInfo?.externalAdReply) {
|
|
647
|
+
message.contextInfo.externalAdReply = await fixupExternalAdReply(message.contextInfo.externalAdReply);
|
|
648
|
+
}
|
|
649
|
+
if (message.externalAdReply) {
|
|
650
|
+
message.externalAdReply = await fixupExternalAdReply(message.externalAdReply);
|
|
668
651
|
}
|
|
652
|
+
let m = {};
|
|
669
653
|
// Lia@Changes 30-01-26 --- Add "raw" boolean to send raw messages directly via generateWAMessage()
|
|
670
654
|
if (hasNonNullishProperty(message, 'raw')) {
|
|
671
655
|
delete message.raw;
|
|
@@ -957,6 +941,100 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
957
941
|
vote: message.pollUpdate.vote
|
|
958
942
|
};
|
|
959
943
|
}
|
|
944
|
+
else if (hasNonNullishProperty(message, 'statusStickerInteraction')) {
|
|
945
|
+
const interaction = message.statusStickerInteraction;
|
|
946
|
+
m.statusStickerInteractionMessage = proto.Message.StatusStickerInteractionMessage.fromObject({
|
|
947
|
+
key: interaction.key,
|
|
948
|
+
stickerKey: interaction.stickerKey,
|
|
949
|
+
type: interaction.type ?? proto.Message.StatusStickerInteractionMessage.StatusStickerType.REACTION
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
else if (hasNonNullishProperty(message, 'statusQuoted')) {
|
|
953
|
+
const quoted = message.statusQuoted;
|
|
954
|
+
m.statusQuotedMessage = proto.Message.StatusQuotedMessage.fromObject({
|
|
955
|
+
type: quoted.type ?? proto.Message.StatusQuotedMessage.StatusQuotedMessageType.QUESTION_ANSWER,
|
|
956
|
+
text: quoted.text,
|
|
957
|
+
thumbnail: quoted.thumbnail,
|
|
958
|
+
originalStatusId: quoted.originalStatusId
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
else if (hasNonNullishProperty(message, 'statusQuestionAnswer')) {
|
|
962
|
+
m.statusQuestionAnswerMessage = proto.Message.StatusQuestionAnswerMessage.fromObject(message.statusQuestionAnswer);
|
|
963
|
+
}
|
|
964
|
+
else if (hasNonNullishProperty(message, 'questionResponse')) {
|
|
965
|
+
m.questionResponseMessage = proto.Message.QuestionResponseMessage.fromObject(message.questionResponse);
|
|
966
|
+
}
|
|
967
|
+
else if (hasNonNullishProperty(message, 'comment')) {
|
|
968
|
+
const comment = message.comment;
|
|
969
|
+
m.commentMessage = proto.Message.CommentMessage.fromObject({ message: comment.message, targetMessageKey: comment.targetMessageKey });
|
|
970
|
+
}
|
|
971
|
+
else if (hasNonNullishProperty(message, 'statusNotification')) {
|
|
972
|
+
m.statusNotificationMessage = proto.Message.StatusNotificationMessage.fromObject(message.statusNotification);
|
|
973
|
+
}
|
|
974
|
+
else if (hasNonNullishProperty(message, 'stickerSyncRMR')) {
|
|
975
|
+
const sync = message.stickerSyncRMR;
|
|
976
|
+
m.stickerSyncRmrMessage = proto.Message.StickerSyncRMRMessage.fromObject({
|
|
977
|
+
filehash: sync.filehash || sync.fileHash || [],
|
|
978
|
+
rmrSource: sync.rmrSource,
|
|
979
|
+
requestTimestamp: sync.requestTimestamp ?? Date.now()
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
else if (hasNonNullishProperty(message, 'sendPayment')) {
|
|
983
|
+
const payment = message.sendPayment;
|
|
984
|
+
m.sendPaymentMessage = proto.Message.SendPaymentMessage.fromObject({
|
|
985
|
+
requestMessageKey: payment.requestMessageKey,
|
|
986
|
+
noteMessage: payment.noteMessage,
|
|
987
|
+
background: payment.background,
|
|
988
|
+
transactionData: payment.transactionData
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
else if (hasNonNullishProperty(message, 'declinePayment')) {
|
|
992
|
+
m.declinePaymentRequestMessage = proto.Message.DeclinePaymentRequestMessage.fromObject({ key: message.declinePayment.key || message.declinePayment });
|
|
993
|
+
}
|
|
994
|
+
else if (hasNonNullishProperty(message, 'cancelPayment')) {
|
|
995
|
+
m.cancelPaymentRequestMessage = proto.Message.CancelPaymentRequestMessage.fromObject({ key: message.cancelPayment.key || message.cancelPayment });
|
|
996
|
+
}
|
|
997
|
+
else if (hasNonNullishProperty(message, 'scheduledCallEdit')) {
|
|
998
|
+
m.scheduledCallEditMessage = proto.Message.ScheduledCallEditMessage.fromObject(message.scheduledCallEdit);
|
|
999
|
+
}
|
|
1000
|
+
else if (hasNonNullishProperty(message, 'secretEncrypted')) {
|
|
1001
|
+
m.secretEncryptedMessage = proto.Message.SecretEncryptedMessage.fromObject(message.secretEncrypted);
|
|
1002
|
+
}
|
|
1003
|
+
else if (hasNonNullishProperty(message, 'encComment')) {
|
|
1004
|
+
m.encCommentMessage = proto.Message.EncCommentMessage.fromObject(message.encComment);
|
|
1005
|
+
}
|
|
1006
|
+
else if (hasNonNullishProperty(message, 'encEventResponse')) {
|
|
1007
|
+
m.encEventResponseMessage = proto.Message.EncEventResponseMessage.fromObject(message.encEventResponse);
|
|
1008
|
+
}
|
|
1009
|
+
else if (hasNonNullishProperty(message, 'messageHistoryBundle')) {
|
|
1010
|
+
const bundle = message.messageHistoryBundle;
|
|
1011
|
+
const media = bundle.media ? await prepareWAMessageMedia({ document: bundle.media }, options) : undefined;
|
|
1012
|
+
const document = media?.documentMessage;
|
|
1013
|
+
m.messageHistoryBundle = proto.Message.MessageHistoryBundle.fromObject({
|
|
1014
|
+
mimetype: bundle.mimetype || document?.mimetype || 'application/octet-stream',
|
|
1015
|
+
fileSha256: bundle.fileSha256 || document?.fileSha256,
|
|
1016
|
+
mediaKey: bundle.mediaKey || document?.mediaKey,
|
|
1017
|
+
fileEncSha256: bundle.fileEncSha256 || document?.fileEncSha256,
|
|
1018
|
+
directPath: bundle.directPath || document?.directPath,
|
|
1019
|
+
mediaKeyTimestamp: bundle.mediaKeyTimestamp || document?.mediaKeyTimestamp,
|
|
1020
|
+
contextInfo: bundle.contextInfo,
|
|
1021
|
+
messageHistoryMetadata: bundle.messageHistoryMetadata
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
else if (hasNonNullishProperty(message, 'messageHistoryNotice')) {
|
|
1025
|
+
m.messageHistoryNotice = proto.Message.MessageHistoryNotice.fromObject(message.messageHistoryNotice);
|
|
1026
|
+
}
|
|
1027
|
+
else if (hasNonNullishProperty(message, 'inviteAdmin')) {
|
|
1028
|
+
const invite = message.inviteAdmin;
|
|
1029
|
+
m.newsletterAdminInviteMessage = proto.Message.NewsletterAdminInviteMessage.fromObject({
|
|
1030
|
+
newsletterJid: invite.newsletterJid || invite.jid,
|
|
1031
|
+
newsletterName: invite.newsletterName || invite.subject,
|
|
1032
|
+
jpegThumbnail: invite.jpegThumbnail || invite.thumbnail,
|
|
1033
|
+
caption: invite.caption || invite.text,
|
|
1034
|
+
inviteExpiration: invite.inviteExpiration,
|
|
1035
|
+
contextInfo: invite.contextInfo
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
960
1038
|
// Lia@Changes 01-02-26 --- Add payment invite message
|
|
961
1039
|
else if (hasNonNullishProperty(message, 'paymentInviteServiceType')) {
|
|
962
1040
|
m.paymentInviteMessage = {
|
|
@@ -1358,21 +1436,18 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1358
1436
|
const messageType = Object.keys(m)[0];
|
|
1359
1437
|
const key = m[messageType];
|
|
1360
1438
|
const content = message.externalAdReply;
|
|
1361
|
-
if ('thumbnail' in content && !Buffer.isBuffer(content.thumbnail)) {
|
|
1439
|
+
if ('thumbnail' in content && content.thumbnail != null && !Buffer.isBuffer(content.thumbnail) && !(content.thumbnail instanceof Uint8Array)) {
|
|
1362
1440
|
throw new Boom('Thumbnail must in buffer type', { statusCode: 400 });
|
|
1363
1441
|
}
|
|
1364
|
-
if (!content.url || typeof content.url !== 'string') {
|
|
1365
|
-
content.url = DONATE_URL; // Lia@Note 02-02-26 --- Apologies if this feels cheeky, just a fallback
|
|
1366
|
-
}
|
|
1367
1442
|
const externalAdReply = {
|
|
1368
1443
|
...content,
|
|
1369
1444
|
body: content.body,
|
|
1370
|
-
mediaType: content.mediaType
|
|
1371
|
-
mediaUrl: content.url,
|
|
1372
|
-
renderLargerThumbnail: content.largeThumbnail,
|
|
1373
|
-
sourceUrl: content.url,
|
|
1445
|
+
mediaType: content.mediaType ?? (content.thumbnail ? 1 : 0),
|
|
1446
|
+
mediaUrl: content.mediaUrl || content.url,
|
|
1447
|
+
renderLargerThumbnail: content.largeThumbnail ?? content.renderLargerThumbnail ?? !!content.thumbnail,
|
|
1448
|
+
sourceUrl: content.sourceUrl || content.url,
|
|
1374
1449
|
thumbnail: content.thumbnail,
|
|
1375
|
-
thumbnailUrl: content.url + '?update=' + Date.now(),
|
|
1450
|
+
thumbnailUrl: content.thumbnailUrl || content.originalImageUrl || (content.url ? content.url + '?update=' + Date.now() : undefined),
|
|
1376
1451
|
title: content.title || LIBRARY_NAME
|
|
1377
1452
|
};
|
|
1378
1453
|
delete externalAdReply.subTitle;
|
|
@@ -1480,12 +1555,6 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1480
1555
|
// synthetic quoted message fallback if none is already present, matching
|
|
1481
1556
|
// the same pattern.
|
|
1482
1557
|
if (hasOptionalProperty(message, 'verifiedMe') && !!message.verifiedMe) {
|
|
1483
|
-
// Premium feature — only on genuine @crysnovax/baileys distributions.
|
|
1484
|
-
if (!premiumEnabled(options?.logger)) {
|
|
1485
|
-
options?.logger?.warn?.({}, 'verifiedMe badge is a premium feature and is disabled on unlicensed copies');
|
|
1486
|
-
delete message.verifiedMe;
|
|
1487
|
-
return m;
|
|
1488
|
-
}
|
|
1489
1558
|
const messageType = Object.keys(m)[0];
|
|
1490
1559
|
const isMediaMessage = messageType === 'imageMessage' || messageType === 'videoMessage';
|
|
1491
1560
|
if (isMediaMessage) {
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
|
|
15
15
|
import { proto } from '../../WAProto/index.js';
|
|
16
16
|
import { BOT_RENDERING_CONFIG_METADATA } from '../Defaults/index.js';
|
|
17
|
-
import { premiumEnabled } from './integrity.js';
|
|
18
17
|
import { delay } from './generics.js';
|
|
19
18
|
|
|
20
19
|
// ─── Step status enum ───
|
|
@@ -135,11 +134,6 @@ export const metaTyping = async (sock, jid, {
|
|
|
135
134
|
placeholderText = '',
|
|
136
135
|
useNativeMeta = false
|
|
137
136
|
} = {}) => {
|
|
138
|
-
// Premium feature — on unlicensed copies the progress indicator is skipped
|
|
139
|
-
// entirely (callers already guard deletes with placeholder?.key).
|
|
140
|
-
if (!premiumEnabled(sock.config?.logger)) {
|
|
141
|
-
return { key: undefined };
|
|
142
|
-
}
|
|
143
137
|
// Show typing indicator
|
|
144
138
|
await sock.sendPresenceUpdate('composing', jid);
|
|
145
139
|
|
|
@@ -175,11 +169,6 @@ export const sendMetaComposited = async (sock, jid, content, {
|
|
|
175
169
|
sendOptions = {},
|
|
176
170
|
useNativeMeta = false
|
|
177
171
|
} = {}) => {
|
|
178
|
-
// Premium feature — on unlicensed copies skip the whole Meta AI flow and
|
|
179
|
-
// just send the final content (the composer downgrades it to plain text).
|
|
180
|
-
if (!premiumEnabled(sock.config?.logger)) {
|
|
181
|
-
return sock.sendMessage(jid, content, sendOptions);
|
|
182
|
-
}
|
|
183
172
|
const placeholder = await metaTyping(sock, jid, {
|
|
184
173
|
description, steps, estimatedMs: thinkingMs, placeholderText, useNativeMeta
|
|
185
174
|
});
|
|
@@ -947,6 +947,65 @@ export const prepareHtmlMessage = (options = {}) => {
|
|
|
947
947
|
return wrapToBotForwardedMessage(richResponseMessage);
|
|
948
948
|
};
|
|
949
949
|
|
|
950
|
+
/**
|
|
951
|
+
* Build the alternate GenAI HTML envelope used by interactive HTML screens.
|
|
952
|
+
* Unlike prepareHtmlMessage(), this includes embedded_screens and uses the
|
|
953
|
+
* aeacdsnw HTML primitive used by the attached game message.
|
|
954
|
+
*/
|
|
955
|
+
export const prepareRichHtmlMessage = (options = {}) => {
|
|
956
|
+
const {
|
|
957
|
+
html = '',
|
|
958
|
+
trustedSources = [],
|
|
959
|
+
url = '',
|
|
960
|
+
title = 'Preview',
|
|
961
|
+
tabHeader = 'HTML',
|
|
962
|
+
tabs
|
|
963
|
+
} = options;
|
|
964
|
+
const tabItems = Array.isArray(tabs) && tabs.length
|
|
965
|
+
? tabs
|
|
966
|
+
: [{ id: 'tab_0', tab_header: tabHeader, html }];
|
|
967
|
+
const embeddedTabs = tabItems.map((tab, index) => ({
|
|
968
|
+
id: tab.id || `tab_${index}`,
|
|
969
|
+
tab_header: tab.tab_header || tab.title || `HTML ${index + 1}`,
|
|
970
|
+
sections: [{
|
|
971
|
+
__typename: 'GenAIUnifiedResponseSection',
|
|
972
|
+
view_model: {
|
|
973
|
+
__typename: 'GenAISingleLayoutViewModel',
|
|
974
|
+
primitive: {
|
|
975
|
+
__typename: 'GenAIaeacdsnwHtmlPrimitive',
|
|
976
|
+
payload: String(tab.html ?? tab.payload ?? html).trim(),
|
|
977
|
+
url: tab.url || url,
|
|
978
|
+
trusted_sources: tab.trustedSources || trustedSources
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
}],
|
|
982
|
+
step_entries: []
|
|
983
|
+
}));
|
|
984
|
+
const unified = {
|
|
985
|
+
response_id: randomUUID(),
|
|
986
|
+
sections: [{
|
|
987
|
+
view_model: {
|
|
988
|
+
primitive: { text: `> ${title}`, __typename: 'GenAIMarkdownTextUXPrimitive' },
|
|
989
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
990
|
+
}
|
|
991
|
+
}],
|
|
992
|
+
embedded_screens: [{
|
|
993
|
+
title,
|
|
994
|
+
content: [{
|
|
995
|
+
__typename: 'FOAIDNixelButtonSheets',
|
|
996
|
+
tabs: embeddedTabs
|
|
997
|
+
}]
|
|
998
|
+
}]
|
|
999
|
+
};
|
|
1000
|
+
const richResponseMessage = proto.AIRichResponseMessage.create({
|
|
1001
|
+
messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
|
|
1002
|
+
submessages: [{ messageType: RichSubMessageType.TEXT, messageText: `> ${title}` }],
|
|
1003
|
+
unifiedResponse: { data: Buffer.from(JSON.stringify(unified)) },
|
|
1004
|
+
contextInfo: { isForwarded: true, forwardingScore: 1, forwardOrigin: 4 }
|
|
1005
|
+
});
|
|
1006
|
+
return wrapToBotForwardedMessage(richResponseMessage);
|
|
1007
|
+
};
|
|
1008
|
+
|
|
950
1009
|
export const wrapToBotForwardedMessage = (richResponseMessage) => ({
|
|
951
1010
|
messageContextInfo: {
|
|
952
1011
|
botMetadata: {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
|
|
6
|
+
const DEFAULT_DIRS = ['lib', 'WAProto'];
|
|
7
|
+
const DEFAULT_EXTENSIONS = new Set(['.js', '.mjs', '.cjs', '.ts', '.d.ts', '.proto', '.md', '.json']);
|
|
8
|
+
|
|
9
|
+
const walk = (directory, files) => {
|
|
10
|
+
if (!fs.existsSync(directory)) return;
|
|
11
|
+
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
12
|
+
if (entry.name === 'node_modules' || entry.name.startsWith('.')) continue;
|
|
13
|
+
const fullPath = path.join(directory, entry.name);
|
|
14
|
+
if (entry.isDirectory()) walk(fullPath, files);
|
|
15
|
+
else if (DEFAULT_EXTENSIONS.has(path.extname(entry.name))) files.push(fullPath);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Find a literal or regular-expression pattern in package source.
|
|
21
|
+
* Returns exact relative file, line, column, and matching source line.
|
|
22
|
+
*/
|
|
23
|
+
export const grepSource = (pattern, options = {}) => {
|
|
24
|
+
if (typeof pattern !== 'string' || !pattern.trim()) {
|
|
25
|
+
throw new TypeError('grepSource requires a non-empty search string');
|
|
26
|
+
}
|
|
27
|
+
const expression = options.regex ? new RegExp(pattern, options.flags || 'i') : null;
|
|
28
|
+
const needle = options.caseSensitive ? pattern : pattern.toLowerCase();
|
|
29
|
+
const files = [];
|
|
30
|
+
for (const relativeDir of options.dirs || DEFAULT_DIRS) walk(path.resolve(PACKAGE_ROOT, relativeDir), files);
|
|
31
|
+
if (options.includeReadme) files.push(path.resolve(PACKAGE_ROOT, 'README.md'));
|
|
32
|
+
const matches = [];
|
|
33
|
+
for (const file of files.sort()) {
|
|
34
|
+
const lines = fs.readFileSync(file, 'utf8').split(/\r?\n/);
|
|
35
|
+
lines.forEach((line, index) => {
|
|
36
|
+
const found = expression ? expression.test(line) : (options.caseSensitive ? line.includes(pattern) : line.toLowerCase().includes(needle));
|
|
37
|
+
if (found) {
|
|
38
|
+
const column = expression ? Math.max(0, line.search(expression)) : (options.caseSensitive ? line.indexOf(pattern) : line.toLowerCase().indexOf(needle));
|
|
39
|
+
matches.push({ file: path.relative(PACKAGE_ROOT, file), line: index + 1, column: column + 1, text: line.trim() });
|
|
40
|
+
}
|
|
41
|
+
if (expression) expression.lastIndex = 0;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return matches.slice(0, Math.max(1, options.maxResults || 200));
|
|
45
|
+
};
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
|
|
22
22
|
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
23
23
|
import { isJidGroup, isJidNewsletter, isJidBroadcast, jidNormalizedUser } from '../WABinary/index.js';
|
|
24
|
-
import { premiumEnabled } from './integrity.js';
|
|
25
24
|
import { delay } from './generics.js';
|
|
26
25
|
|
|
27
26
|
// ─── Defaults ────────────────────────────────────────────────────────────────
|
|
@@ -162,11 +161,8 @@ export const createWelcomeFlow = (sock, config = {}) => {
|
|
|
162
161
|
await sock.sendPresenceUpdate('paused', jid);
|
|
163
162
|
}
|
|
164
163
|
|
|
165
|
-
// Send the welcome message
|
|
166
|
-
|
|
167
|
-
? buildWelcomeMessage(cfg, msg)
|
|
168
|
-
: { text: cfg.greeting };
|
|
169
|
-
await sock.sendMessage(jid, welcomeContent);
|
|
164
|
+
// Send the configured welcome message.
|
|
165
|
+
await sock.sendMessage(jid, buildWelcomeMessage(cfg, msg));
|
|
170
166
|
|
|
171
167
|
// Fire onGreet callback if provided
|
|
172
168
|
if (typeof cfg.onGreet === 'function') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plogme",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Production-ready Baileys fork \u2689 with AI groups, Meta AI prompting, safe compositing fallbacks, rich responses, interactive messages, albums, newsletters, and communities \u2014 without antiban wrappers.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"type": "module",
|