noho_bot 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.
package/noho_bot.js. ADDED
@@ -0,0 +1,549 @@
1
+ // noho_bot.js
2
+ // NOHO Bot Library - Build bots for any platform
3
+ // Created by: nohojs (Omar)
4
+
5
+ const { default: makeWASocket, DisconnectReason, useMultiFileAuthState } = require('@whiskeysockets/baileys');
6
+ const qrcode = require('qrcode-terminal');
7
+ const pino = require('pino');
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const crypto = require('crypto');
11
+
12
+ // ==========================================
13
+ // UTILS
14
+ // ==========================================
15
+ const colors = {
16
+ reset: '\x1b[0m',
17
+ bright: '\x1b[1m',
18
+ green: '\x1b[32m',
19
+ yellow: '\x1b[33m',
20
+ red: '\x1b[31m',
21
+ cyan: '\x1b[36m',
22
+ magenta: '\x1b[35m'
23
+ };
24
+
25
+ function log(type, msg) {
26
+ const icons = {
27
+ info: 'ℹ️',
28
+ success: '✅',
29
+ error: '❌',
30
+ warning: '⚠️',
31
+ bot: '🤖',
32
+ lock: '🔒'
33
+ };
34
+ console.log(`${icons[type] || '•'} ${msg}`);
35
+ }
36
+
37
+ // ==========================================
38
+ // NOHO USER SYSTEM (للمستخدمين)
39
+ // ==========================================
40
+ class NohoUser {
41
+ constructor() {
42
+ this.dataPath = path.join(process.cwd(), '.noho');
43
+ this.userFile = path.join(this.dataPath, 'user.json');
44
+ this.projectsFile = path.join(this.dataPath, 'projects.json');
45
+ this.apiFile = path.join(this.dataPath, 'api.key');
46
+ this.ensureDataDir();
47
+ }
48
+
49
+ ensureDataDir() {
50
+ if (!fs.existsSync(this.dataPath)) {
51
+ fs.mkdirSync(this.dataPath, { recursive: true });
52
+ }
53
+ }
54
+
55
+ // تسجيل مستخدم جديد
56
+ register(username, password) {
57
+ if (this.exists()) {
58
+ log('error', 'أنت مسجل بالفعل! استخدم .d.noho لعرض بياناتك');
59
+ return false;
60
+ }
61
+
62
+ const apiKey = this.generateAPI();
63
+ const userData = {
64
+ username,
65
+ password: this.hash(password),
66
+ apiKey,
67
+ createdAt: new Date().toISOString(),
68
+ projects: []
69
+ };
70
+
71
+ fs.writeFileSync(this.userFile, JSON.stringify(userData, null, 2));
72
+ fs.writeFileSync(this.apiFile, apiKey);
73
+
74
+ log('success', `تم التسجيل بنجاح! مرحباً ${username}`);
75
+ log('bot', `API Key الخاص بك: ${apiKey.slice(0, 20)}...`);
76
+ return true;
77
+ }
78
+
79
+ // تسجيل الدخول
80
+ login(username, password) {
81
+ if (!this.exists()) {
82
+ log('error', 'ليس لديك حساب! استخدم: .longin <username> <password>');
83
+ return false;
84
+ }
85
+
86
+ const user = this.getUser();
87
+ if (user.username !== username || user.password !== this.hash(password)) {
88
+ log('error', 'اسم المستخدم أو كلمة المرور غير صحيحة');
89
+ return false;
90
+ }
91
+
92
+ log('success', `مرحباً بعودتك ${username}!`);
93
+ return true;
94
+ }
95
+
96
+ // عرض البيانات
97
+ getInfo() {
98
+ if (!this.exists()) {
99
+ log('error', 'ليس لديك حساب في noho!');
100
+ return null;
101
+ }
102
+
103
+ const user = this.getUser();
104
+ const projects = this.getProjects();
105
+
106
+ return {
107
+ username: user.username,
108
+ apiKey: user.apiKey.slice(0, 20) + '...',
109
+ projectsCount: projects.length,
110
+ createdAt: user.createdAt
111
+ };
112
+ }
113
+
114
+ // توليد API مميز
115
+ generateAPI() {
116
+ return 'NPI-' + crypto.randomBytes(32).toString('hex').toUpperCase();
117
+ }
118
+
119
+ // تجديد API
120
+ renewAPI() {
121
+ if (!this.exists()) {
122
+ log('error', 'ليس لديك حساب!');
123
+ return null;
124
+ }
125
+
126
+ const newApi = this.generateAPI();
127
+ const user = this.getUser();
128
+ user.apiKey = newApi;
129
+ user.updatedAt = new Date().toISOString();
130
+
131
+ fs.writeFileSync(this.userFile, JSON.stringify(user, null, 2));
132
+ fs.writeFileSync(this.apiFile, newApi);
133
+
134
+ log('success', 'تم تجديد API Key بنجاح!');
135
+ return newApi;
136
+ }
137
+
138
+ // حفظ مشروع
139
+ saveProject(name, platform, config) {
140
+ const projects = this.getProjects();
141
+ projects.push({
142
+ name,
143
+ platform,
144
+ config,
145
+ createdAt: new Date().toISOString()
146
+ });
147
+ fs.writeFileSync(this.projectsFile, JSON.stringify(projects, null, 2));
148
+ log('success', `تم حفظ المشروع: ${name}`);
149
+ }
150
+
151
+ getProjects() {
152
+ if (!fs.existsSync(this.projectsFile)) return [];
153
+ return JSON.parse(fs.readFileSync(this.projectsFile, 'utf8'));
154
+ }
155
+
156
+ getUser() {
157
+ return JSON.parse(fs.readFileSync(this.userFile, 'utf8'));
158
+ }
159
+
160
+ exists() {
161
+ return fs.existsSync(this.userFile);
162
+ }
163
+
164
+ hash(str) {
165
+ return crypto.createHash('sha256').update(str).digest('hex');
166
+ }
167
+ }
168
+
169
+ // ==========================================
170
+ // CODE CHECKER (.m)
171
+ // ==========================================
172
+ class CodeChecker {
173
+ check(filePath) {
174
+ if (!fs.existsSync(filePath)) {
175
+ log('error', `الملف غير موجود: ${filePath}`);
176
+ return false;
177
+ }
178
+
179
+ const code = fs.readFileSync(filePath, 'utf8');
180
+ const issues = [];
181
+ const warnings = [];
182
+
183
+ // فحص الأخطاء الشائعة
184
+ if (code.includes('console.log') && !code.includes('// debug')) {
185
+ warnings.push('يوجد console.log - احذفها قبل النشر');
186
+ }
187
+
188
+ if (!code.includes('try') && code.includes('await')) {
189
+ warnings.push('يفضل استخدام try-catch مع async/await');
190
+ }
191
+
192
+ if (code.includes('eval(')) {
193
+ issues.push('⚠️ خطير: استخدام eval() غير آمن!');
194
+ }
195
+
196
+ if (code.includes('password') && !code.includes('hash')) {
197
+ warnings.push('تأكد من تشفير كلمات المرور');
198
+ }
199
+
200
+ // فحص بناء الملفات
201
+ const lines = code.split('\n');
202
+ if (lines.length > 500) {
203
+ warnings.push('الملف كبير (>500 سطر) - فكر في تقسيمه');
204
+ }
205
+
206
+ // النتيجة
207
+ console.log(`\n${colors.cyan}═══ فحص الكود ═══${colors.reset}`);
208
+ console.log(`الملف: ${filePath}`);
209
+ console.log(`الأسطر: ${lines.length}`);
210
+ console.log(`الأحرف: ${code.length}`);
211
+
212
+ if (issues.length === 0 && warnings.length === 0) {
213
+ log('success', 'الكود نظيف! لا يوجد مشاكل ✅');
214
+ return true;
215
+ }
216
+
217
+ if (issues.length > 0) {
218
+ console.log(`\n${colors.red}أخطاء خطيرة:${colors.reset}`);
219
+ issues.forEach(i => console.log(` ❌ ${i}`));
220
+ }
221
+
222
+ if (warnings.length > 0) {
223
+ console.log(`\n${colors.yellow}تحذيرات:${colors.reset}`);
224
+ warnings.forEach(w => console.log(` ⚠️ ${w}`));
225
+ }
226
+
227
+ return issues.length === 0;
228
+ }
229
+ }
230
+
231
+ // ==========================================
232
+ // BOT LINKER (.link)
233
+ // ==========================================
234
+ class BotLinker {
235
+ constructor() {
236
+ this.platforms = {
237
+ whatsapp: { name: 'واتساب', auth: 'qr' },
238
+ telegram: { name: 'تلجرام', auth: 'token' },
239
+ discord: { name: 'ديسكورد', auth: 'token' },
240
+ slack: { name: 'سلاك', auth: 'token' },
241
+ facebook: { name: 'فيسبوك', auth: 'app' }
242
+ };
243
+ }
244
+
245
+ list() {
246
+ console.log(`\n${colors.cyan}═══ المنصات المتاحة ═══${colors.reset}`);
247
+ Object.entries(this.platforms).forEach(([key, val]) => {
248
+ console.log(` ${key === 'whatsapp' ? '1' : key === 'telegram' ? '2' : key === 'discord' ? '3' : key === 'slack' ? '4' : '5'}. ${val.name} (${val.auth})`);
249
+ });
250
+ return this.platforms;
251
+ }
252
+
253
+ select(platform) {
254
+ const p = this.platforms[platform.toLowerCase()];
255
+ if (!p) {
256
+ log('error', `المنصة ${platform} غير موجودة`);
257
+ return null;
258
+ }
259
+ log('success', `تم اختيار: ${p.name}`);
260
+ return p;
261
+ }
262
+ }
263
+
264
+ // ==========================================
265
+ // BASE ADAPTER
266
+ // ==========================================
267
+ class BaseAdapter {
268
+ constructor(name, config = {}) {
269
+ this.name = name;
270
+ this.config = config;
271
+ this.connected = false;
272
+ this.authData = null;
273
+ this.sock = null;
274
+ }
275
+
276
+ getFingerprint() {
277
+ return {
278
+ platform: this.name,
279
+ connected: this.connected,
280
+ authType: this.getAuthType(),
281
+ user: this.authData?.user || null
282
+ };
283
+ }
284
+
285
+ getAuthType() { return 'unknown'; }
286
+ async connect() { throw new Error('Not implemented'); }
287
+ async disconnect() { throw new Error('Not implemented'); }
288
+ async sendMessage(to, text) { throw new Error('Not implemented'); }
289
+ }
290
+
291
+ // ==========================================
292
+ // WHATSAPP ADAPTER
293
+ // ==========================================
294
+ class WhatsAppAdapter extends BaseAdapter {
295
+ constructor(config = {}) {
296
+ super('whatsapp', {
297
+ sessionPath: config.sessionPath || './.noho_sessions/whatsapp',
298
+ printQR: config.printQR !== false,
299
+ ...config
300
+ });
301
+ this.qrCode = null;
302
+ this.pairingCode = null;
303
+ }
304
+
305
+ getAuthType() { return this.qrCode ? 'qr' : this.pairingCode ? 'pairing' : 'none'; }
306
+
307
+ async connect(method = 'qr', phoneNumber = null) {
308
+ if (method === 'pairing' && !phoneNumber) {
309
+ throw new Error('رقم الهاتف مطلوب لطريقة الكود');
310
+ }
311
+
312
+ const { state, saveCreds } = await useMultiFileAuthState(this.config.sessionPath);
313
+
314
+ this.sock = makeWASocket({
315
+ logger: pino({ level: 'silent' }),
316
+ printQRInTerminal: false,
317
+ auth: state,
318
+ browser: ['NOHO Bot', 'Chrome', '1.0']
319
+ });
320
+
321
+ return new Promise((resolve, reject) => {
322
+ const timeout = setTimeout(() => reject(new Error('انتهى الوقت')), 120000);
323
+
324
+ this.sock.ev.on('connection.update', async (update) => {
325
+ const { connection, lastDisconnect, qr } = update;
326
+
327
+ if (qr && method === 'qr' && this.config.printQR) {
328
+ this.qrCode = qr;
329
+ console.log('\n┌─────────────────────────────┐');
330
+ console.log('│ امسح QR Code بالكاميرا │');
331
+ console.log('└─────────────────────────────┘\n');
332
+ qrcode.generate(qr, { small: true });
333
+ }
334
+
335
+ if (update.isNewLogin && method === 'pairing') {
336
+ try {
337
+ this.pairingCode = await this.sock.requestPairingCode(phoneNumber);
338
+ console.log('\n┌─────────────────────────────┐');
339
+ console.log(`│ الكود: ${this.pairingCode} │`);
340
+ console.log('└─────────────────────────────┘');
341
+ } catch (err) {
342
+ console.error('خطأ في الكود:', err);
343
+ }
344
+ }
345
+
346
+ if (connection === 'open') {
347
+ clearTimeout(timeout);
348
+ this.connected = true;
349
+ this.authData = {
350
+ id: this.sock.user.id,
351
+ user: {
352
+ name: this.sock.user.name,
353
+ phone: this.sock.user.id.split(':')[0]
354
+ }
355
+ };
356
+ log('success', `واتساب متصل: ${this.authData.user.name}`);
357
+ resolve(this.getFingerprint());
358
+ }
359
+
360
+ if (connection === 'close') {
361
+ this.connected = false;
362
+ const shouldReconnect = lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut;
363
+ if (shouldReconnect) {
364
+ log('warning', 'إعادة الاتصال...');
365
+ await this.connect(method, phoneNumber);
366
+ }
367
+ }
368
+ });
369
+
370
+ this.sock.ev.on('creds.update', saveCreds);
371
+ });
372
+ }
373
+
374
+ async disconnect() {
375
+ if (this.sock) {
376
+ await this.sock.logout();
377
+ this.sock = null;
378
+ }
379
+ this.connected = false;
380
+ log('info', 'واتساب: تم قطع الاتصال');
381
+ }
382
+ }
383
+
384
+ // ==========================================
385
+ // MAIN NOHO BOT CLASS
386
+ // ==========================================
387
+ class NohoBot {
388
+ constructor() {
389
+ this.user = new NohoUser();
390
+ this.checker = new CodeChecker();
391
+ this.linker = new BotLinker();
392
+ this.adapters = new Map();
393
+ this.sessions = new Map();
394
+
395
+ this.register('whatsapp', WhatsAppAdapter);
396
+
397
+ this.setupCLI();
398
+ }
399
+
400
+ register(name, AdapterClass) {
401
+ this.adapters.set(name, AdapterClass);
402
+ }
403
+
404
+ // CLI Commands
405
+ setupCLI() {
406
+ const args = process.argv.slice(2);
407
+ const command = args[0];
408
+
409
+ switch(command) {
410
+ case '.longin':
411
+ this.cmdLogin(args[1], args[2]);
412
+ break;
413
+ case '.m':
414
+ this.cmdCheck(args[1]);
415
+ break;
416
+ case '.link':
417
+ this.cmdLink(args[1]);
418
+ break;
419
+ case '.noho.lock.link':
420
+ this.cmdLockLink(args[1], args[2]);
421
+ break;
422
+ case '.d.noho':
423
+ this.cmdInfo();
424
+ break;
425
+ case 'NPI':
426
+ this.cmdNPI();
427
+ break;
428
+ case 'help':
429
+ case '--help':
430
+ case '-h':
431
+ this.cmdHelp();
432
+ break;
433
+ default:
434
+ this.cmdHelp();
435
+ }
436
+ }
437
+
438
+ // الأوامر
439
+ cmdLogin(username, password) {
440
+ if (!username || !password) {
441
+ console.log('الاستخدام: .longin <username> <password>');
442
+ return;
443
+ }
444
+
445
+ if (this.user.exists()) {
446
+ this.user.login(username, password);
447
+ } else {
448
+ this.user.register(username, password);
449
+ }
450
+ }
451
+
452
+ cmdCheck(filePath) {
453
+ if (!filePath) {
454
+ console.log('الاستخدام: .m <file.js>');
455
+ return;
456
+ }
457
+ this.checker.check(filePath);
458
+ }
459
+
460
+ cmdLink(platform) {
461
+ if (!platform) {
462
+ this.linker.list();
463
+ console.log('\nالاستخدام: .link <platform>');
464
+ return;
465
+ }
466
+ this.linker.select(platform);
467
+ }
468
+
469
+ cmdLockLink(platform, sessionName) {
470
+ if (!platform || !sessionName) {
471
+ console.log('الاستخدام: .noho.lock.link <platform> <session-name>');
472
+ return;
473
+ }
474
+ log('lock', `ربط ${platform} باسم ${sessionName}...`);
475
+ // هنا يتم ربط البوت فعلياً
476
+ }
477
+
478
+ cmdInfo() {
479
+ const info = this.user.getInfo();
480
+ if (info) {
481
+ console.log(`\n${colors.cyan}═══ حساب NOHO ═══${colors.reset}`);
482
+ console.log(`المستخدم: ${info.username}`);
483
+ console.log(`المشاريع: ${info.projectsCount}`);
484
+ console.log(`API: ${info.apiKey}`);
485
+ console.log(`منذ: ${info.createdAt}`);
486
+ }
487
+ }
488
+
489
+ cmdNPI() {
490
+ if (!this.user.exists()) {
491
+ log('error', 'سجل دخولك أولاً باستخدام .longin');
492
+ return;
493
+ }
494
+ const newApi = this.user.renewAPI();
495
+ if (newApi) {
496
+ console.log(`API Key جديد: ${newApi}`);
497
+ }
498
+ }
499
+
500
+ cmdHelp() {
501
+ console.log(`
502
+ ${colors.cyan}╔══════════════════════════════════════╗${colors.reset}
503
+ ${colors.cyan}║ NOHO Bot Library v1.0 ║${colors.reset}
504
+ ${colors.cyan}╚══════════════════════════════════════╝${colors.reset}
505
+
506
+ الأوامر المتاحة:
507
+
508
+ ${colors.yellow}.longin <user> <pass>${colors.reset} تسجيل/دخول في noho
509
+ ${colors.yellow}.m <file.js>${colors.reset} فحص كود جافاسكربت
510
+ ${colors.yellow}.link${colors.reset} عرض المنصات المتاحة
511
+ ${colors.yellow}.link <platform>${colors.reset} اختيار منصة (whatsapp, telegram...)
512
+ ${colors.yellow}.noho.lock.link <p> <name>${colors.reset} ربط البوت بجلسة
513
+ ${colors.yellow}.d.noho${colors.reset} عرض بيانات حسابك
514
+ ${colors.yellow}NPI${colors.reset} توليد API Key جديد
515
+
516
+ أمثلة:
517
+ node noho_bot.js .longin omar 123456
518
+ node noho_bot.js .m bot.js
519
+ node noho_bot.js .link whatsapp
520
+ `);
521
+ }
522
+
523
+ // إنشاء بوت جديد
524
+ async create(platform, config = {}) {
525
+ const AdapterClass = this.adapters.get(platform);
526
+ if (!AdapterClass) {
527
+ throw new Error(`المنصة ${platform} غير مدعومة`);
528
+ }
529
+
530
+ const adapter = new AdapterClass(config);
531
+ const sessionId = `${platform}-${Date.now()}`;
532
+ this.sessions.set(sessionId, adapter);
533
+
534
+ return {
535
+ sessionId,
536
+ connect: (...args) => adapter.connect(...args),
537
+ disconnect: () => adapter.disconnect(),
538
+ getFingerprint: () => adapter.getFingerprint()
539
+ };
540
+ }
541
+ }
542
+
543
+ // Export
544
+ module.exports = NohoBot;
545
+
546
+ // تشغيل مباشر إذا تم استدعاء الملف مباشرة
547
+ if (require.main === module) {
548
+ new NohoBot();
549
+ }