natureco-cli 1.0.43 → 1.0.45

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "1.0.43",
3
+ "version": "1.0.45",
4
4
  "description": "NatureCo AI Bot Terminal Interface",
5
5
  "main": "bin/natureco.js",
6
6
  "bin": {
@@ -194,6 +194,9 @@ async function startWhatsAppProvider(sessionDir, config) {
194
194
  const { state, saveCreds } = await useMultiFileAuthState(sessionDir);
195
195
  const { version } = await fetchLatestBaileysVersion();
196
196
 
197
+ // Track last bot reply to prevent infinite loop
198
+ let lastBotReply = '';
199
+
197
200
  const sock = makeWASocket({
198
201
  version,
199
202
  auth: state,
@@ -237,18 +240,10 @@ async function startWhatsAppProvider(sessionDir, config) {
237
240
  // Log raw message info
238
241
  log('whatsapp', `Raw message - fromMe: ${msg.key.fromMe}, remoteJid: ${msg.key.remoteJid}`, 'gray');
239
242
 
240
- const sender = msg.key.remoteJid?.split('@')[0].split(':')[0];
241
- const allowedNumbers = config.whatsappAllowedNumbers || [];
242
-
243
- // Log incoming number before access control
244
- log('whatsapp', `Incoming from: +${sender}, allowed: ${JSON.stringify(allowedNumbers)}`, 'gray');
245
-
246
- // Access control - compare last 10 digits
247
- if (allowedNumbers.length > 0 && !allowedNumbers.some(n => numberMatches(n, sender))) {
248
- log('whatsapp', `blocked message from +${sender} (not in allowed list)`, 'yellow');
249
- continue;
250
- }
243
+ const remoteJid = msg.key.remoteJid || '';
244
+ const isLID = remoteJid.includes('@lid');
251
245
 
246
+ // Skip bot's own replies (fromMe=true and not LID, or matches last bot reply)
252
247
  const messageText = msg.message?.conversation ||
253
248
  msg.message?.extendedTextMessage?.text ||
254
249
  msg.message?.imageMessage?.caption ||
@@ -259,6 +254,36 @@ async function startWhatsAppProvider(sessionDir, config) {
259
254
  msg.message?.viewOnceMessage?.message?.conversation ||
260
255
  '';
261
256
 
257
+ // Skip if this is the bot's own reply
258
+ if (msg.key.fromMe && !isLID) {
259
+ log('whatsapp', 'Skipping bot own reply (fromMe=true, not LID)', 'gray');
260
+ continue;
261
+ }
262
+
263
+ // Skip if message matches last bot reply (prevent loop)
264
+ if (messageText === lastBotReply && lastBotReply !== '') {
265
+ log('whatsapp', 'Skipping duplicate bot reply (matches last sent)', 'gray');
266
+ continue;
267
+ }
268
+
269
+ // Handle LID format (new WhatsApp format)
270
+ if (isLID && !msg.key.fromMe) {
271
+ log('whatsapp', 'LID format detected, fromMe=false, blocked', 'yellow');
272
+ continue;
273
+ }
274
+
275
+ const sender = remoteJid.split('@')[0].split(':')[0];
276
+ const allowedNumbers = config.whatsappAllowedNumbers || [];
277
+
278
+ // Log incoming number
279
+ log('whatsapp', `Incoming from: +${sender}, allowed: ${JSON.stringify(allowedNumbers)}`, 'gray');
280
+
281
+ // Access control - skip if fromMe + LID (own conversation)
282
+ if (!(msg.key.fromMe && isLID) && allowedNumbers.length > 0 && !allowedNumbers.some(n => numberMatches(n, sender))) {
283
+ log('whatsapp', `blocked message from +${sender} (not in allowed list)`, 'yellow');
284
+ continue;
285
+ }
286
+
262
287
  if (!messageText) {
263
288
  log('whatsapp', `Message without text content. Keys: ${Object.keys(msg.message || {}).join(', ')}`, 'gray');
264
289
  continue;
@@ -266,7 +291,6 @@ async function startWhatsAppProvider(sessionDir, config) {
266
291
 
267
292
  const ownNumber = sock.user?.id?.split(':')[0].replace('@s.whatsapp.net', '') || 'unknown';
268
293
  log('whatsapp', `Inbound message +${sender} -> +${ownNumber} (${messageText.length} chars)`, 'cyan');
269
- log('whatsapp', `Message: "${messageText.substring(0, 100)}${messageText.length > 100 ? '...' : ''}"`, 'gray');
270
294
 
271
295
  try {
272
296
  const { sendMessage } = require('../utils/api');
@@ -276,10 +300,13 @@ async function startWhatsAppProvider(sessionDir, config) {
276
300
  const reply = response?.reply || response?.message || '';
277
301
 
278
302
  if (reply) {
279
- log('whatsapp', `API response: "${reply.substring(0, 100)}${reply.length > 100 ? '...' : ''}"`, 'gray');
280
303
  log('whatsapp', 'Sending reply...', 'cyan');
281
304
 
282
305
  await sock.sendMessage(msg.key.remoteJid, { text: reply });
306
+
307
+ // Store last bot reply to prevent loop
308
+ lastBotReply = reply;
309
+
283
310
  log('whatsapp', `Reply sent (${reply.length} chars)`, 'green');
284
311
  } else {
285
312
  log('whatsapp', 'No reply from API', 'yellow');