natureco-cli 2.8.0 → 2.8.2
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 +1 -1
- package/src/commands/dashboard.js +2 -2
- package/src/commands/gateway-server.js +112 -3
- package/src/commands/message.js +26 -107
package/package.json
CHANGED
|
@@ -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.
|
|
214
|
+
<div class="version-badge" id="version-badge">v2.8.2</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.
|
|
344
|
+
version: 'v2.8.2',
|
|
345
345
|
bots: cfg.bots || [],
|
|
346
346
|
telegramToken: cfg.telegramToken || null,
|
|
347
347
|
whatsappConnected: cfg.whatsappConnected || false,
|
|
@@ -10,7 +10,6 @@ const LOG_FILE = path.join(os.homedir(), '.natureco', 'gateway.log');
|
|
|
10
10
|
// WhatsApp imports
|
|
11
11
|
let makeWASocket, useMultiFileAuthState, DisconnectReason, fetchLatestBaileysVersion, Browsers;
|
|
12
12
|
const pino = require('pino');
|
|
13
|
-
const logger = pino({ level: 'silent' });
|
|
14
13
|
|
|
15
14
|
// Lazy load Baileys
|
|
16
15
|
function loadBaileys() {
|
|
@@ -128,7 +127,7 @@ async function startGateway() {
|
|
|
128
127
|
|
|
129
128
|
async function runGatewayWorker() {
|
|
130
129
|
// This runs in the background
|
|
131
|
-
log('gateway', 'Starting NatureCo Gateway v2.8.
|
|
130
|
+
log('gateway', 'Starting NatureCo Gateway v2.8.2...', 'green');
|
|
132
131
|
|
|
133
132
|
// Load config
|
|
134
133
|
const { getConfig } = require('../utils/config');
|
|
@@ -139,6 +138,10 @@ async function runGatewayWorker() {
|
|
|
139
138
|
process.exit(1);
|
|
140
139
|
}
|
|
141
140
|
|
|
141
|
+
// Store provider instances globally for HTTP endpoint
|
|
142
|
+
global.whatsappSock = null;
|
|
143
|
+
global.telegramBot = null;
|
|
144
|
+
|
|
142
145
|
// Start WhatsApp if configured
|
|
143
146
|
if (config.whatsappConnected && config.whatsappBotId) {
|
|
144
147
|
const sessionDir = path.join(os.homedir(), '.natureco', 'whatsapp-sessions', config.whatsappBotId);
|
|
@@ -162,6 +165,9 @@ async function runGatewayWorker() {
|
|
|
162
165
|
log('telegram', 'not configured, skipping', 'gray');
|
|
163
166
|
}
|
|
164
167
|
|
|
168
|
+
// Start HTTP server for message sending
|
|
169
|
+
startHttpServer();
|
|
170
|
+
|
|
165
171
|
// Health check every 60 seconds
|
|
166
172
|
setInterval(() => {
|
|
167
173
|
log('gateway', 'health check: OK', 'gray');
|
|
@@ -201,7 +207,7 @@ async function startWhatsAppProvider(sessionDir, config) {
|
|
|
201
207
|
version,
|
|
202
208
|
auth: state,
|
|
203
209
|
printQRInTerminal: false,
|
|
204
|
-
logger:
|
|
210
|
+
logger: pino({ level: 'silent' }),
|
|
205
211
|
browser: Browsers.ubuntu('Chrome'),
|
|
206
212
|
connectTimeoutMs: 60000,
|
|
207
213
|
defaultQueryTimeoutMs: 60000,
|
|
@@ -236,6 +242,9 @@ async function startWhatsAppProvider(sessionDir, config) {
|
|
|
236
242
|
log('whatsapp', `Connected successfully`, 'green');
|
|
237
243
|
log('whatsapp', `Listening for inbound messages.`, 'cyan');
|
|
238
244
|
log('whatsapp', `Phone: +${phone}`, 'gray');
|
|
245
|
+
|
|
246
|
+
// Store socket globally for HTTP endpoint
|
|
247
|
+
global.whatsappSock = sock;
|
|
239
248
|
}
|
|
240
249
|
});
|
|
241
250
|
|
|
@@ -446,11 +455,111 @@ async function startTelegramProvider(config) {
|
|
|
446
455
|
log('telegram', `Polling error: ${error.message}`, 'red');
|
|
447
456
|
});
|
|
448
457
|
|
|
458
|
+
// Store bot globally for HTTP endpoint
|
|
459
|
+
global.telegramBot = bot;
|
|
460
|
+
|
|
449
461
|
} catch (err) {
|
|
450
462
|
log('telegram', `Failed to start: ${err.message}`, 'red');
|
|
451
463
|
}
|
|
452
464
|
}
|
|
453
465
|
|
|
466
|
+
function startHttpServer() {
|
|
467
|
+
const http = require('http');
|
|
468
|
+
|
|
469
|
+
const server = http.createServer(async (req, res) => {
|
|
470
|
+
// CORS headers
|
|
471
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
472
|
+
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
|
|
473
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
474
|
+
|
|
475
|
+
if (req.method === 'OPTIONS') {
|
|
476
|
+
res.writeHead(200);
|
|
477
|
+
res.end();
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (req.method === 'POST' && req.url === '/send') {
|
|
482
|
+
let body = '';
|
|
483
|
+
|
|
484
|
+
req.on('data', chunk => {
|
|
485
|
+
body += chunk.toString();
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
req.on('end', async () => {
|
|
489
|
+
try {
|
|
490
|
+
const { channel, target, message } = JSON.parse(body);
|
|
491
|
+
|
|
492
|
+
if (!channel || !target || !message) {
|
|
493
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
494
|
+
res.end(JSON.stringify({ error: 'Missing required fields: channel, target, message' }));
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if (channel === 'whatsapp') {
|
|
499
|
+
if (!global.whatsappSock) {
|
|
500
|
+
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
501
|
+
res.end(JSON.stringify({ error: 'WhatsApp not connected' }));
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
const normalizedTarget = target.replace(/[^\d]/g, '');
|
|
506
|
+
const jid = `${normalizedTarget}@s.whatsapp.net`;
|
|
507
|
+
|
|
508
|
+
await global.whatsappSock.sendMessage(jid, { text: message });
|
|
509
|
+
|
|
510
|
+
log('http', `WhatsApp message sent to ${target}`, 'green');
|
|
511
|
+
|
|
512
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
513
|
+
res.end(JSON.stringify({ success: true, channel: 'whatsapp', target }));
|
|
514
|
+
|
|
515
|
+
} else if (channel === 'telegram') {
|
|
516
|
+
if (!global.telegramBot) {
|
|
517
|
+
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
518
|
+
res.end(JSON.stringify({ error: 'Telegram not connected' }));
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
const chatId = target.trim();
|
|
523
|
+
if (!/^-?\d+$/.test(chatId)) {
|
|
524
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
525
|
+
res.end(JSON.stringify({ error: 'Invalid Telegram chat ID' }));
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
await global.telegramBot.sendMessage(chatId, message);
|
|
530
|
+
|
|
531
|
+
log('http', `Telegram message sent to ${target}`, 'green');
|
|
532
|
+
|
|
533
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
534
|
+
res.end(JSON.stringify({ success: true, channel: 'telegram', target }));
|
|
535
|
+
|
|
536
|
+
} else {
|
|
537
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
538
|
+
res.end(JSON.stringify({ error: 'Invalid channel. Use "whatsapp" or "telegram"' }));
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
} catch (err) {
|
|
542
|
+
log('http', `Error: ${err.message}`, 'red');
|
|
543
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
544
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
} else {
|
|
549
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
550
|
+
res.end(JSON.stringify({ error: 'Not found' }));
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
server.listen(3847, '127.0.0.1', () => {
|
|
555
|
+
log('http', 'HTTP server listening on http://127.0.0.1:3847', 'green');
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
server.on('error', (err) => {
|
|
559
|
+
log('http', `Server error: ${err.message}`, 'red');
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
|
|
454
563
|
function stopGateway() {
|
|
455
564
|
if (!fs.existsSync(PID_FILE)) {
|
|
456
565
|
console.log(chalk.gray('\n⚠️ Gateway not running\n'));
|
package/src/commands/message.js
CHANGED
|
@@ -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
|
-
|
|
58
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
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
|
|
85
|
+
const data = await response.json();
|
|
165
86
|
|
|
166
|
-
|
|
167
|
-
|
|
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('
|
|
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('
|
|
188
|
-
console.log(chalk.yellow('⚠️
|
|
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);
|