waengine 1.0.1

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/src/client.js ADDED
@@ -0,0 +1,412 @@
1
+ import makeWASocket, { useMultiFileAuthState, DisconnectReason } from "@whiskeysockets/baileys";
2
+ import pino from "pino";
3
+ import { generateQRCode, closeBrowser } from "./qr.js";
4
+ import { Message } from "./message.js";
5
+
6
+ export class WhatsAppClient {
7
+ constructor(options = {}) {
8
+ this.options = {
9
+ authDir: "./auth",
10
+ printQR: false,
11
+ browser: options.browser || ["MyLibrary", "1.0.0", ""],
12
+ logLevel: options.logLevel || "silent", // Sauber ohne Debug
13
+ ...options
14
+ };
15
+
16
+ this.socket = null;
17
+ this.isConnected = false;
18
+ this.eventHandlers = new Map();
19
+
20
+ // Prefix System
21
+ this.prefix = null;
22
+ this.commands = new Map();
23
+
24
+ // Deine eigenen API-Objekte
25
+ this.get = new GetAPI(this);
26
+ this.add = new AddAPI(this);
27
+ this.kick = new KickAPI(this);
28
+ this.promote = new PromoteAPI(this);
29
+ this.demote = new DemoteAPI(this);
30
+ }
31
+
32
+ // ===== CONNECTION METHODS =====
33
+
34
+ async connect() {
35
+ console.log("🔄 Starte Verbindung...");
36
+
37
+ if (this.socket && this.isConnected) {
38
+ console.log("✅ Bereits verbunden");
39
+ return this.socket;
40
+ }
41
+
42
+ const { state, saveCreds } = await useMultiFileAuthState(this.options.authDir);
43
+ console.log("📁 Auth-Daten geladen");
44
+
45
+ // Prüfen ob bereits eingeloggt
46
+ const isLoggedIn = !!state.creds?.me?.id;
47
+ console.log(`🔐 Login-Status: ${isLoggedIn ? 'Eingeloggt' : 'Nicht eingeloggt'}`);
48
+
49
+ this.socket = makeWASocket({
50
+ auth: state,
51
+ printQRInTerminal: this.options.printQR,
52
+ logger: pino({ level: this.options.logLevel }),
53
+ browser: this.options.browser
54
+ });
55
+
56
+ console.log("🔌 Socket erstellt");
57
+
58
+ // QR-Code Browser nur öffnen wenn nicht eingeloggt
59
+ if (!this.options.printQR && !isLoggedIn) {
60
+ console.log("🌐 Öffne Browser für QR-Code...");
61
+ await generateQRCode();
62
+ } else if (isLoggedIn) {
63
+ console.log("✅ Bereits authentifiziert, verbinde direkt...");
64
+ }
65
+
66
+ return new Promise((resolve, reject) => {
67
+ this.socket.ev.on("connection.update", async ({ connection, lastDisconnect, qr }) => {
68
+ console.log(`🔄 Connection Status: ${connection}`);
69
+
70
+ if (qr && !this.options.printQR && !isLoggedIn) {
71
+ console.log("📱 QR Code empfangen, zeige im Browser...");
72
+ await generateQRCode(qr);
73
+ }
74
+
75
+ if (connection === "connecting") {
76
+ console.log("🔄 Verbinde mit WhatsApp...");
77
+ }
78
+
79
+ if (connection === "close") {
80
+ console.log("🔴 Verbindung geschlossen");
81
+ const shouldReconnect = lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut;
82
+
83
+ if (shouldReconnect) {
84
+ console.log("🔄 Wiederverbindung...");
85
+ this.isConnected = false;
86
+ this.socket = null;
87
+ setTimeout(() => this.connect().then(resolve).catch(reject), 3000);
88
+ } else {
89
+ console.log("👋 Ausgeloggt - QR-Code wird beim nächsten Start benötigt");
90
+ await closeBrowser();
91
+ this.emit('disconnected', { reason: 'logged_out' });
92
+ }
93
+ } else if (connection === "open") {
94
+ console.log("✅ WhatsApp erfolgreich verbunden!");
95
+ this.isConnected = true;
96
+ this.setupEventHandlers();
97
+ this.emit('connected');
98
+ resolve(this);
99
+ }
100
+ });
101
+
102
+ this.socket.ev.on("creds.update", saveCreds);
103
+
104
+ setTimeout(() => {
105
+ if (!this.isConnected) {
106
+ console.log("⏰ Verbindungs-Timeout");
107
+ reject(new Error("Connection timeout"));
108
+ }
109
+ }, 60000);
110
+ });
111
+ }
112
+
113
+ async disconnect() {
114
+ if (this.socket) {
115
+ this.socket.end();
116
+ this.socket = null;
117
+ this.isConnected = false;
118
+ await closeBrowser();
119
+ this.emit('disconnected', { reason: 'manual' });
120
+ }
121
+ }
122
+
123
+ // ===== EVENT SYSTEM =====
124
+
125
+ on(event, handler) {
126
+ if (!this.eventHandlers.has(event)) {
127
+ this.eventHandlers.set(event, []);
128
+ }
129
+ this.eventHandlers.get(event).push(handler);
130
+ return this;
131
+ }
132
+
133
+ off(event, handler) {
134
+ if (this.eventHandlers.has(event)) {
135
+ const handlers = this.eventHandlers.get(event);
136
+ const index = handlers.indexOf(handler);
137
+ if (index > -1) {
138
+ handlers.splice(index, 1);
139
+ }
140
+ }
141
+ return this;
142
+ }
143
+
144
+ emit(event, data) {
145
+ if (this.eventHandlers.has(event)) {
146
+ this.eventHandlers.get(event).forEach(handler => {
147
+ try {
148
+ handler(data);
149
+ } catch (error) {
150
+ console.error(`❌ Error in event handler for '${event}':`, error);
151
+ }
152
+ });
153
+ }
154
+ }
155
+
156
+ setupEventHandlers() {
157
+ // Messages - Sauber ohne Debug-Spam
158
+ this.socket.ev.on("messages.upsert", ({ messages, type }) => {
159
+ if (type !== "notify") return;
160
+
161
+ messages.forEach(msg => {
162
+ if (!msg.message || msg.key.fromMe) return;
163
+
164
+ const messageData = this.parseMessage(msg);
165
+ const messageObj = new Message(this, messageData);
166
+
167
+ // Prefix System - Command Check
168
+ if (this.prefix && messageData.text && messageData.text.startsWith(this.prefix)) {
169
+ const commandText = messageData.text.slice(this.prefix.length).trim();
170
+ const [command, ...args] = commandText.split(' ');
171
+
172
+ messageObj.isCommand = true;
173
+ messageObj.command = command.toLowerCase();
174
+ messageObj.args = args;
175
+ messageObj.commandText = commandText;
176
+
177
+ // Command Event emittieren
178
+ this.emit('command', messageObj);
179
+
180
+ // Spezifischen Command Handler aufrufen falls vorhanden
181
+ if (this.commands.has(command.toLowerCase())) {
182
+ const handler = this.commands.get(command.toLowerCase());
183
+ try {
184
+ handler(messageObj, args);
185
+ } catch (error) {
186
+ console.error(`❌ Fehler in Command '${command}':`, error);
187
+ }
188
+ }
189
+ } else {
190
+ messageObj.isCommand = false;
191
+ messageObj.command = null;
192
+ messageObj.args = [];
193
+ }
194
+
195
+ this.emit('message', messageObj);
196
+ });
197
+ });
198
+
199
+ // Group updates
200
+ this.socket.ev.on("group-participants.update", (update) => {
201
+ this.emit('group.participants.update', update);
202
+ });
203
+
204
+ // Presence updates
205
+ this.socket.ev.on("presence.update", (update) => {
206
+ this.emit('presence.update', update);
207
+ });
208
+ }
209
+
210
+ parseMessage(msg) {
211
+ const text =
212
+ msg.message.conversation ||
213
+ msg.message.extendedTextMessage?.text ||
214
+ msg.message.imageMessage?.caption ||
215
+ msg.message.videoMessage?.caption ||
216
+ null;
217
+
218
+ return {
219
+ id: msg.key.id,
220
+ from: msg.key.remoteJid,
221
+ fromMe: msg.key.fromMe,
222
+ text: text,
223
+ timestamp: msg.messageTimestamp,
224
+ type: this.getMessageType(msg.message),
225
+ isGroup: msg.key.remoteJid?.includes("@g.us"),
226
+ raw: msg
227
+ };
228
+ }
229
+
230
+ getMessageType(message) {
231
+ if (message.conversation) return 'text';
232
+ if (message.imageMessage) return 'image';
233
+ if (message.videoMessage) return 'video';
234
+ if (message.audioMessage) return 'audio';
235
+ if (message.documentMessage) return 'document';
236
+ if (message.stickerMessage) return 'sticker';
237
+ if (message.locationMessage) return 'location';
238
+ if (message.contactMessage) return 'contact';
239
+ return 'unknown';
240
+ }
241
+
242
+ getConnectionState() {
243
+ return {
244
+ isConnected: this.isConnected,
245
+ socket: !!this.socket
246
+ };
247
+ }
248
+
249
+ // ===== PREFIX SYSTEM =====
250
+
251
+ setPrefix(prefix) {
252
+ this.prefix = prefix;
253
+ console.log(`🎯 Prefix gesetzt auf: "${prefix}"`);
254
+ return this;
255
+ }
256
+
257
+ getPrefix() {
258
+ return this.prefix;
259
+ }
260
+
261
+ addCommand(command, handler) {
262
+ this.commands.set(command.toLowerCase(), handler);
263
+ console.log(`⚡ Command registriert: ${this.prefix || ''}${command}`);
264
+ return this;
265
+ }
266
+
267
+ removeCommand(command) {
268
+ const removed = this.commands.delete(command.toLowerCase());
269
+ if (removed) {
270
+ console.log(`🗑️ Command entfernt: ${command}`);
271
+ }
272
+ return this;
273
+ }
274
+
275
+ getCommands() {
276
+ return Array.from(this.commands.keys());
277
+ }
278
+
279
+ // ===== PRESENCE SYSTEM =====
280
+
281
+ async setPresence(presence, chatId = null) {
282
+ try {
283
+ await this.socket.sendPresenceUpdate(presence, chatId);
284
+ return true;
285
+ } catch (error) {
286
+ console.error(`❌ Fehler beim Setzen der Presence '${presence}':`, error);
287
+ return false;
288
+ }
289
+ }
290
+
291
+ async setOnline() {
292
+ return await this.setPresence('available');
293
+ }
294
+
295
+ async setOffline() {
296
+ return await this.setPresence('unavailable');
297
+ }
298
+
299
+ async setTyping(chatId) {
300
+ return await this.setPresence('composing', chatId);
301
+ }
302
+
303
+ async setRecording(chatId) {
304
+ return await this.setPresence('recording', chatId);
305
+ }
306
+
307
+ async setPaused(chatId) {
308
+ return await this.setPresence('paused', chatId);
309
+ }
310
+ }
311
+
312
+ // ===== DEINE API-KLASSEN =====
313
+
314
+ class GetAPI {
315
+ constructor(client) {
316
+ this.client = client;
317
+ }
318
+
319
+ async GroupMetadata(groupId) {
320
+ return await this.client.socket.groupMetadata(groupId);
321
+ }
322
+
323
+ async GroupParticipants(groupId) {
324
+ const metadata = await this.GroupMetadata(groupId);
325
+ return metadata.participants;
326
+ }
327
+
328
+ async GroupAdmins(groupId) {
329
+ const participants = await this.GroupParticipants(groupId);
330
+ return participants.filter(p => p.admin === 'admin' || p.admin === 'superadmin');
331
+ }
332
+ }
333
+
334
+ class AddAPI {
335
+ constructor(client) {
336
+ this.client = client;
337
+ }
338
+
339
+ async user(groupId, users, mentions = []) {
340
+ const result = await this.client.socket.groupParticipantsUpdate(groupId, users, 'add');
341
+
342
+ if (mentions.length > 0) {
343
+ const welcomeText = `Willkommen! ${mentions.map(id => `@${id.split('@')[0]}`).join(' ')}`;
344
+ await this.client.socket.sendMessage(groupId, {
345
+ text: welcomeText,
346
+ mentions: mentions
347
+ });
348
+ }
349
+
350
+ return result;
351
+ }
352
+ }
353
+
354
+ class KickAPI {
355
+ constructor(client) {
356
+ this.client = client;
357
+ }
358
+
359
+ async user(groupId, users, mentions = []) {
360
+ const result = await this.client.socket.groupParticipantsUpdate(groupId, users, 'remove');
361
+
362
+ if (mentions.length > 0) {
363
+ const kickText = `${mentions.map(id => `@${id.split('@')[0]}`).join(' ')} wurde entfernt.`;
364
+ await this.client.socket.sendMessage(groupId, {
365
+ text: kickText,
366
+ mentions: mentions
367
+ });
368
+ }
369
+
370
+ return result;
371
+ }
372
+ }
373
+
374
+ class PromoteAPI {
375
+ constructor(client) {
376
+ this.client = client;
377
+ }
378
+
379
+ async user(groupId, users, mentions = []) {
380
+ const result = await this.client.socket.groupParticipantsUpdate(groupId, users, 'promote');
381
+
382
+ if (mentions.length > 0) {
383
+ const promoteText = `🎉 ${mentions.map(id => `@${id.split('@')[0]}`).join(' ')} ist jetzt Admin!`;
384
+ await this.client.socket.sendMessage(groupId, {
385
+ text: promoteText,
386
+ mentions: mentions
387
+ });
388
+ }
389
+
390
+ return result;
391
+ }
392
+ }
393
+
394
+ class DemoteAPI {
395
+ constructor(client) {
396
+ this.client = client;
397
+ }
398
+
399
+ async user(groupId, users, mentions = []) {
400
+ const result = await this.client.socket.groupParticipantsUpdate(groupId, users, 'demote');
401
+
402
+ if (mentions.length > 0) {
403
+ const demoteText = `${mentions.map(id => `@${id.split('@')[0]}`).join(' ')} ist nicht mehr Admin.`;
404
+ await this.client.socket.sendMessage(groupId, {
405
+ text: demoteText,
406
+ mentions: mentions
407
+ });
408
+ }
409
+
410
+ return result;
411
+ }
412
+ }
package/src/core.js ADDED
@@ -0,0 +1,79 @@
1
+ import makeWASocket, { useMultiFileAuthState, DisconnectReason } from "@whiskeysockets/baileys";
2
+ import pino from "pino";
3
+ import { generateQRCode, closeBrowser } from "./qr.js";
4
+
5
+ let socket = null;
6
+ let isConnected = false;
7
+
8
+ export async function getSocket() {
9
+ if (socket && isConnected) return socket;
10
+
11
+ const { state, saveCreds } = await useMultiFileAuthState("./auth");
12
+
13
+ socket = makeWASocket({
14
+ auth: state,
15
+ printQRInTerminal: false,
16
+ logger: pino({ level: "debug" }), // Debug-Level für mehr Logs
17
+ browser: ["Chrome (Linux)", "", ""]
18
+ });
19
+
20
+ // Browser öffnen für QR-Code
21
+ await generateQRCode();
22
+
23
+ // Connection-Events abwarten
24
+ return new Promise((resolve, reject) => {
25
+ socket.ev.on("connection.update", async ({ connection, lastDisconnect, qr }) => {
26
+ console.log(`🔄 Connection Update: ${connection}`);
27
+
28
+ if (qr) {
29
+ console.log("📱 QR-Code generiert - wird im Edge Browser angezeigt!");
30
+ await generateQRCode(qr);
31
+ }
32
+
33
+ if (connection === "close") {
34
+ const shouldReconnect = lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut;
35
+ console.log("🔴 Verbindung geschlossen:", lastDisconnect?.error);
36
+
37
+ if (shouldReconnect) {
38
+ console.log("🔄 Versuche Wiederverbindung...");
39
+ isConnected = false;
40
+ socket = null;
41
+ getSocket().then(resolve).catch(reject);
42
+ } else {
43
+ await closeBrowser();
44
+ }
45
+ } else if (connection === "open") {
46
+ console.log("✅ Erfolgreich mit WhatsApp verbunden!");
47
+ console.log("🎉 Du kannst jetzt den Browser schließen oder offen lassen");
48
+ isConnected = true;
49
+
50
+ // Test: Alle Event-Listener anzeigen
51
+ console.log("🎧 Registrierte Events:", Object.keys(socket.ev.listenerCount));
52
+
53
+ resolve(socket);
54
+ }
55
+ });
56
+
57
+ socket.ev.on("creds.update", saveCreds);
58
+
59
+ // WICHTIG: Alle Events loggen für Debug
60
+ socket.ev.on("messages.upsert", (data) => {
61
+ console.log("🚨 RAW MESSAGE EVENT:", JSON.stringify(data, null, 2));
62
+ });
63
+
64
+ socket.ev.on("chats.set", (data) => {
65
+ console.log("💬 Chats Set Event:", data.length, "chats");
66
+ });
67
+
68
+ socket.ev.on("contacts.set", (data) => {
69
+ console.log("👥 Contacts Set Event:", data.length, "contacts");
70
+ });
71
+
72
+ // Timeout nach 60 Sekunden
73
+ setTimeout(() => {
74
+ if (!isConnected) {
75
+ reject(new Error("Connection timeout - QR-Code im Browser nicht gescannt?"));
76
+ }
77
+ }, 60000);
78
+ });
79
+ }