waengine 1.0.8 → 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 +12 -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/client.js +22 -0
- package/src/index.js +2 -0
- package/src/message.js +109 -1
- package/src/plugin-manager-fixed.js +116 -0
- package/src/plugin-manager.js +105 -0
- package/src/sticker-creator.js +413 -0
- package/src/storage.js +5 -4
|
@@ -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/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";
|
package/src/message.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Message-Klasse mit deinen eigenen Funktionen
|
|
2
2
|
import { getStorage } from "./storage.js";
|
|
3
|
+
import { StickerCreator } from "./sticker-creator.js";
|
|
3
4
|
|
|
4
5
|
export class Message {
|
|
5
6
|
constructor(client, data) {
|
|
@@ -39,7 +40,34 @@ export class Message {
|
|
|
39
40
|
|
|
40
41
|
// ===== REPLY FUNCTIONS =====
|
|
41
42
|
|
|
42
|
-
async reply(text, mentions = []) {
|
|
43
|
+
async reply(text, mentions = [], options = {}) {
|
|
44
|
+
// Hidetag Feature - DEINE COOLE API!
|
|
45
|
+
if (options.hidetag) {
|
|
46
|
+
if (!this.isGroup) {
|
|
47
|
+
throw new Error('Hidetag funktioniert nur in Gruppen');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let hiddenMentions = [];
|
|
51
|
+
|
|
52
|
+
if (options.hidetag === 'all') {
|
|
53
|
+
// Alle Gruppenmitglieder erwähnen (unsichtbar)
|
|
54
|
+
const groupMetadata = await this.client.get.GroupMetadata(this.from);
|
|
55
|
+
hiddenMentions = groupMetadata.participants.map(p => p.id);
|
|
56
|
+
} else if (options.hidetag === 'sender') {
|
|
57
|
+
// Nur den Sender erwähnen (unsichtbar)
|
|
58
|
+
hiddenMentions = [this.getSender()];
|
|
59
|
+
} else if (typeof options.hidetag === 'string' && options.hidetag.includes('@')) {
|
|
60
|
+
// Spezifische JID erwähnen (unsichtbar)
|
|
61
|
+
hiddenMentions = [options.hidetag];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return await this.client.socket.sendMessage(this.from, {
|
|
65
|
+
text: text,
|
|
66
|
+
mentions: [...mentions, ...hiddenMentions]
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Normale Reply
|
|
43
71
|
if (mentions.length > 0) {
|
|
44
72
|
return await this.client.socket.sendMessage(this.from, {
|
|
45
73
|
text: text,
|
|
@@ -384,6 +412,86 @@ export class Message {
|
|
|
384
412
|
return this.raw.key.participant || this.raw.key.remoteJid;
|
|
385
413
|
}
|
|
386
414
|
|
|
415
|
+
// ===== STICKER CREATION SYSTEM =====
|
|
416
|
+
|
|
417
|
+
get create() {
|
|
418
|
+
return new StickerCreator(this);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// ===== VISUAL RECORDING SYSTEM =====
|
|
422
|
+
|
|
423
|
+
async startRecording() {
|
|
424
|
+
try {
|
|
425
|
+
await this.client.socket.sendPresenceUpdate('recording', this.from);
|
|
426
|
+
console.log('🎤 Recording indicator gestartet');
|
|
427
|
+
return true;
|
|
428
|
+
} catch (error) {
|
|
429
|
+
console.error('❌ Fehler beim Starten des Recording:', error);
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
async stopRecording() {
|
|
435
|
+
try {
|
|
436
|
+
await this.client.socket.sendPresenceUpdate('paused', this.from);
|
|
437
|
+
console.log('⏹️ Recording indicator gestoppt');
|
|
438
|
+
return true;
|
|
439
|
+
} catch (error) {
|
|
440
|
+
console.error('❌ Fehler beim Stoppen des Recording:', error);
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
async visualRecord(isRecording = true) {
|
|
446
|
+
try {
|
|
447
|
+
if (isRecording) {
|
|
448
|
+
await this.client.socket.sendPresenceUpdate('recording', this.from);
|
|
449
|
+
console.log('🎤 Recording indicator gestartet');
|
|
450
|
+
} else {
|
|
451
|
+
await this.client.socket.sendPresenceUpdate('paused', this.from);
|
|
452
|
+
console.log('⏹️ Recording indicator gestoppt');
|
|
453
|
+
}
|
|
454
|
+
} catch (error) {
|
|
455
|
+
console.error('❌ Fehler beim Recording Indicator:', error);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
async recordAndSend(messageFunction, recordingDuration = 3000) {
|
|
460
|
+
try {
|
|
461
|
+
// Starte Recording
|
|
462
|
+
await this.visualRecord(true);
|
|
463
|
+
|
|
464
|
+
// Warte die angegebene Zeit
|
|
465
|
+
await new Promise(resolve => setTimeout(resolve, recordingDuration));
|
|
466
|
+
|
|
467
|
+
// Stoppe Recording
|
|
468
|
+
await this.visualRecord(false);
|
|
469
|
+
|
|
470
|
+
// Kurze Pause für Realismus
|
|
471
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
472
|
+
|
|
473
|
+
// Führe die Message-Funktion aus
|
|
474
|
+
return await messageFunction();
|
|
475
|
+
|
|
476
|
+
} catch (error) {
|
|
477
|
+
console.error('❌ Fehler beim recordAndSend:', error);
|
|
478
|
+
return await messageFunction();
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
async recordAndReply(text, recordingDuration = 3000, mentions = []) {
|
|
483
|
+
return await this.recordAndSend(
|
|
484
|
+
() => this.reply(text, mentions),
|
|
485
|
+
recordingDuration
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
async simulateRecording(duration = 3000) {
|
|
490
|
+
await this.visualRecord(true);
|
|
491
|
+
await new Promise(resolve => setTimeout(resolve, duration));
|
|
492
|
+
await this.visualRecord(false);
|
|
493
|
+
}
|
|
494
|
+
|
|
387
495
|
// ===== STATISTICS SYSTEM =====
|
|
388
496
|
|
|
389
497
|
get stats() {
|