waengine 1.0.8 → 1.0.10

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.
@@ -0,0 +1,221 @@
1
+ // 🎵 Music Plugin mit yt-dlp
2
+ import { exec } from 'child_process';
3
+ import { promisify } from 'util';
4
+
5
+ const execAsync = promisify(exec);
6
+
7
+ export default class MusicPlugin {
8
+ constructor(client) {
9
+ this.client = client;
10
+ this.name = 'music-plugin';
11
+ this.version = '1.0.0';
12
+ this.description = 'Music System mit YouTube Download und Spotify Integration';
13
+ }
14
+
15
+ async searchYouTube(query) {
16
+ try {
17
+ const { stdout } = await execAsync(`yt-dlp --dump-json "ytsearch5:${query}"`);
18
+ const results = stdout.trim().split('\n').map(line => JSON.parse(line));
19
+
20
+ return results.map(video => ({
21
+ id: video.id,
22
+ title: video.title,
23
+ duration: video.duration,
24
+ uploader: video.uploader,
25
+ url: video.webpage_url,
26
+ thumbnail: video.thumbnail
27
+ }));
28
+ } catch (error) {
29
+ console.error('YouTube Search Error:', error);
30
+ return [];
31
+ }
32
+ }
33
+
34
+ async getVideoInfo(url) {
35
+ try {
36
+ const { stdout } = await execAsync(`yt-dlp --dump-json "${url}"`);
37
+ const info = JSON.parse(stdout);
38
+
39
+ return {
40
+ id: info.id,
41
+ title: info.title,
42
+ duration: info.duration,
43
+ uploader: info.uploader,
44
+ description: info.description,
45
+ thumbnail: info.thumbnail,
46
+ formats: info.formats
47
+ };
48
+ } catch (error) {
49
+ console.error('Video Info Error:', error);
50
+ return null;
51
+ }
52
+ }
53
+
54
+ async downloadAudio(url, quality = 'best') {
55
+ try {
56
+ const outputPath = `./downloads/%(title)s.%(ext)s`;
57
+ const command = `yt-dlp -x --audio-format mp3 --audio-quality ${quality} -o "${outputPath}" "${url}"`;
58
+
59
+ const { stdout } = await execAsync(command);
60
+ return { success: true, output: stdout };
61
+ } catch (error) {
62
+ console.error('Download Error:', error);
63
+ return { success: false, error: error.message };
64
+ }
65
+ }
66
+
67
+ formatDuration(seconds) {
68
+ const minutes = Math.floor(seconds / 60);
69
+ const remainingSeconds = seconds % 60;
70
+ return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
71
+ }
72
+
73
+ async createPlaylist(userId, name) {
74
+ const playlistId = Date.now().toString();
75
+ this.client.storage.write.in('music').set(`playlists.${playlistId}`, {
76
+ id: playlistId,
77
+ name,
78
+ owner: userId,
79
+ songs: [],
80
+ created: Date.now()
81
+ });
82
+
83
+ return playlistId;
84
+ }
85
+
86
+ async addToPlaylist(playlistId, song) {
87
+ this.client.storage.write.in('music').push(`playlists.${playlistId}.songs`, song);
88
+ }
89
+
90
+ async getUserPlaylists(userId) {
91
+ const playlists = this.client.storage.read.from('music').get('playlists') || {};
92
+ return Object.values(playlists).filter(playlist => playlist.owner === userId);
93
+ }
94
+
95
+ getCommands() {
96
+ return {
97
+ 'music': this.handleMusic.bind(this),
98
+ 'youtube': this.handleYouTube.bind(this),
99
+ 'download': this.handleDownload.bind(this),
100
+ 'playlist': this.handlePlaylist.bind(this),
101
+ 'lyrics': this.handleLyrics.bind(this),
102
+ 'spotify': this.handleSpotify.bind(this)
103
+ };
104
+ }
105
+
106
+ async handleMusic(msg, args) {
107
+ if (args.length === 0) {
108
+ return msg.reply(`🎵 **Music Plugin Commands:**
109
+
110
+ 🔍 !music search <song> - Musik suchen
111
+ 📺 !youtube <query> - YouTube suchen
112
+ ⬇️ !download <url> - Audio downloaden
113
+ 📋 !playlist - Playlist verwalten
114
+ 📝 !lyrics <song> - Songtexte suchen
115
+ 🎧 !spotify - Spotify Features`);
116
+ }
117
+
118
+ const action = args[0].toLowerCase();
119
+ const query = args.slice(1).join(' ');
120
+
121
+ if (action === 'search') {
122
+ if (!query) return msg.reply('❌ Gib einen Suchbegriff ein!');
123
+
124
+ await msg.reply('🔍 Suche Musik...');
125
+ const results = await this.searchYouTube(query);
126
+
127
+ if (results.length === 0) {
128
+ return msg.reply('❌ Keine Ergebnisse gefunden!');
129
+ }
130
+
131
+ let resultText = `🎵 **Suchergebnisse für "${query}":**\n\n`;
132
+ results.slice(0, 3).forEach((video, index) => {
133
+ resultText += `${index + 1}. **${video.title}**\n`;
134
+ resultText += `👤 ${video.uploader}\n`;
135
+ resultText += `⏱️ ${this.formatDuration(video.duration)}\n`;
136
+ resultText += `🔗 ${video.url}\n\n`;
137
+ });
138
+
139
+ await msg.reply(resultText);
140
+ }
141
+ }
142
+
143
+ async handleYouTube(msg, args) {
144
+ if (args.length === 0) {
145
+ return msg.reply('❌ Verwendung: !youtube <suchbegriff>');
146
+ }
147
+
148
+ const query = args.join(' ');
149
+ await msg.reply('📺 Suche auf YouTube...');
150
+
151
+ const results = await this.searchYouTube(query);
152
+
153
+ if (results.length === 0) {
154
+ return msg.reply('❌ Keine YouTube Videos gefunden!');
155
+ }
156
+
157
+ let resultText = `📺 **YouTube Ergebnisse:**\n\n`;
158
+ results.slice(0, 5).forEach((video, index) => {
159
+ resultText += `${index + 1}. **${video.title}**\n`;
160
+ resultText += `👤 ${video.uploader}\n`;
161
+ resultText += `⏱️ ${this.formatDuration(video.duration)}\n`;
162
+ resultText += `🔗 ${video.url}\n\n`;
163
+ });
164
+
165
+ resultText += '⬇️ Download mit: !download <url>';
166
+ await msg.reply(resultText);
167
+ }
168
+ async handleDownload(msg, args) {
169
+ if (args.length === 0) {
170
+ return msg.reply('❌ Verwendung: !download <youtube-url>');
171
+ }
172
+
173
+ const url = args[0];
174
+ await msg.reply('⬇️ Starte Download...');
175
+
176
+ const result = await this.downloadAudio(url);
177
+
178
+ if (result.success) {
179
+ await msg.reply('✅ Download erfolgreich! Audio wird verarbeitet...');
180
+ } else {
181
+ await msg.reply(`❌ Download fehlgeschlagen: ${result.error}`);
182
+ }
183
+ }
184
+
185
+ async handlePlaylist(msg, args) {
186
+ const userId = msg.getSender();
187
+
188
+ if (args.length === 0) {
189
+ const playlists = await this.getUserPlaylists(userId);
190
+
191
+ if (playlists.length === 0) {
192
+ return msg.reply('📋 **Keine Playlists gefunden!**\n\n💡 Erstelle eine mit: !playlist create <name>');
193
+ }
194
+
195
+ let playlistText = '📋 **Deine Playlists:**\n\n';
196
+ playlists.forEach((playlist, index) => {
197
+ playlistText += `${index + 1}. **${playlist.name}**\n`;
198
+ playlistText += `🎵 ${playlist.songs.length} Songs\n`;
199
+ playlistText += `📅 Erstellt: ${new Date(playlist.created).toLocaleDateString()}\n\n`;
200
+ });
201
+
202
+ await msg.reply(playlistText);
203
+ }
204
+ }
205
+
206
+ async handleLyrics(msg, args) {
207
+ if (args.length === 0) {
208
+ return msg.reply('❌ Verwendung: !lyrics <song title>');
209
+ }
210
+
211
+ const song = args.join(' ');
212
+ await msg.reply(`🔍 Suche Songtexte für "${song}"...`);
213
+
214
+ // Placeholder - hier würdest du eine Lyrics API verwenden
215
+ await msg.reply(`📝 **Songtexte für "${song}":**\n\n_Lyrics API Integration folgt..._\n\n💡 Verwende eine Lyrics API wie Genius oder AZLyrics`);
216
+ }
217
+
218
+ async handleSpotify(msg, args) {
219
+ await msg.reply(`🎧 **Spotify Integration:**\n\n_Spotify API Integration folgt..._\n\n💡 Features:\n• Now Playing\n• Playlists\n• Search\n• Recommendations`);
220
+ }
221
+ }
@@ -0,0 +1,230 @@
1
+ // 🌍 Travel Plugin
2
+ export default class TravelPlugin {
3
+ constructor(client) {
4
+ this.client = client;
5
+ this.name = 'travel-plugin';
6
+ this.version = '1.0.0';
7
+ this.description = 'Reise-System mit Wetter, Flügen, Hotels und Währungsrechner';
8
+ }
9
+
10
+ async getWeather(city) {
11
+ try {
12
+ // Verwende den HTTP Client für Wetter-API
13
+ return await this.client.http.getWeather(city);
14
+ } catch (error) {
15
+ return {
16
+ city: city,
17
+ temperature: Math.floor(Math.random() * 30) + 5,
18
+ description: 'Teilweise bewölkt',
19
+ humidity: Math.floor(Math.random() * 40) + 40,
20
+ windSpeed: Math.floor(Math.random() * 10) + 2
21
+ };
22
+ }
23
+ }
24
+
25
+ async searchFlights(from, to) {
26
+ // Simulierte Flugdaten
27
+ const airlines = ['Lufthansa', 'Ryanair', 'Eurowings', 'Turkish Airlines', 'Emirates'];
28
+ const flights = [];
29
+
30
+ for (let i = 0; i < 3; i++) {
31
+ flights.push({
32
+ airline: airlines[Math.floor(Math.random() * airlines.length)],
33
+ departure: `${Math.floor(Math.random() * 12) + 6}:${Math.floor(Math.random() * 6) * 10}`,
34
+ arrival: `${Math.floor(Math.random() * 12) + 12}:${Math.floor(Math.random() * 6) * 10}`,
35
+ price: Math.floor(Math.random() * 500) + 100,
36
+ duration: `${Math.floor(Math.random() * 8) + 2}h ${Math.floor(Math.random() * 6) * 10}m`,
37
+ stops: Math.floor(Math.random() * 3)
38
+ });
39
+ }
40
+
41
+ return flights;
42
+ }
43
+
44
+ async searchHotels(city) {
45
+ const hotelNames = ['Hotel Central', 'Grand Palace', 'City Inn', 'Comfort Suites', 'Luxury Resort'];
46
+ const hotels = [];
47
+
48
+ for (let i = 0; i < 4; i++) {
49
+ hotels.push({
50
+ name: hotelNames[Math.floor(Math.random() * hotelNames.length)],
51
+ stars: Math.floor(Math.random() * 3) + 3,
52
+ price: Math.floor(Math.random() * 200) + 50,
53
+ rating: (Math.random() * 2 + 3).toFixed(1),
54
+ amenities: ['WiFi', 'Pool', 'Gym', 'Restaurant'].slice(0, Math.floor(Math.random() * 4) + 1)
55
+ });
56
+ }
57
+
58
+ return hotels;
59
+ }
60
+
61
+ async convertCurrency(amount, from, to) {
62
+ // Simulierte Wechselkurse
63
+ const rates = {
64
+ 'USD': { 'EUR': 0.85, 'GBP': 0.73, 'JPY': 110 },
65
+ 'EUR': { 'USD': 1.18, 'GBP': 0.86, 'JPY': 130 },
66
+ 'GBP': { 'USD': 1.37, 'EUR': 1.16, 'JPY': 151 }
67
+ };
68
+
69
+ if (from === to) return amount;
70
+
71
+ const rate = rates[from]?.[to] || 1;
72
+ const converted = (amount * rate).toFixed(2);
73
+
74
+ return {
75
+ original: amount,
76
+ converted: parseFloat(converted),
77
+ fromCurrency: from,
78
+ toCurrency: to,
79
+ rate: rate
80
+ };
81
+ }
82
+
83
+ async translateText(text, targetLang) {
84
+ // Verwende AI Integration falls verfügbar
85
+ try {
86
+ return await this.client.ai.translate(text, targetLang);
87
+ } catch (error) {
88
+ return `[Übersetzung zu ${targetLang}]: ${text}`;
89
+ }
90
+ }
91
+
92
+ getCommands() {
93
+ return {
94
+ 'weather': this.handleWeather.bind(this),
95
+ 'flights': this.handleFlights.bind(this),
96
+ 'hotels': this.handleHotels.bind(this),
97
+ 'currency': this.handleCurrency.bind(this),
98
+ 'translate': this.handleTranslate.bind(this),
99
+ 'travel': this.handleTravel.bind(this)
100
+ };
101
+ }
102
+
103
+ async handleWeather(msg, args) {
104
+ if (args.length === 0) {
105
+ return msg.reply('❌ Verwendung: !weather <stadt>\n\n🌤️ Beispiel: !weather Berlin');
106
+ }
107
+
108
+ const city = args.join(' ');
109
+ await msg.reply(`🌤️ Lade Wetterdaten für ${city}...`);
110
+
111
+ const weather = await this.getWeather(city);
112
+
113
+ let weatherText = `🌤️ **Wetter in ${weather.city}:**\n\n`;
114
+ weatherText += `🌡️ Temperatur: ${weather.temperature}°C\n`;
115
+ weatherText += `☁️ Bedingungen: ${weather.description}\n`;
116
+ weatherText += `💧 Luftfeuchtigkeit: ${weather.humidity}%\n`;
117
+ weatherText += `💨 Windgeschwindigkeit: ${weather.windSpeed} km/h`;
118
+
119
+ await msg.reply(weatherText);
120
+ }
121
+
122
+ async handleFlights(msg, args) {
123
+ if (args.length < 2) {
124
+ return msg.reply('❌ Verwendung: !flights <von> <nach>\n\n✈️ Beispiel: !flights Berlin München');
125
+ }
126
+
127
+ const from = args[0];
128
+ const to = args[1];
129
+
130
+ await msg.reply(`✈️ Suche Flüge von ${from} nach ${to}...`);
131
+
132
+ const flights = await this.searchFlights(from, to);
133
+
134
+ let flightText = `✈️ **Flüge ${from} → ${to}:**\n\n`;
135
+
136
+ flights.forEach((flight, index) => {
137
+ flightText += `${index + 1}. **${flight.airline}**\n`;
138
+ flightText += `🕐 ${flight.departure} → ${flight.arrival}\n`;
139
+ flightText += `⏱️ Dauer: ${flight.duration}\n`;
140
+ flightText += `🔄 Stops: ${flight.stops === 0 ? 'Direktflug' : `${flight.stops} Stop(s)`}\n`;
141
+ flightText += `💰 Preis: €${flight.price}\n\n`;
142
+ });
143
+
144
+ await msg.reply(flightText);
145
+ }
146
+
147
+ async handleHotels(msg, args) {
148
+ if (args.length === 0) {
149
+ return msg.reply('❌ Verwendung: !hotels <stadt>\n\n🏨 Beispiel: !hotels Paris');
150
+ }
151
+
152
+ const city = args.join(' ');
153
+ await msg.reply(`🏨 Suche Hotels in ${city}...`);
154
+
155
+ const hotels = await this.searchHotels(city);
156
+
157
+ let hotelText = `🏨 **Hotels in ${city}:**\n\n`;
158
+
159
+ hotels.forEach((hotel, index) => {
160
+ const stars = '⭐'.repeat(hotel.stars);
161
+ flightText += `${index + 1}. **${hotel.name}** ${stars}\n`;
162
+ hotelText += `⭐ Rating: ${hotel.rating}/5.0\n`;
163
+ hotelText += `💰 Ab €${hotel.price}/Nacht\n`;
164
+ hotelText += `🎯 Ausstattung: ${hotel.amenities.join(', ')}\n\n`;
165
+ });
166
+
167
+ await msg.reply(hotelText);
168
+ }
169
+
170
+ async handleCurrency(msg, args) {
171
+ if (args.length < 3) {
172
+ return msg.reply('❌ Verwendung: !currency <betrag> <von> <zu>\n\n💱 Beispiel: !currency 100 USD EUR');
173
+ }
174
+
175
+ const amount = parseFloat(args[0]);
176
+ const from = args[1].toUpperCase();
177
+ const to = args[2].toUpperCase();
178
+
179
+ if (isNaN(amount)) {
180
+ return msg.reply('❌ Ungültiger Betrag!');
181
+ }
182
+
183
+ const result = await this.convertCurrency(amount, from, to);
184
+
185
+ let currencyText = `💱 **Währungsrechner:**\n\n`;
186
+ currencyText += `💰 ${result.original} ${result.fromCurrency}\n`;
187
+ currencyText += `= ${result.converted} ${result.toCurrency}\n\n`;
188
+ currencyText += `📊 Wechselkurs: 1 ${result.fromCurrency} = ${result.rate} ${result.toCurrency}`;
189
+
190
+ await msg.reply(currencyText);
191
+ }
192
+
193
+ async handleTranslate(msg, args) {
194
+ if (args.length < 2) {
195
+ return msg.reply('❌ Verwendung: !translate <sprache> <text>\n\n🌍 Beispiel: !translate en Hallo Welt');
196
+ }
197
+
198
+ const targetLang = args[0];
199
+ const text = args.slice(1).join(' ');
200
+
201
+ await msg.reply(`🌍 Übersetze zu ${targetLang}...`);
202
+
203
+ const translation = await this.translateText(text, targetLang);
204
+
205
+ let translateText = `🌍 **Übersetzung:**\n\n`;
206
+ translateText += `📝 Original: ${text}\n`;
207
+ translateText += `🔄 ${targetLang}: ${translation}`;
208
+
209
+ await msg.reply(translateText);
210
+ }
211
+
212
+ async handleTravel(msg, args) {
213
+ const helpText = `🌍 **Travel Plugin Commands:**
214
+
215
+ 🌤️ !weather <stadt> - Wetter abrufen
216
+ ✈️ !flights <von> <nach> - Flüge suchen
217
+ 🏨 !hotels <stadt> - Hotels finden
218
+ 💱 !currency <betrag> <von> <zu> - Währung umrechnen
219
+ 🌍 !translate <sprache> <text> - Text übersetzen
220
+
221
+ 📋 **Beispiele:**
222
+ • !weather Berlin
223
+ • !flights München Hamburg
224
+ • !hotels Paris
225
+ • !currency 100 USD EUR
226
+ • !translate en Guten Tag`;
227
+
228
+ await msg.reply(helpText);
229
+ }
230
+ }
package/src/client.js CHANGED
@@ -8,6 +8,7 @@ import { getStorage } from "./storage.js";
8
8
  import { AIIntegration } from "./ai-integration.js";
9
9
  import { HTTPClient } from "./http-client.js";
10
10
  import { Scheduler } from "./scheduler.js";
11
+ import { PluginManager } from "./plugin-manager-fixed.js";
11
12
 
12
13
  export class WhatsAppClient {
13
14
  constructor(options = {}) {
@@ -49,6 +50,23 @@ export class WhatsAppClient {
49
50
  // Waiting System für Messages
50
51
  this.waiting = this.scheduler.createWaiting();
51
52
 
53
+ // Plugin System
54
+ this.plugins = new PluginManager(this);
55
+
56
+ // Load API für Plugins
57
+ this.load = {
58
+ Plugins: async (pluginName) => {
59
+ if (pluginName === 'all') {
60
+ console.log('🔌 Lade alle Plugins...');
61
+ await this.plugins.loadAllPlugins();
62
+ console.log('✅ Alle Plugins geladen!');
63
+ } else {
64
+ console.log(`🔌 Lade Plugin: ${pluginName}`);
65
+ await this.plugins.load(pluginName);
66
+ }
67
+ }
68
+ };
69
+
52
70
  // Deine eigenen API-Objekte
53
71
  this.get = new GetAPI(this);
54
72
  this.add = new AddAPI(this);
@@ -191,6 +209,10 @@ export class WhatsAppClient {
191
209
  this.isConnected = true;
192
210
  await closeBrowser(); // QR Browser schließen
193
211
  this.emit('connected');
212
+
213
+ // 🔌 Plugins werden NICHT automatisch geladen
214
+ // Verwende client.load.Plugins("plugin-name") um Plugins zu laden
215
+
194
216
  resolve(this);
195
217
  }
196
218
  });
package/src/easy-bot.js CHANGED
@@ -413,78 +413,79 @@ class EasyRule {
413
413
  this.actions = [];
414
414
  }
415
415
 
416
- // Actions - Return this rule for chaining!
416
+ // Actions - Return bot for chaining more rules!
417
417
  reply(text) {
418
418
  this.actions.push({ type: 'reply', value: text });
419
- return this; // Rule chaining!
419
+ return this.bot; // Return bot for more .when() calls!
420
420
  }
421
421
 
422
422
  send(text) {
423
- return this.reply(text);
423
+ this.actions.push({ type: 'reply', value: text });
424
+ return this.bot; // Return bot for more .when() calls!
424
425
  }
425
426
 
426
427
  react(emoji) {
427
428
  this.actions.push({ type: 'react', value: emoji });
428
- return this; // Rule chaining!
429
+ return this.bot; // Return bot for more .when() calls!
429
430
  }
430
431
 
431
432
  type(seconds = 2) {
432
433
  this.actions.push({ type: 'type', value: seconds * 1000 });
433
- return this; // Rule chaining!
434
+ return this.bot; // Return bot for more .when() calls!
434
435
  }
435
436
 
436
437
  typeAndReply(text, seconds = 2) {
437
438
  this.type(seconds);
438
439
  this.reply(text);
439
- return this; // Rule chaining!
440
+ return this.bot; // Return bot for more .when() calls!
440
441
  }
441
442
 
442
443
  useTemplate(templateName) {
443
444
  this.actions.push({ type: 'template', value: templateName });
444
- return this; // Rule chaining!
445
+ return this.bot; // Return bot for more .when() calls!
445
446
  }
446
447
 
447
448
  // Media actions
448
449
  sendImage(path, caption = "") {
449
450
  this.actions.push({ type: 'image', value: { path, caption } });
450
- return this;
451
+ return this.bot;
451
452
  }
452
453
 
453
454
  sendSticker(path) {
454
455
  this.actions.push({ type: 'sticker', value: path });
455
- return this;
456
+ return this.bot;
456
457
  }
457
458
 
458
459
  sendLocation(lat, lng) {
459
460
  this.actions.push({ type: 'location', value: { lat, lng } });
460
- return this;
461
+ return this.bot;
461
462
  }
462
463
 
463
464
  // Mention actions
464
465
  mentionSender(text) {
465
466
  this.actions.push({ type: 'mentionSender', value: text });
466
- return this;
467
+ return this.bot;
467
468
  }
468
469
 
469
470
  mentionAll(text) {
470
471
  this.actions.push({ type: 'mentionAll', value: text });
471
- return this;
472
+ return this.bot;
472
473
  }
473
474
 
474
475
  mentionUser(text, userJid) {
475
476
  this.actions.push({ type: 'mentionUser', value: { text, userJid } });
476
- return this;
477
+ return this.bot;
477
478
  }
478
479
 
479
480
  // Delete actions
480
481
  deleteMessage() {
481
482
  this.actions.push({ type: 'delete' });
482
- return this;
483
+ return this.bot;
483
484
  }
484
485
 
485
486
  deleteAfter(seconds) {
486
487
  this.actions.push({ type: 'deleteAfter', value: seconds });
487
- return this;
488
+ return this.bot;
488
489
  }
489
490
 
490
491
  // End chaining - return bot
package/src/index.js CHANGED
@@ -6,6 +6,8 @@ export { WAStorage, createStorage, getStorage, write, read, del } from "./storag
6
6
  export { AIIntegration } from "./ai-integration.js";
7
7
  export { HTTPClient } from "./http-client.js";
8
8
  export { Scheduler } from "./scheduler.js";
9
+ export { StickerCreator } from "./sticker-creator.js";
10
+ export { PluginManager } from "./plugin-manager-fixed.js";
9
11
  export { EasyBot, createBot, createMultiBot, quickBot, bot, multiBot } from "./easy-bot.js";
10
12
  export { generateQRCode } from "./qr.js";
11
13
  export { Message } from "./message.js";