natureco-cli 2.8.0 → 2.8.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "2.8.0",
3
+ "version": "2.8.1",
4
4
  "description": "NatureCo AI Bot Terminal Interface",
5
5
  "main": "bin/natureco.js",
6
6
  "bin": {
@@ -211,7 +211,7 @@ body::before{
211
211
  <div class="header-bot-name" id="header-bot-name">Nature Bot</div>
212
212
  <div class="header-bot-model" id="header-bot-model">NatureCo</div>
213
213
  </div>
214
- <div class="version-badge" id="version-badge">v2.8.0</div>
214
+ <div class="version-badge" id="version-badge">v2.8.1</div>
215
215
  </div>
216
216
  <div class="messages" id="messages"></div>
217
217
  <div class="input-area">
@@ -341,7 +341,7 @@ function dashboard(action) {
341
341
  apiKey: cfg.apiKey,
342
342
  defaultBot: cfg.defaultBot,
343
343
  defaultBotId: cfg.defaultBotId,
344
- version: 'v2.8.0',
344
+ version: 'v2.8.1',
345
345
  bots: cfg.bots || [],
346
346
  telegramToken: cfg.telegramToken || null,
347
347
  whatsappConnected: cfg.whatsappConnected || false,
@@ -128,7 +128,7 @@ async function startGateway() {
128
128
 
129
129
  async function runGatewayWorker() {
130
130
  // This runs in the background
131
- log('gateway', 'Starting NatureCo Gateway v2.8.0...', 'green');
131
+ log('gateway', 'Starting NatureCo Gateway v2.8.1...', 'green');
132
132
 
133
133
  // Load config
134
134
  const { getConfig } = require('../utils/config');
@@ -139,6 +139,10 @@ async function runGatewayWorker() {
139
139
  process.exit(1);
140
140
  }
141
141
 
142
+ // Store provider instances globally for HTTP endpoint
143
+ global.whatsappSock = null;
144
+ global.telegramBot = null;
145
+
142
146
  // Start WhatsApp if configured
143
147
  if (config.whatsappConnected && config.whatsappBotId) {
144
148
  const sessionDir = path.join(os.homedir(), '.natureco', 'whatsapp-sessions', config.whatsappBotId);
@@ -162,6 +166,9 @@ async function runGatewayWorker() {
162
166
  log('telegram', 'not configured, skipping', 'gray');
163
167
  }
164
168
 
169
+ // Start HTTP server for message sending
170
+ startHttpServer();
171
+
165
172
  // Health check every 60 seconds
166
173
  setInterval(() => {
167
174
  log('gateway', 'health check: OK', 'gray');
@@ -236,6 +243,9 @@ async function startWhatsAppProvider(sessionDir, config) {
236
243
  log('whatsapp', `Connected successfully`, 'green');
237
244
  log('whatsapp', `Listening for inbound messages.`, 'cyan');
238
245
  log('whatsapp', `Phone: +${phone}`, 'gray');
246
+
247
+ // Store socket globally for HTTP endpoint
248
+ global.whatsappSock = sock;
239
249
  }
240
250
  });
241
251
 
@@ -446,11 +456,111 @@ async function startTelegramProvider(config) {
446
456
  log('telegram', `Polling error: ${error.message}`, 'red');
447
457
  });
448
458
 
459
+ // Store bot globally for HTTP endpoint
460
+ global.telegramBot = bot;
461
+
449
462
  } catch (err) {
450
463
  log('telegram', `Failed to start: ${err.message}`, 'red');
451
464
  }
452
465
  }
453
466
 
467
+ function startHttpServer() {
468
+ const http = require('http');
469
+
470
+ const server = http.createServer(async (req, res) => {
471
+ // CORS headers
472
+ res.setHeader('Access-Control-Allow-Origin', '*');
473
+ res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
474
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
475
+
476
+ if (req.method === 'OPTIONS') {
477
+ res.writeHead(200);
478
+ res.end();
479
+ return;
480
+ }
481
+
482
+ if (req.method === 'POST' && req.url === '/send') {
483
+ let body = '';
484
+
485
+ req.on('data', chunk => {
486
+ body += chunk.toString();
487
+ });
488
+
489
+ req.on('end', async () => {
490
+ try {
491
+ const { channel, target, message } = JSON.parse(body);
492
+
493
+ if (!channel || !target || !message) {
494
+ res.writeHead(400, { 'Content-Type': 'application/json' });
495
+ res.end(JSON.stringify({ error: 'Missing required fields: channel, target, message' }));
496
+ return;
497
+ }
498
+
499
+ if (channel === 'whatsapp') {
500
+ if (!global.whatsappSock) {
501
+ res.writeHead(503, { 'Content-Type': 'application/json' });
502
+ res.end(JSON.stringify({ error: 'WhatsApp not connected' }));
503
+ return;
504
+ }
505
+
506
+ const normalizedTarget = target.replace(/[^\d]/g, '');
507
+ const jid = `${normalizedTarget}@s.whatsapp.net`;
508
+
509
+ await global.whatsappSock.sendMessage(jid, { text: message });
510
+
511
+ log('http', `WhatsApp message sent to ${target}`, 'green');
512
+
513
+ res.writeHead(200, { 'Content-Type': 'application/json' });
514
+ res.end(JSON.stringify({ success: true, channel: 'whatsapp', target }));
515
+
516
+ } else if (channel === 'telegram') {
517
+ if (!global.telegramBot) {
518
+ res.writeHead(503, { 'Content-Type': 'application/json' });
519
+ res.end(JSON.stringify({ error: 'Telegram not connected' }));
520
+ return;
521
+ }
522
+
523
+ const chatId = target.trim();
524
+ if (!/^-?\d+$/.test(chatId)) {
525
+ res.writeHead(400, { 'Content-Type': 'application/json' });
526
+ res.end(JSON.stringify({ error: 'Invalid Telegram chat ID' }));
527
+ return;
528
+ }
529
+
530
+ await global.telegramBot.sendMessage(chatId, message);
531
+
532
+ log('http', `Telegram message sent to ${target}`, 'green');
533
+
534
+ res.writeHead(200, { 'Content-Type': 'application/json' });
535
+ res.end(JSON.stringify({ success: true, channel: 'telegram', target }));
536
+
537
+ } else {
538
+ res.writeHead(400, { 'Content-Type': 'application/json' });
539
+ res.end(JSON.stringify({ error: 'Invalid channel. Use "whatsapp" or "telegram"' }));
540
+ }
541
+
542
+ } catch (err) {
543
+ log('http', `Error: ${err.message}`, 'red');
544
+ res.writeHead(500, { 'Content-Type': 'application/json' });
545
+ res.end(JSON.stringify({ error: err.message }));
546
+ }
547
+ });
548
+
549
+ } else {
550
+ res.writeHead(404, { 'Content-Type': 'application/json' });
551
+ res.end(JSON.stringify({ error: 'Not found' }));
552
+ }
553
+ });
554
+
555
+ server.listen(3847, '127.0.0.1', () => {
556
+ log('http', 'HTTP server listening on http://127.0.0.1:3847', 'green');
557
+ });
558
+
559
+ server.on('error', (err) => {
560
+ log('http', `Server error: ${err.message}`, 'red');
561
+ });
562
+ }
563
+
454
564
  function stopGateway() {
455
565
  if (!fs.existsSync(PID_FILE)) {
456
566
  console.log(chalk.gray('\n⚠️ Gateway not running\n'));
@@ -5,6 +5,7 @@ const os = require('os');
5
5
  const { getConfig } = require('../utils/config');
6
6
 
7
7
  const PID_FILE = path.join(os.homedir(), '.natureco', 'gateway.pid');
8
+ const GATEWAY_HTTP_URL = 'http://127.0.0.1:3847/send';
8
9
 
9
10
  async function message(args) {
10
11
  // Parse arguments
@@ -54,128 +55,42 @@ async function message(args) {
54
55
 
55
56
  const config = getConfig();
56
57
 
57
- if (channel === 'whatsapp') {
58
- await sendWhatsAppMessage(target, messageText, config);
59
- } else if (channel === 'telegram') {
60
- await sendTelegramMessage(target, messageText, config);
61
- }
62
- }
63
-
64
- async function sendWhatsAppMessage(target, messageText, config) {
65
- if (!config.whatsappConnected || !config.whatsappBotId) {
58
+ // Validate channel configuration
59
+ if (channel === 'whatsapp' && (!config.whatsappConnected || !config.whatsappBotId)) {
66
60
  console.log(chalk.red('\n❌ WhatsApp bağlı değil\n'));
67
61
  console.log(chalk.yellow('Önce WhatsApp\'ı bağlayın:'), chalk.cyan('natureco whatsapp connect\n'));
68
62
  process.exit(1);
69
63
  }
70
64
 
71
- console.log(chalk.yellow('\n⏳ WhatsApp mesajı gönderiliyor...\n'));
72
-
73
- try {
74
- // Lazy load Baileys
75
- const baileys = require('@whiskeysockets/baileys');
76
- const makeWASocket = baileys.default;
77
- const useMultiFileAuthState = baileys.useMultiFileAuthState;
78
- const fetchLatestBaileysVersion = baileys.fetchLatestBaileysVersion;
79
- const Browsers = baileys.Browsers;
80
- const pino = require('pino');
81
- const logger = pino({ level: 'silent' });
82
-
83
- const sessionDir = path.join(os.homedir(), '.natureco', 'whatsapp-sessions', config.whatsappBotId);
84
-
85
- if (!fs.existsSync(sessionDir)) {
86
- console.log(chalk.red('❌ WhatsApp session bulunamadı\n'));
87
- console.log(chalk.yellow('Önce WhatsApp\'ı bağlayın:'), chalk.cyan('natureco whatsapp connect\n'));
88
- process.exit(1);
89
- }
90
-
91
- const { state } = await useMultiFileAuthState(sessionDir);
92
- const { version } = await fetchLatestBaileysVersion();
93
-
94
- const sock = makeWASocket({
95
- version,
96
- auth: state,
97
- printQRInTerminal: false,
98
- logger: logger,
99
- browser: Browsers.ubuntu('Chrome'),
100
- connectTimeoutMs: 30000,
101
- });
102
-
103
- // Wait for connection
104
- await new Promise((resolve, reject) => {
105
- const timeout = setTimeout(() => {
106
- reject(new Error('Connection timeout'));
107
- }, 30000);
108
-
109
- sock.ev.on('connection.update', (update) => {
110
- if (update.connection === 'open') {
111
- clearTimeout(timeout);
112
- resolve();
113
- } else if (update.connection === 'close') {
114
- clearTimeout(timeout);
115
- reject(new Error('Connection failed'));
116
- }
117
- });
118
- });
119
-
120
- // Normalize phone number
121
- const normalizedTarget = target.replace(/[^\d]/g, '');
122
- const jid = `${normalizedTarget}@s.whatsapp.net`;
123
-
124
- // Send message
125
- await sock.sendMessage(jid, { text: messageText });
126
-
127
- console.log(chalk.green('✅ Mesaj gönderildi!\n'));
128
- console.log(chalk.cyan('Hedef:'), chalk.white(target));
129
- console.log(chalk.cyan('Mesaj:'), chalk.white(messageText));
130
- console.log('');
131
-
132
- // Close connection
133
- setTimeout(() => {
134
- sock.end();
135
- process.exit(0);
136
- }, 2000);
137
-
138
- } catch (err) {
139
- console.log(chalk.red(`\n❌ Hata: ${err.message}\n`));
140
- process.exit(1);
141
- }
142
- }
143
-
144
- async function sendTelegramMessage(target, messageText, config) {
145
- if (!config.telegramToken || !config.telegramBotId) {
65
+ if (channel === 'telegram' && (!config.telegramToken || !config.telegramBotId)) {
146
66
  console.log(chalk.red('\n❌ Telegram bağlı değil\n'));
147
67
  console.log(chalk.yellow('Önce Telegram\'ı bağlayın:'), chalk.cyan('natureco telegram connect\n'));
148
68
  process.exit(1);
149
69
  }
150
70
 
151
- console.log(chalk.yellow('\n⏳ Telegram mesajı gönderiliyor...\n'));
71
+ // Send message via HTTP endpoint
72
+ await sendMessageViaHttp(channel, target, messageText);
73
+ }
74
+
75
+ async function sendMessageViaHttp(channel, target, messageText) {
76
+ console.log(chalk.yellow(`\n⏳ ${channel === 'whatsapp' ? 'WhatsApp' : 'Telegram'} mesajı gönderiliyor...\n`));
152
77
 
153
78
  try {
154
- // Lazy load node-telegram-bot-api
155
- let TelegramBot;
156
- try {
157
- TelegramBot = require('node-telegram-bot-api');
158
- } catch (err) {
159
- console.log(chalk.red('❌ node-telegram-bot-api yüklü değil\n'));
160
- console.log(chalk.yellow('Yüklemek için:'), chalk.cyan('npm install -g node-telegram-bot-api\n'));
161
- process.exit(1);
162
- }
79
+ const response = await fetch(GATEWAY_HTTP_URL, {
80
+ method: 'POST',
81
+ headers: { 'Content-Type': 'application/json' },
82
+ body: JSON.stringify({ channel, target, message: messageText })
83
+ });
163
84
 
164
- const bot = new TelegramBot(config.telegramToken, { polling: false });
85
+ const data = await response.json();
165
86
 
166
- // Validate chat ID (should be numeric)
167
- const chatId = target.trim();
168
- if (!/^-?\d+$/.test(chatId)) {
169
- console.log(chalk.red('❌ Geçersiz Telegram Chat ID\n'));
170
- console.log(chalk.gray('Chat ID sadece rakamlardan oluşmalı (örnek: 123456789)\n'));
171
- process.exit(1);
87
+ if (!response.ok) {
88
+ throw new Error(data.error || `HTTP ${response.status}`);
172
89
  }
173
90
 
174
- // Send message
175
- await bot.sendMessage(chatId, messageText);
176
-
177
91
  console.log(chalk.green('✅ Mesaj gönderildi!\n'));
178
- console.log(chalk.cyan('Chat ID:'), chalk.white(chatId));
92
+ console.log(chalk.cyan('Kanal:'), chalk.white(channel));
93
+ console.log(chalk.cyan('Hedef:'), chalk.white(target));
179
94
  console.log(chalk.cyan('Mesaj:'), chalk.white(messageText));
180
95
  console.log('');
181
96
 
@@ -184,8 +99,12 @@ async function sendTelegramMessage(target, messageText, config) {
184
99
  } catch (err) {
185
100
  console.log(chalk.red(`\n❌ Hata: ${err.message}\n`));
186
101
 
187
- if (err.message.includes('chat not found')) {
188
- console.log(chalk.yellow('⚠️ Chat ID bulunamadı. Önce bot\'a mesaj gönderin.\n'));
102
+ if (err.message.includes('ECONNREFUSED')) {
103
+ console.log(chalk.yellow('⚠️ Gateway HTTP sunucusuna bağlanılamadı'));
104
+ console.log(chalk.gray('Gateway\'i yeniden başlatın: natureco gateway stop && natureco gateway start\n'));
105
+ } else if (err.message.includes('not connected')) {
106
+ console.log(chalk.yellow(`⚠️ ${channel === 'whatsapp' ? 'WhatsApp' : 'Telegram'} bağlı değil`));
107
+ console.log(chalk.gray(`Bağlantıyı kontrol edin: natureco ${channel} status\n`));
189
108
  }
190
109
 
191
110
  process.exit(1);