waengine 1.7.3 → 1.7.4
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/CHANGELOG.md +29 -0
- package/README.md +34 -3
- package/package.json +3 -2
- package/src/ab-testing.js +698 -0
- package/src/advanced-scheduler.js +577 -0
- package/src/ai-features.js +459 -0
- package/src/ai-integration.js +2 -1
- package/src/analytics-manager.js +458 -0
- package/src/business-manager.js +362 -0
- package/src/client.js +447 -39
- package/src/console-logger.js +256 -0
- package/src/core.js +28 -3
- package/src/cross-platform.js +538 -0
- package/src/database-manager.js +766 -0
- package/src/device-manager.js +1 -1
- package/src/easy-bot-fixed.js +341 -0
- package/src/easy-bot.js +503 -22
- package/src/error-handler.js +230 -0
- package/src/gaming-manager.js +842 -0
- package/src/http-client.js +1 -1
- package/src/index.js +15 -0
- package/src/message.js +197 -94
- package/src/multi-client.js +26 -12
- package/src/plugin-manager.js +59 -10
- package/src/prefix-manager.js +48 -1
- package/src/qr-terminal-fix.js +239 -0
- package/src/qr.js +170 -27
- package/src/quick-bot.js +63 -0
- package/src/reporting-manager.js +867 -0
- package/src/scheduler.js +14 -1
- package/src/security-manager.js +678 -0
- package/src/session-manager-old.js +314 -0
- package/src/session-manager.js +429 -24
- package/src/storage.js +254 -194
- package/src/ui-components.js +560 -0
package/src/http-client.js
CHANGED
package/src/index.js
CHANGED
|
@@ -11,6 +11,8 @@ export { PluginManager } from "./plugin-manager-fixed.js";
|
|
|
11
11
|
export { EasyBot, createBot, createMultiBot, quickBot, bot, multiBot } from "./easy-bot.js";
|
|
12
12
|
export { generateQRCode } from "./qr.js";
|
|
13
13
|
export { Message } from "./message.js";
|
|
14
|
+
export { ConsoleLogger, logger } from "./console-logger.js";
|
|
15
|
+
export { ErrorHandler, defaultErrorHandler } from "./error-handler.js";
|
|
14
16
|
|
|
15
17
|
// ===== ADVANCED FEATURES EXPORTS - NEU! =====
|
|
16
18
|
export {
|
|
@@ -28,3 +30,16 @@ export { EasyAdvanced, EasyAdvancedRule } from "./easy-advanced.js";
|
|
|
28
30
|
// NEUE ROBUSTE FACTORY METHODS - NEU!
|
|
29
31
|
export const createRobustBot = () => EasyBot.createRobust();
|
|
30
32
|
export const createUltraRobustBot = () => EasyBot.createRobust().enableUltraRobust();
|
|
33
|
+
|
|
34
|
+
// ===== NEUE ADVANCED MANAGER EXPORTS =====
|
|
35
|
+
export { BusinessManager } from "./business-manager.js";
|
|
36
|
+
export { AnalyticsManager } from "./analytics-manager.js";
|
|
37
|
+
export { UIComponents } from "./ui-components.js";
|
|
38
|
+
export { AIFeatures } from "./ai-features.js";
|
|
39
|
+
export { CrossPlatformIntegration as CrossPlatform } from "./cross-platform.js";
|
|
40
|
+
export { SecurityManager } from "./security-manager.js";
|
|
41
|
+
export { AdvancedScheduler } from "./advanced-scheduler.js";
|
|
42
|
+
export { GamingManager } from "./gaming-manager.js";
|
|
43
|
+
export { DatabaseManager } from "./database-manager.js";
|
|
44
|
+
export { ABTestingManager } from "./ab-testing.js";
|
|
45
|
+
export { ReportingManager } from "./reporting-manager.js";
|
package/src/message.js
CHANGED
|
@@ -80,42 +80,62 @@ export class Message {
|
|
|
80
80
|
hiddenMentions = [options.hidetag];
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
try {
|
|
84
|
+
return await this.client.socket.sendMessage(this.from, {
|
|
85
|
+
text: text,
|
|
86
|
+
mentions: [...mentions, ...hiddenMentions]
|
|
87
|
+
});
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error('❌ Fehler beim Senden der Hidetag-Nachricht:', error);
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
// Normale Reply
|
|
90
|
-
|
|
95
|
+
try {
|
|
96
|
+
if (mentions.length > 0) {
|
|
97
|
+
return await this.client.socket.sendMessage(this.from, {
|
|
98
|
+
text: text,
|
|
99
|
+
mentions: mentions
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
91
103
|
return await this.client.socket.sendMessage(this.from, {
|
|
92
|
-
text: text
|
|
93
|
-
mentions: mentions
|
|
104
|
+
text: text
|
|
94
105
|
});
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error('❌ Fehler beim Senden der Nachricht:', error);
|
|
108
|
+
throw error;
|
|
95
109
|
}
|
|
96
|
-
|
|
97
|
-
return await this.client.socket.sendMessage(this.from, {
|
|
98
|
-
text: text
|
|
99
|
-
});
|
|
100
110
|
}
|
|
101
111
|
|
|
102
112
|
async sendImage(imagePath, caption = "", mentions = []) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
113
|
+
try {
|
|
114
|
+
const message = {
|
|
115
|
+
image: { url: imagePath },
|
|
116
|
+
caption: caption
|
|
117
|
+
};
|
|
107
118
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
119
|
+
if (mentions.length > 0) {
|
|
120
|
+
message.mentions = mentions;
|
|
121
|
+
}
|
|
111
122
|
|
|
112
|
-
|
|
123
|
+
return await this.client.socket.sendMessage(this.from, message);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
console.error('❌ Fehler beim Senden des Bildes:', error);
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
113
128
|
}
|
|
114
129
|
|
|
115
130
|
async sendSticker(stickerPath) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
131
|
+
try {
|
|
132
|
+
return await this.client.socket.sendMessage(this.from, {
|
|
133
|
+
sticker: { url: stickerPath }
|
|
134
|
+
});
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.error('❌ Fehler beim Senden des Stickers:', error);
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
119
139
|
}
|
|
120
140
|
|
|
121
141
|
// ===== PROFILE PICTURE FUNCTIONS - NEU! =====
|
|
@@ -152,23 +172,33 @@ export class Message {
|
|
|
152
172
|
}
|
|
153
173
|
|
|
154
174
|
async sendAudio(audioPath) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
175
|
+
try {
|
|
176
|
+
return await this.client.socket.sendMessage(this.from, {
|
|
177
|
+
audio: { url: audioPath },
|
|
178
|
+
mimetype: 'audio/mp4'
|
|
179
|
+
});
|
|
180
|
+
} catch (error) {
|
|
181
|
+
console.error('❌ Fehler beim Senden der Audio-Datei:', error);
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
159
184
|
}
|
|
160
185
|
|
|
161
186
|
async sendVideo(videoPath, caption = "", mentions = []) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
187
|
+
try {
|
|
188
|
+
const message = {
|
|
189
|
+
video: { url: videoPath },
|
|
190
|
+
caption: caption
|
|
191
|
+
};
|
|
166
192
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
193
|
+
if (mentions.length > 0) {
|
|
194
|
+
message.mentions = mentions;
|
|
195
|
+
}
|
|
170
196
|
|
|
171
|
-
|
|
197
|
+
return await this.client.socket.sendMessage(this.from, message);
|
|
198
|
+
} catch (error) {
|
|
199
|
+
console.error('❌ Fehler beim Senden des Videos:', error);
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
172
202
|
}
|
|
173
203
|
|
|
174
204
|
async sendDocument(documentPath, fileName, mentions = []) {
|
|
@@ -352,44 +382,143 @@ export class Message {
|
|
|
352
382
|
try {
|
|
353
383
|
console.log('📊 Sende Poll:', question, options);
|
|
354
384
|
|
|
355
|
-
//
|
|
356
|
-
|
|
357
|
-
poll: {
|
|
358
|
-
name: question,
|
|
359
|
-
values: options,
|
|
360
|
-
selectableCount: 1
|
|
361
|
-
}
|
|
362
|
-
};
|
|
385
|
+
// PROBLEM IDENTIFIZIERT: WhatsApp blockiert möglicherweise Bot-Polls
|
|
386
|
+
// Versuche verschiedene Ansätze
|
|
363
387
|
|
|
364
|
-
//
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
388
|
+
// Ansatz 1: Standard Poll ohne selectableCount
|
|
389
|
+
try {
|
|
390
|
+
console.log('🧪 Ansatz 1: Standard Poll ohne selectableCount');
|
|
391
|
+
const basicPoll = {
|
|
392
|
+
poll: {
|
|
393
|
+
name: question,
|
|
394
|
+
values: options
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
const result1 = await this.client.socket.sendMessage(this.from, basicPoll);
|
|
399
|
+
console.log('✅ Basic Poll gesendet:', result1?.key?.id);
|
|
400
|
+
|
|
401
|
+
// Warte kurz und prüfe ob Poll ankommt
|
|
402
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
403
|
+
console.log('⏳ Poll sollte jetzt sichtbar sein...');
|
|
404
|
+
return result1;
|
|
405
|
+
|
|
406
|
+
} catch (error1) {
|
|
407
|
+
console.log('❌ Basic Poll fehlgeschlagen:', error1.message);
|
|
408
|
+
|
|
409
|
+
// Ansatz 2: Poll mit expliziter Konfiguration
|
|
410
|
+
try {
|
|
411
|
+
console.log('🧪 Ansatz 2: Poll mit expliziter Konfiguration');
|
|
412
|
+
const configuredPoll = {
|
|
413
|
+
poll: {
|
|
414
|
+
name: question,
|
|
415
|
+
values: options,
|
|
416
|
+
selectableCount: 1,
|
|
417
|
+
messageSecret: Buffer.from(Array(32).fill(0).map(() => Math.floor(Math.random() * 256)))
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
const result2 = await this.client.socket.sendMessage(this.from, configuredPoll);
|
|
422
|
+
console.log('✅ Configured Poll gesendet:', result2?.key?.id);
|
|
423
|
+
return result2;
|
|
424
|
+
|
|
425
|
+
} catch (error2) {
|
|
426
|
+
console.log('❌ Configured Poll fehlgeschlagen:', error2.message);
|
|
427
|
+
throw error2;
|
|
370
428
|
}
|
|
371
|
-
}
|
|
429
|
+
}
|
|
372
430
|
|
|
373
|
-
|
|
431
|
+
} catch (error) {
|
|
432
|
+
console.error('❌ Alle Poll-Ansätze fehlgeschlagen:', error.message);
|
|
433
|
+
console.log('🔄 Verwende intelligenten Fallback...');
|
|
374
434
|
|
|
435
|
+
// INTELLIGENTER FALLBACK: Interaktive Nachricht mit Buttons (falls verfügbar)
|
|
375
436
|
try {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
437
|
+
console.log('🧪 Versuche Button-Fallback...');
|
|
438
|
+
|
|
439
|
+
const buttonMessage = {
|
|
440
|
+
text: `📊 **${question}**\n\n_Wähle eine Option:_`,
|
|
441
|
+
buttons: options.slice(0, 3).map((option, index) => ({
|
|
442
|
+
buttonId: `poll_${index}`,
|
|
443
|
+
buttonText: { displayText: option },
|
|
444
|
+
type: 1
|
|
445
|
+
})),
|
|
446
|
+
headerType: 1
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
const buttonResult = await this.client.socket.sendMessage(this.from, buttonMessage);
|
|
450
|
+
console.log('✅ Button-Fallback erfolgreich:', buttonResult?.key?.id);
|
|
451
|
+
return buttonResult;
|
|
452
|
+
|
|
453
|
+
} catch (buttonError) {
|
|
454
|
+
console.log('❌ Button-Fallback fehlgeschlagen:', buttonError.message);
|
|
455
|
+
|
|
456
|
+
// LETZTER FALLBACK: Emoji-basierte Poll
|
|
457
|
+
console.log('🔄 Verwende Emoji-Fallback...');
|
|
458
|
+
|
|
459
|
+
let fallbackText = `📊 **${question}**\n\n`;
|
|
460
|
+
const emojis = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟'];
|
|
461
|
+
|
|
462
|
+
options.forEach((option, index) => {
|
|
463
|
+
const emoji = emojis[index] || `${index + 1}️⃣`;
|
|
464
|
+
fallbackText += `${emoji} ${option}\n`;
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
fallbackText += `\n_Reagiere mit dem entsprechenden Emoji zum Abstimmen!_`;
|
|
381
468
|
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
|
|
469
|
+
const fallbackResult = await this.reply(fallbackText);
|
|
470
|
+
|
|
471
|
+
// Auto-Reactions hinzufügen
|
|
472
|
+
setTimeout(async () => {
|
|
473
|
+
try {
|
|
474
|
+
for (let i = 0; i < Math.min(options.length, emojis.length); i++) {
|
|
475
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
476
|
+
await this.client.socket.sendMessage(this.from, {
|
|
477
|
+
react: {
|
|
478
|
+
text: emojis[i],
|
|
479
|
+
key: fallbackResult.key
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
console.log('✅ Emoji-Fallback mit Auto-Reactions bereit');
|
|
484
|
+
} catch (reactError) {
|
|
485
|
+
console.log('⚠️ Auto-Reactions fehlgeschlagen:', reactError.message);
|
|
486
|
+
}
|
|
487
|
+
}, 300);
|
|
488
|
+
|
|
489
|
+
return fallbackResult;
|
|
385
490
|
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
async sendMultiPoll(question, options, maxSelections = 1) {
|
|
495
|
+
if (!Array.isArray(options) || options.length < 2 || options.length > 12) {
|
|
496
|
+
throw new Error('Poll muss zwischen 2 und 12 Optionen haben');
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
try {
|
|
500
|
+
console.log('📊 Sende Multi-Poll:', question, options, 'Max:', maxSelections);
|
|
501
|
+
|
|
502
|
+
// KORRIGIERTE Multi-Poll Syntax
|
|
503
|
+
const multiPollMessage = {
|
|
504
|
+
poll: {
|
|
505
|
+
name: question,
|
|
506
|
+
values: options,
|
|
507
|
+
selectableCount: maxSelections
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
console.log('📋 Multi-Poll Message:', JSON.stringify(multiPollMessage, null, 2));
|
|
512
|
+
|
|
513
|
+
const result = await this.client.socket.sendMessage(this.from, multiPollMessage);
|
|
514
|
+
console.log('✅ Multi-Poll erfolgreich gesendet:', result?.key?.id);
|
|
515
|
+
return result;
|
|
386
516
|
|
|
387
517
|
} catch (error) {
|
|
388
|
-
console.error('❌
|
|
389
|
-
console.log('🔄 Verwende Fallback...');
|
|
518
|
+
console.error('❌ Multi-Poll Fehler:', error.message);
|
|
390
519
|
|
|
391
|
-
// Fallback: Als
|
|
392
|
-
let fallbackText = `📊 **${question}**\n\n`;
|
|
520
|
+
// Fallback: Als normale Nachricht mit Hinweis
|
|
521
|
+
let fallbackText = `📊 **${question}**\n_(Max. ${maxSelections} Auswahlen)_\n\n`;
|
|
393
522
|
const emojis = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟'];
|
|
394
523
|
|
|
395
524
|
options.forEach((option, index) => {
|
|
@@ -397,15 +526,15 @@ export class Message {
|
|
|
397
526
|
fallbackText += `${emoji} ${option}\n`;
|
|
398
527
|
});
|
|
399
528
|
|
|
400
|
-
fallbackText += `\n_Reagiere mit
|
|
529
|
+
fallbackText += `\n_Reagiere mit bis zu ${maxSelections} Emojis!_`;
|
|
401
530
|
|
|
402
531
|
const fallbackResult = await this.reply(fallbackText);
|
|
403
532
|
|
|
404
|
-
// Auto-Reactions
|
|
533
|
+
// Auto-Reactions für Multi-Poll
|
|
405
534
|
setTimeout(async () => {
|
|
406
535
|
try {
|
|
407
536
|
for (let i = 0; i < Math.min(options.length, emojis.length); i++) {
|
|
408
|
-
await new Promise(resolve => setTimeout(resolve,
|
|
537
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
409
538
|
await this.client.socket.sendMessage(this.from, {
|
|
410
539
|
react: {
|
|
411
540
|
text: emojis[i],
|
|
@@ -413,42 +542,16 @@ export class Message {
|
|
|
413
542
|
}
|
|
414
543
|
});
|
|
415
544
|
}
|
|
545
|
+
console.log('✅ Multi-Poll Auto-Reactions hinzugefügt');
|
|
416
546
|
} catch (reactError) {
|
|
417
|
-
console.log('⚠️
|
|
547
|
+
console.log('⚠️ Multi-Poll Auto-Reactions fehlgeschlagen:', reactError.message);
|
|
418
548
|
}
|
|
419
|
-
},
|
|
549
|
+
}, 500);
|
|
420
550
|
|
|
421
551
|
return fallbackResult;
|
|
422
552
|
}
|
|
423
553
|
}
|
|
424
554
|
|
|
425
|
-
async sendMultiPoll(question, options, maxSelections = 1) {
|
|
426
|
-
if (!Array.isArray(options) || options.length < 2 || options.length > 12) {
|
|
427
|
-
throw new Error('Poll muss zwischen 2 und 12 Optionen haben');
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
try {
|
|
431
|
-
return await this.client.socket.sendMessage(this.from, {
|
|
432
|
-
poll: {
|
|
433
|
-
name: question,
|
|
434
|
-
values: options,
|
|
435
|
-
selectableCount: maxSelections
|
|
436
|
-
}
|
|
437
|
-
});
|
|
438
|
-
} catch (error) {
|
|
439
|
-
console.error('❌ Multi-Poll Fehler:', error);
|
|
440
|
-
|
|
441
|
-
// Fallback: Als normale Nachricht
|
|
442
|
-
let fallbackText = `📊 **${question}**\n_(Max. ${maxSelections} Auswahlen)_\n\n`;
|
|
443
|
-
options.forEach((option, index) => {
|
|
444
|
-
fallbackText += `${index + 1}. ${option}\n`;
|
|
445
|
-
});
|
|
446
|
-
fallbackText += `\n_Reagiere mit den entsprechenden Zahlen!_`;
|
|
447
|
-
|
|
448
|
-
return await this.reply(fallbackText);
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
555
|
// ===== UTILITY FUNCTIONS =====
|
|
453
556
|
|
|
454
557
|
async react(emoji) {
|
package/src/multi-client.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { DeviceManager } from "./device-manager.js";
|
|
2
2
|
import { Message } from "./message.js";
|
|
3
|
+
import { ConsoleLogger } from "./console-logger.js";
|
|
3
4
|
|
|
4
5
|
export class MultiWhatsAppClient {
|
|
5
6
|
constructor(options = {}) {
|
|
7
|
+
// Console Logger initialisieren
|
|
8
|
+
this.logger = new ConsoleLogger({
|
|
9
|
+
verbose: options.verbose || false,
|
|
10
|
+
silent: options.silent || false
|
|
11
|
+
});
|
|
12
|
+
|
|
6
13
|
this.deviceManager = new DeviceManager({
|
|
7
14
|
maxDevices: options.maxDevices || 3,
|
|
8
15
|
loadBalancing: options.loadBalancing || 'round-robin',
|
|
@@ -27,7 +34,9 @@ export class MultiWhatsAppClient {
|
|
|
27
34
|
// Device Manager Events weiterleiten
|
|
28
35
|
this.setupDeviceManagerEvents();
|
|
29
36
|
|
|
30
|
-
|
|
37
|
+
// Schöne Console Ausgabe statt Spam
|
|
38
|
+
this.logger.showBanner();
|
|
39
|
+
this.logger.info("Multi-Device Bot wird initialisiert...");
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
// ===== DEVICE MANAGEMENT =====
|
|
@@ -67,8 +76,8 @@ export class MultiWhatsAppClient {
|
|
|
67
76
|
|
|
68
77
|
// NEUE SEQUENZIELLE VERBINDUNG - Ein QR nach dem anderen!
|
|
69
78
|
async connectDevicesSequentially(deviceIds) {
|
|
70
|
-
|
|
71
|
-
|
|
79
|
+
// Schöne Setup Animation
|
|
80
|
+
await this.logger.animateSetup();
|
|
72
81
|
|
|
73
82
|
const results = [];
|
|
74
83
|
let connectedCount = 0;
|
|
@@ -77,34 +86,39 @@ export class MultiWhatsAppClient {
|
|
|
77
86
|
const deviceId = deviceIds[i];
|
|
78
87
|
|
|
79
88
|
try {
|
|
80
|
-
|
|
81
|
-
|
|
89
|
+
// QR-Code Animation
|
|
90
|
+
await this.logger.animateQRGeneration(deviceId, i + 1, deviceIds.length);
|
|
82
91
|
|
|
83
92
|
// Verbinde ein Device und warte bis es fertig ist
|
|
84
93
|
const client = await this.deviceManager.connectDevice(deviceId);
|
|
85
94
|
|
|
86
|
-
|
|
95
|
+
// Connection Animation - Device sollte authentifiziert sein nach connectDevice
|
|
96
|
+
await this.logger.animateConnection(deviceId, true);
|
|
97
|
+
|
|
87
98
|
connectedCount++;
|
|
88
99
|
results.push({ deviceId, status: 'connected', client });
|
|
89
100
|
|
|
90
101
|
// Kurze Pause zwischen Devices
|
|
91
102
|
if (i < deviceIds.length - 1) {
|
|
92
|
-
|
|
93
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
103
|
+
await this.logger.showDevicePause(3);
|
|
94
104
|
}
|
|
95
105
|
|
|
96
106
|
} catch (error) {
|
|
97
|
-
|
|
107
|
+
this.logger.error(`Device '${deviceId}' Verbindung fehlgeschlagen: ${error.message}`);
|
|
98
108
|
results.push({ deviceId, status: 'failed', error: error.message });
|
|
99
109
|
|
|
100
110
|
// Frage ob weiter machen
|
|
101
|
-
|
|
111
|
+
this.logger.warning("Soll mit dem nächsten Device fortgefahren werden? (Automatisch ja in 5s)");
|
|
102
112
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
103
113
|
}
|
|
104
114
|
}
|
|
105
115
|
|
|
106
|
-
|
|
107
|
-
|
|
116
|
+
// Finale schöne Zusammenfassung
|
|
117
|
+
const connectedDeviceNames = results
|
|
118
|
+
.filter(r => r.status === 'connected')
|
|
119
|
+
.map(r => r.deviceId);
|
|
120
|
+
|
|
121
|
+
this.logger.showFinalSummary(connectedDeviceNames);
|
|
108
122
|
|
|
109
123
|
if (connectedCount === 0) {
|
|
110
124
|
throw new Error("❌ Keine Devices konnten verbunden werden!");
|
package/src/plugin-manager.js
CHANGED
|
@@ -26,28 +26,77 @@ export class PluginManager {
|
|
|
26
26
|
try {
|
|
27
27
|
console.log(`🔌 Lade Plugin: ${pluginName}`);
|
|
28
28
|
|
|
29
|
-
// Plugin
|
|
30
|
-
|
|
29
|
+
// Plugin-Pfad validieren
|
|
30
|
+
if (!pluginName || typeof pluginName !== 'string') {
|
|
31
|
+
throw new Error('Ungültiger Plugin-Name');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Sanitize Plugin-Name (Sicherheit)
|
|
35
|
+
const sanitizedName = pluginName.replace(/[^a-zA-Z0-9-_]/g, '');
|
|
36
|
+
if (!sanitizedName) {
|
|
37
|
+
throw new Error('Plugin-Name enthält ungültige Zeichen');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const pluginPath = join(process.cwd(), this.pluginsDir, sanitizedName, 'index.js');
|
|
31
41
|
|
|
32
42
|
if (!existsSync(pluginPath)) {
|
|
33
|
-
console.log(`📝 Plugin ${
|
|
43
|
+
console.log(`📝 Plugin ${sanitizedName} nicht gefunden - wird übersprungen`);
|
|
34
44
|
return null;
|
|
35
45
|
}
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
// Plugin-Struktur validieren vor Import
|
|
48
|
+
const pluginModule = await import(pluginPath);
|
|
49
|
+
|
|
50
|
+
if (!pluginModule.default) {
|
|
51
|
+
throw new Error(`Plugin ${sanitizedName} hat keinen default export`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const PluginClass = pluginModule.default;
|
|
38
55
|
|
|
39
|
-
// Plugin
|
|
40
|
-
|
|
41
|
-
|
|
56
|
+
// Validiere Plugin-Klasse
|
|
57
|
+
if (typeof PluginClass !== 'function') {
|
|
58
|
+
throw new Error(`Plugin ${sanitizedName} default export ist keine Klasse`);
|
|
59
|
+
}
|
|
42
60
|
|
|
43
|
-
//
|
|
44
|
-
|
|
61
|
+
// Plugin instanziieren mit Error-Handling
|
|
62
|
+
let plugin;
|
|
63
|
+
try {
|
|
64
|
+
plugin = new PluginClass(this.client);
|
|
65
|
+
} catch (constructorError) {
|
|
66
|
+
throw new Error(`Plugin ${sanitizedName} Konstruktor-Fehler: ${constructorError.message}`);
|
|
67
|
+
}
|
|
45
68
|
|
|
46
|
-
|
|
69
|
+
// Validiere Plugin-Interface
|
|
70
|
+
if (!plugin.name || !plugin.version) {
|
|
71
|
+
throw new Error(`Plugin ${sanitizedName} fehlt name oder version`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (typeof plugin.getCommands !== 'function') {
|
|
75
|
+
console.warn(`⚠️ Plugin ${sanitizedName} hat keine getCommands() Methode`);
|
|
76
|
+
plugin.getCommands = () => [];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Plugin registrieren
|
|
80
|
+
this.plugins.set(sanitizedName, plugin);
|
|
81
|
+
|
|
82
|
+
// Commands registrieren mit Error-Handling
|
|
83
|
+
try {
|
|
84
|
+
await this.registerPluginCommands(plugin);
|
|
85
|
+
} catch (commandError) {
|
|
86
|
+
console.warn(`⚠️ Plugin ${sanitizedName} Commands konnten nicht registriert werden:`, commandError.message);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
console.log(`✅ Plugin geladen: ${plugin.name} v${plugin.version}`);
|
|
47
90
|
return plugin;
|
|
48
91
|
|
|
49
92
|
} catch (error) {
|
|
50
93
|
console.error(`❌ Plugin Fehler: ${pluginName}`, error.message);
|
|
94
|
+
|
|
95
|
+
// Plugin aus Map entfernen falls teilweise geladen
|
|
96
|
+
if (this.plugins.has(pluginName)) {
|
|
97
|
+
this.plugins.delete(pluginName);
|
|
98
|
+
}
|
|
99
|
+
|
|
51
100
|
return null;
|
|
52
101
|
}
|
|
53
102
|
}
|
package/src/prefix-manager.js
CHANGED
|
@@ -115,7 +115,10 @@ export class PrefixManager {
|
|
|
115
115
|
|
|
116
116
|
const prefix = this.getPrefix(chatId);
|
|
117
117
|
const commandText = text.slice(prefix.length).trim();
|
|
118
|
-
const [command, ...
|
|
118
|
+
const [command, ...rawArgs] = commandText.split(' ');
|
|
119
|
+
|
|
120
|
+
// INTELLIGENTES ARGUMENT-PARSING für Anführungszeichen
|
|
121
|
+
const args = this.parseQuotedArguments(rawArgs.join(' '));
|
|
119
122
|
|
|
120
123
|
return {
|
|
121
124
|
prefix,
|
|
@@ -126,6 +129,50 @@ export class PrefixManager {
|
|
|
126
129
|
};
|
|
127
130
|
}
|
|
128
131
|
|
|
132
|
+
// Parst Argumente mit Anführungszeichen-Unterstützung
|
|
133
|
+
parseQuotedArguments(argsString) {
|
|
134
|
+
if (!argsString.trim()) return [];
|
|
135
|
+
|
|
136
|
+
const args = [];
|
|
137
|
+
let current = '';
|
|
138
|
+
let inQuotes = false;
|
|
139
|
+
let quoteChar = '';
|
|
140
|
+
|
|
141
|
+
for (let i = 0; i < argsString.length; i++) {
|
|
142
|
+
const char = argsString[i];
|
|
143
|
+
|
|
144
|
+
if ((char === '"' || char === "'") && !inQuotes) {
|
|
145
|
+
// Start einer Anführungszeichen-Gruppe
|
|
146
|
+
inQuotes = true;
|
|
147
|
+
quoteChar = char;
|
|
148
|
+
} else if (char === quoteChar && inQuotes) {
|
|
149
|
+
// Ende einer Anführungszeichen-Gruppe
|
|
150
|
+
inQuotes = false;
|
|
151
|
+
quoteChar = '';
|
|
152
|
+
if (current.trim()) {
|
|
153
|
+
args.push(current.trim());
|
|
154
|
+
current = '';
|
|
155
|
+
}
|
|
156
|
+
} else if (char === ' ' && !inQuotes) {
|
|
157
|
+
// Leerzeichen außerhalb von Anführungszeichen
|
|
158
|
+
if (current.trim()) {
|
|
159
|
+
args.push(current.trim());
|
|
160
|
+
current = '';
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
// Normales Zeichen
|
|
164
|
+
current += char;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Letztes Argument hinzufügen
|
|
169
|
+
if (current.trim()) {
|
|
170
|
+
args.push(current.trim());
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return args;
|
|
174
|
+
}
|
|
175
|
+
|
|
129
176
|
// ===== STATISTICS =====
|
|
130
177
|
|
|
131
178
|
getStats() {
|