plogme 1.0.6 → 2.0.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.
@@ -9,7 +9,6 @@ import { isLidUser, isPnUser, isJidGroup, isJidNewsletter, isJidStatusBroadcast,
9
9
  import { sha256 } from './crypto.js';
10
10
  import { generateMessageIDV2, getKeyAuthor, unixTimestampSeconds } from './generics.js';
11
11
  import { downloadContentFromMessage, encryptedStream, extractImageThumb, generateThumbnail, getAudioDuration, getAudioWaveform, getImageProcessingLibrary, getRawMediaUploadData, getStream, toBuffer } from './messages-media.js';
12
- import { premiumEnabled } from './integrity.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 ||
@@ -694,20 +650,6 @@ export const generateWAMessageContent = async (message, options) => {
694
650
  message.externalAdReply = await fixupExternalAdReply(message.externalAdReply);
695
651
  }
696
652
  let m = {};
697
- // Premium downgrade: on revoked/rebranded copies, strip every feature the
698
- // fork added and fall back to plain messaging (or a visible notice).
699
- if (!premiumEnabled(options?.logger)) {
700
- downgradePremiumContent(message);
701
- }
702
- // Premium gate — secureMetaServiceLabel is only honored on genuine copies.
703
- // Stripping it here means the sender's isNeedBizAttrs check (which runs after
704
- // generateWAMessage on the same content object) sees it as absent, so the
705
- // business-node attributes silently degrade on unlicensed copies.
706
- if (hasNonNullishProperty(message, 'secureMetaServiceLabel') &&
707
- !!message.secureMetaServiceLabel &&
708
- !premiumEnabled(options?.logger)) {
709
- delete message.secureMetaServiceLabel;
710
- }
711
653
  // Lia@Changes 30-01-26 --- Add "raw" boolean to send raw messages directly via generateWAMessage()
712
654
  if (hasNonNullishProperty(message, 'raw')) {
713
655
  delete message.raw;
@@ -1155,6 +1097,11 @@ export const generateWAMessageContent = async (message, options) => {
1155
1097
  else if (hasNonNullishProperty(message, 'chatTheme')) {
1156
1098
  const theme = message.chatTheme || {};
1157
1099
  const themeSetting = {};
1100
+ if (theme.colorSchemeId || theme.chatThemeId) {
1101
+ const colorSchemeId = theme.colorSchemeId ||
1102
+ (String(theme.chatThemeId).includes('@') ? theme.chatThemeId : `${theme.chatThemeId}@Tonal`);
1103
+ themeSetting.colorSchemeId = String(colorSchemeId);
1104
+ }
1158
1105
  if (theme.animatedWallpaper) {
1159
1106
  const wallpaper = theme.animatedWallpaper;
1160
1107
  themeSetting.animatedWallpaper = proto.Message.ChatAnimatedWallpaper.fromObject({
@@ -1511,7 +1458,7 @@ export const generateWAMessageContent = async (message, options) => {
1511
1458
  delete externalAdReply.subTitle;
1512
1459
  delete externalAdReply.largeThumbnail;
1513
1460
  delete externalAdReply.url;
1514
- if ('contextInfo' in key && !!key.contextInfo) {
1461
+ if (key && 'contextInfo' in key && !!key.contextInfo) {
1515
1462
  key.contextInfo.externalAdReply = { ...key.contextInfo.externalAdReply, ...externalAdReply };
1516
1463
  }
1517
1464
  else if (key) {
@@ -1541,7 +1488,7 @@ export const generateWAMessageContent = async (message, options) => {
1541
1488
  if (hasOptionalProperty(message, 'contextInfo') && !!message.contextInfo) {
1542
1489
  const messageType = Object.keys(m)[0];
1543
1490
  const key = m[messageType];
1544
- if ('contextInfo' in key && !!key.contextInfo) {
1491
+ if (key && 'contextInfo' in key && !!key.contextInfo) {
1545
1492
  key.contextInfo = { ...key.contextInfo, ...message.contextInfo };
1546
1493
  }
1547
1494
  else if (key) {
@@ -1552,7 +1499,7 @@ export const generateWAMessageContent = async (message, options) => {
1552
1499
  if (hasOptionalProperty(message, 'groupStatus') && !!message.groupStatus) {
1553
1500
  const messageType = Object.keys(m)[0];
1554
1501
  const key = m[messageType];
1555
- if ('contextInfo' in key && !!key.contextInfo) {
1502
+ if (key && 'contextInfo' in key && !!key.contextInfo) {
1556
1503
  key.contextInfo.isGroupStatus = message.groupStatus;
1557
1504
  }
1558
1505
  else if (key) {
@@ -1578,7 +1525,7 @@ export const generateWAMessageContent = async (message, options) => {
1578
1525
  m = { viewOnceMessage: { message: m } };
1579
1526
  }
1580
1527
  else if (mediaSpoiler && mediaSpoilerMode === 'native') {
1581
- if ('contextInfo' in key && !!key.contextInfo) {
1528
+ if (key && 'contextInfo' in key && !!key.contextInfo) {
1582
1529
  key.contextInfo.isSpoiler = true;
1583
1530
  }
1584
1531
  else if (key) {
@@ -1613,12 +1560,6 @@ export const generateWAMessageContent = async (message, options) => {
1613
1560
  // synthetic quoted message fallback if none is already present, matching
1614
1561
  // the same pattern.
1615
1562
  if (hasOptionalProperty(message, 'verifiedMe') && !!message.verifiedMe) {
1616
- // Premium feature — only on genuine @crysnovax/baileys distributions.
1617
- if (!premiumEnabled(options?.logger)) {
1618
- options?.logger?.warn?.({}, 'verifiedMe badge is a premium feature and is disabled on unlicensed copies');
1619
- delete message.verifiedMe;
1620
- return m;
1621
- }
1622
1563
  const messageType = Object.keys(m)[0];
1623
1564
  const isMediaMessage = messageType === 'imageMessage' || messageType === 'videoMessage';
1624
1565
  if (isMediaMessage) {
@@ -1628,7 +1569,7 @@ export const generateWAMessageContent = async (message, options) => {
1628
1569
  participant: '0@s.whatsapp.net',
1629
1570
  remoteJid: '0@s.whatsapp.net'
1630
1571
  };
1631
- if ('contextInfo' in key && !!key.contextInfo) {
1572
+ if (key && 'contextInfo' in key && !!key.contextInfo) {
1632
1573
  key.contextInfo = { ...key.contextInfo, ...verifiedContext };
1633
1574
  }
1634
1575
  else if (key) {
@@ -1727,7 +1668,7 @@ export const generateWAMessageFromContent = (jid, message, options) => {
1727
1668
  if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
1728
1669
  delete quotedContent.contextInfo;
1729
1670
  }
1730
- const contextInfo = ('contextInfo' in innerMessage[key] && innerMessage[key]?.contextInfo) || {};
1671
+ const contextInfo = (innerMessage[key] && 'contextInfo' in innerMessage[key] && innerMessage[key]?.contextInfo) || {};
1731
1672
  contextInfo.participant = jidNormalizedUser(participant);
1732
1673
  contextInfo.stanzaId = quoted.key.id;
1733
1674
  contextInfo.quotedMessage = quotedMsg;
@@ -14,7 +14,7 @@
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';
17
+ import { BotCapabilityType, buildBotCapabilityMetadata } from './bot-capabilities.js';
18
18
  import { delay } from './generics.js';
19
19
 
20
20
  // ─── Step status enum ───
@@ -89,10 +89,16 @@ export const buildCompositingPlaceholder = ({
89
89
  unifiedResponse: { data: unifiedData },
90
90
  submessages: []
91
91
  };
92
+ const capabilities = [
93
+ BotCapabilityType.PROGRESS_INDICATOR,
94
+ ...(steps.length ? [BotCapabilityType.AGENTIC_PLANNING] : []),
95
+ ...(steps.some(step => step.queryPlan || step.type === 'query') ? [BotCapabilityType.QUERY_PLAN] : [])
96
+ ];
92
97
 
93
98
  return {
94
99
  messageContextInfo: {
95
100
  botMetadata: {
101
+ capabilityMetadata: buildBotCapabilityMetadata(capabilities),
96
102
  pluginMetadata: {},
97
103
  progressIndicatorMetadata,
98
104
  botRenderingConfigMetadata: BOT_RENDERING_CONFIG_METADATA,
@@ -135,11 +141,6 @@ export const metaTyping = async (sock, jid, {
135
141
  placeholderText = '',
136
142
  useNativeMeta = false
137
143
  } = {}) => {
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
144
  // Show typing indicator
144
145
  await sock.sendPresenceUpdate('composing', jid);
145
146
 
@@ -175,11 +176,6 @@ export const sendMetaComposited = async (sock, jid, content, {
175
176
  sendOptions = {},
176
177
  useNativeMeta = false
177
178
  } = {}) => {
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
179
  const placeholder = await metaTyping(sock, jid, {
184
180
  description, steps, estimatedMs: thinkingMs, placeholderText, useNativeMeta
185
181
  });
@@ -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/lib/index.d.ts CHANGED
@@ -266,8 +266,14 @@ export interface WASocket {
266
266
  sendBotDiagnostics(jid: string, content?: { text?: string; botBackend?: number; toolsUsed?: string[]; isThinking?: boolean; botJid?: string }, options?: Record<string, unknown>): Promise<unknown>;
267
267
  /** Send a rich response with experimental bot command metadata. */
268
268
  sendBotCommand(jid: string, content?: { text?: string; commandName?: string; commandDescription?: string; commandPrompt?: string; botJid?: string }, options?: Record<string, unknown>): Promise<unknown>;
269
+ /** Send an agentic execution plan, advertising AGENTIC_PLANNING and QUERY_PLAN. */
270
+ sendBotPlanning(jid: string, content?: { text?: string; steps?: Array<string | { title?: string; name?: string; body?: string }>; queryPlan?: boolean; botJid?: string }, options?: Record<string, unknown>): Promise<unknown>;
269
271
  /** Send a rich response with experimental resolved tool-call metadata. */
270
272
  sendBotToolResult(jid: string, content?: { text?: string; toolCallId?: string; resolutionData?: unknown; resolutionDataSerialized?: string; botJid?: string }, options?: Record<string, unknown>): Promise<unknown>;
273
+ /** Resolve a WhatsApp Channel invite code or invite URL to channel metadata. */
274
+ newsletterGetInviteInfo(inviteCodeOrUrl: string): Promise<Record<string, unknown> | null>;
275
+ /** React to a Channel post; pass an empty string, null, or undefined to remove the reaction. */
276
+ newsletterReactMessage(jid: string, serverId: string | number, reaction?: string | null): Promise<void>;
271
277
  /** Send Markdown text containing blockquotes in a forwarded GenAI rich response. */
272
278
  sendMarkdownQuote(jid: string, content?: { text?: string; copyText?: string; copyLabel?: string; alignment?: 'END' | 'START' | 'CENTER' }, options?: Record<string, unknown>): Promise<unknown>;
273
279
  /** Send Markdown blockquotes followed by a GenAI COPY_TO_CLIPBOARD action. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "plogme",
3
- "version": "1.0.6",
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.",
3
+ "version": "2.0.1",
4
+ "description": "Production-ready Baileys fork ⚉ with AI groups, Meta AI prompting, safe compositing fallbacks, rich responses, interactive messages, albums, newsletters, and communities — without antiban wrappers.",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
7
7
  "scripts": {