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.
@@ -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
- // ─── Premium downgrade (revoked / rebranded copies) ───────────────────────────
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
- let m = {};
655
- // Premium downgrade: on revoked/rebranded copies, strip every feature the
656
- // fork added and fall back to plain messaging (or a visible notice).
657
- if (!premiumEnabled(options?.logger)) {
658
- downgradePremiumContent(message);
659
- }
660
- // Premium gate — secureMetaServiceLabel is only honored on genuine copies.
661
- // Stripping it here means the sender's isNeedBizAttrs check (which runs after
662
- // generateWAMessage on the same content object) sees it as absent, so the
663
- // business-node attributes silently degrade on unlicensed copies.
664
- if (hasNonNullishProperty(message, 'secureMetaServiceLabel') &&
665
- !!message.secureMetaServiceLabel &&
666
- !premiumEnabled(options?.logger)) {
667
- delete message.secureMetaServiceLabel;
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 || 1,
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 (plain text greeting on unlicensed copies)
166
- const welcomeContent = premiumEnabled(sock.config?.logger)
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": "1.0.5",
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",