waengine 1.0.7 → 1.0.9
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 +89 -0
- package/FEATURES.md +2354 -0
- package/PLUGIN-SYSTEM.md +271 -0
- package/package.json +14 -3
- package/plugins/analytics-plugin/config.json +91 -0
- package/plugins/analytics-plugin/index.js +461 -0
- package/plugins/creative-plugin/config.json +87 -0
- package/plugins/creative-plugin/index.js +320 -0
- package/plugins/economy-system/config.json +48 -0
- package/plugins/economy-system/index.js +237 -0
- package/plugins/education-plugin/index.js +275 -0
- package/plugins/games-plugin/config.json +35 -0
- package/plugins/games-plugin/index.js +300 -0
- package/plugins/moderation-plugin/config.json +86 -0
- package/plugins/moderation-plugin/index.js +458 -0
- package/plugins/music-plugin/config.json +32 -0
- package/plugins/music-plugin/index.js +221 -0
- package/plugins/travel-plugin/index.js +230 -0
- package/src/ai-integration.js +185 -0
- package/src/client.js +41 -0
- package/src/http-client.js +276 -0
- package/src/index.js +6 -0
- package/src/message.js +127 -1
- package/src/plugin-manager-fixed.js +116 -0
- package/src/plugin-manager.js +105 -0
- package/src/scheduler.js +322 -0
- package/src/sticker-creator.js +413 -0
- package/src/storage.js +422 -0
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// AI Integration für WAEngine
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
|
|
4
|
+
export class AIIntegration {
|
|
5
|
+
constructor(options = {}) {
|
|
6
|
+
this.apiKey = options.apiKey || process.env.OPENAI_API_KEY;
|
|
7
|
+
this.baseURL = options.baseURL || 'https://api.openai.com/v1';
|
|
8
|
+
this.model = options.model || 'gpt-3.5-turbo';
|
|
9
|
+
this.enabled = !!this.apiKey;
|
|
10
|
+
|
|
11
|
+
if (!this.enabled) {
|
|
12
|
+
console.log('⚠️ AI Integration deaktiviert - Kein API Key gefunden');
|
|
13
|
+
} else {
|
|
14
|
+
console.log('🤖 AI Integration aktiviert');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// ===== CHAT COMPLETION =====
|
|
19
|
+
|
|
20
|
+
async chat(prompt, options = {}) {
|
|
21
|
+
if (!this.enabled) {
|
|
22
|
+
throw new Error('❌ AI Integration nicht konfiguriert! Setze OPENAI_API_KEY');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const response = await axios.post(`${this.baseURL}/chat/completions`, {
|
|
27
|
+
model: options.model || this.model,
|
|
28
|
+
messages: [
|
|
29
|
+
{
|
|
30
|
+
role: 'system',
|
|
31
|
+
content: options.systemPrompt || 'Du bist ein hilfreicher WhatsApp Bot Assistent. Antworte kurz und freundlich auf Deutsch.'
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
role: 'user',
|
|
35
|
+
content: prompt
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
max_tokens: options.maxTokens || 500,
|
|
39
|
+
temperature: options.temperature || 0.7
|
|
40
|
+
}, {
|
|
41
|
+
headers: {
|
|
42
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
43
|
+
'Content-Type': 'application/json'
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return response.data.choices[0].message.content.trim();
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error('❌ AI Chat Fehler:', error.response?.data || error.message);
|
|
50
|
+
throw new Error(`AI Fehler: ${error.response?.data?.error?.message || error.message}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ===== SMART RESPONSES =====
|
|
55
|
+
|
|
56
|
+
async smartReply(message, context = {}) {
|
|
57
|
+
const prompt = `
|
|
58
|
+
Kontext: WhatsApp Bot Nachricht
|
|
59
|
+
User schrieb: "${message}"
|
|
60
|
+
Chat-Type: ${context.isGroup ? 'Gruppe' : 'Privat'}
|
|
61
|
+
${context.userName ? `User: ${context.userName}` : ''}
|
|
62
|
+
|
|
63
|
+
Antworte natürlich und hilfreich. Maximal 2 Sätze.
|
|
64
|
+
`.trim();
|
|
65
|
+
|
|
66
|
+
return await this.chat(prompt, {
|
|
67
|
+
systemPrompt: 'Du bist ein freundlicher WhatsApp Bot. Antworte natürlich und kurz.',
|
|
68
|
+
maxTokens: 200
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ===== TEXT ANALYSIS =====
|
|
73
|
+
|
|
74
|
+
async analyzeMessage(text) {
|
|
75
|
+
const prompt = `
|
|
76
|
+
Analysiere diese Nachricht:
|
|
77
|
+
"${text}"
|
|
78
|
+
|
|
79
|
+
Gib zurück als JSON:
|
|
80
|
+
{
|
|
81
|
+
"sentiment": "positive/negative/neutral",
|
|
82
|
+
"language": "de/en/es/fr/etc",
|
|
83
|
+
"category": "question/command/greeting/complaint/other",
|
|
84
|
+
"toxicity": "low/medium/high",
|
|
85
|
+
"confidence": 0.0-1.0
|
|
86
|
+
}
|
|
87
|
+
`.trim();
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const response = await this.chat(prompt, {
|
|
91
|
+
systemPrompt: 'Du bist ein Text-Analyse-Experte. Antworte nur mit gültigem JSON.',
|
|
92
|
+
maxTokens: 150
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return JSON.parse(response);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
sentiment: 'neutral',
|
|
99
|
+
language: 'unknown',
|
|
100
|
+
category: 'other',
|
|
101
|
+
toxicity: 'low',
|
|
102
|
+
confidence: 0.5
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ===== MODERATION =====
|
|
108
|
+
|
|
109
|
+
async moderateContent(text) {
|
|
110
|
+
try {
|
|
111
|
+
const response = await axios.post(`${this.baseURL}/moderations`, {
|
|
112
|
+
input: text
|
|
113
|
+
}, {
|
|
114
|
+
headers: {
|
|
115
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
116
|
+
'Content-Type': 'application/json'
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const result = response.data.results[0];
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
flagged: result.flagged,
|
|
124
|
+
categories: result.categories,
|
|
125
|
+
scores: result.category_scores,
|
|
126
|
+
safe: !result.flagged
|
|
127
|
+
};
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error('❌ Moderation Fehler:', error.message);
|
|
130
|
+
return { flagged: false, safe: true };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ===== TRANSLATION =====
|
|
135
|
+
|
|
136
|
+
async translate(text, targetLang = 'de') {
|
|
137
|
+
const prompt = `Übersetze folgenden Text nach ${targetLang}. Antworte nur mit der Übersetzung:\n\n"${text}"`;
|
|
138
|
+
|
|
139
|
+
return await this.chat(prompt, {
|
|
140
|
+
systemPrompt: 'Du bist ein professioneller Übersetzer. Antworte nur mit der Übersetzung.',
|
|
141
|
+
maxTokens: 300
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ===== SUMMARIZATION =====
|
|
146
|
+
|
|
147
|
+
async summarize(text, maxLength = 100) {
|
|
148
|
+
const prompt = `Fasse folgenden Text in maximal ${maxLength} Zeichen zusammen:\n\n"${text}"`;
|
|
149
|
+
|
|
150
|
+
return await this.chat(prompt, {
|
|
151
|
+
systemPrompt: 'Du bist ein Experte für Textzusammenfassungen. Sei präzise und kurz.',
|
|
152
|
+
maxTokens: Math.ceil(maxLength / 2)
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ===== QUESTION ANSWERING =====
|
|
157
|
+
|
|
158
|
+
async answerQuestion(question, context = '') {
|
|
159
|
+
const prompt = context ?
|
|
160
|
+
`Kontext: ${context}\n\nFrage: ${question}` :
|
|
161
|
+
question;
|
|
162
|
+
|
|
163
|
+
return await this.chat(prompt, {
|
|
164
|
+
systemPrompt: 'Du bist ein hilfreicher Assistent. Beantworte Fragen präzise und verständlich.',
|
|
165
|
+
maxTokens: 400
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ===== CREATIVE WRITING =====
|
|
170
|
+
|
|
171
|
+
async generateText(prompt, style = 'normal') {
|
|
172
|
+
const stylePrompts = {
|
|
173
|
+
funny: 'Schreibe lustig und humorvoll',
|
|
174
|
+
formal: 'Schreibe formal und professionell',
|
|
175
|
+
casual: 'Schreibe locker und umgangssprachlich',
|
|
176
|
+
creative: 'Schreibe kreativ und fantasievoll',
|
|
177
|
+
normal: 'Schreibe natürlich und verständlich'
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
return await this.chat(prompt, {
|
|
181
|
+
systemPrompt: `Du bist ein kreativer Schreiber. ${stylePrompts[style] || stylePrompts.normal}.`,
|
|
182
|
+
maxTokens: 600
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
package/src/client.js
CHANGED
|
@@ -4,6 +4,11 @@ import { generateQRCode, closeBrowser } from "./qr.js";
|
|
|
4
4
|
import { Message } from "./message.js";
|
|
5
5
|
import { SessionManager } from "./session-manager.js";
|
|
6
6
|
import { PrefixManager } from "./prefix-manager.js";
|
|
7
|
+
import { getStorage } from "./storage.js";
|
|
8
|
+
import { AIIntegration } from "./ai-integration.js";
|
|
9
|
+
import { HTTPClient } from "./http-client.js";
|
|
10
|
+
import { Scheduler } from "./scheduler.js";
|
|
11
|
+
import { PluginManager } from "./plugin-manager-fixed.js";
|
|
7
12
|
|
|
8
13
|
export class WhatsAppClient {
|
|
9
14
|
constructor(options = {}) {
|
|
@@ -30,6 +35,38 @@ export class WhatsAppClient {
|
|
|
30
35
|
this.prefixManager = new PrefixManager('./data');
|
|
31
36
|
this.commands = new Map();
|
|
32
37
|
|
|
38
|
+
// Storage System
|
|
39
|
+
this.storage = getStorage();
|
|
40
|
+
|
|
41
|
+
// AI Integration
|
|
42
|
+
this.ai = new AIIntegration(options.ai || {});
|
|
43
|
+
|
|
44
|
+
// HTTP Client
|
|
45
|
+
this.http = new HTTPClient(options.http || {});
|
|
46
|
+
|
|
47
|
+
// Scheduler System
|
|
48
|
+
this.scheduler = new Scheduler(this);
|
|
49
|
+
|
|
50
|
+
// Waiting System für Messages
|
|
51
|
+
this.waiting = this.scheduler.createWaiting();
|
|
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
|
+
|
|
33
70
|
// Deine eigenen API-Objekte
|
|
34
71
|
this.get = new GetAPI(this);
|
|
35
72
|
this.add = new AddAPI(this);
|
|
@@ -172,6 +209,10 @@ export class WhatsAppClient {
|
|
|
172
209
|
this.isConnected = true;
|
|
173
210
|
await closeBrowser(); // QR Browser schließen
|
|
174
211
|
this.emit('connected');
|
|
212
|
+
|
|
213
|
+
// 🔌 Plugins werden NICHT automatisch geladen
|
|
214
|
+
// Verwende client.load.Plugins("plugin-name") um Plugins zu laden
|
|
215
|
+
|
|
175
216
|
resolve(this);
|
|
176
217
|
}
|
|
177
218
|
});
|