waengine 2.4.9 → 2.5.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/FEATURES.md +69 -0
- package/README.md +9 -2
- package/package.json +1 -1
- package/src/client.js +131 -2
- package/src/connection-recovery.js +27 -13
- package/src/message.js +94 -0
package/FEATURES.md
CHANGED
|
@@ -4832,6 +4832,75 @@ bot.when('check @user online').checkOnline().done(); // Online-Status von Mentio
|
|
|
4832
4832
|
|
|
4833
4833
|
---
|
|
4834
4834
|
|
|
4835
|
+
## Sonstiges
|
|
4836
|
+
|
|
4837
|
+
- **`msg.sendPTV(path)`** — send round video bubble (PTV)
|
|
4838
|
+
```js
|
|
4839
|
+
await msg.sendPTV('./video.mp4');
|
|
4840
|
+
```
|
|
4841
|
+
- **`msg.sendAll(text)`** — native @everyone mention in groups
|
|
4842
|
+
```js
|
|
4843
|
+
await msg.sendAll('Hey everyone!');
|
|
4844
|
+
```
|
|
4845
|
+
- **`msg.sendViewOnce(path, type)`** — view-once image, video or audio
|
|
4846
|
+
```js
|
|
4847
|
+
await msg.sendViewOnce('./img.jpg', 'image');
|
|
4848
|
+
await msg.sendViewOnce('./clip.mp4', 'video');
|
|
4849
|
+
await msg.sendViewOnce('./voice.ogg', 'audio');
|
|
4850
|
+
```
|
|
4851
|
+
- **`msg.remReact()`** — remove your reaction from a message
|
|
4852
|
+
```js
|
|
4853
|
+
await msg.remReact();
|
|
4854
|
+
```
|
|
4855
|
+
|
|
4856
|
+
- **`msg.isReply`** / **`msg.quotedMessage`** — detect & read replied messages
|
|
4857
|
+
```js
|
|
4858
|
+
if (msg.isReply) console.log(msg.quotedMessage.text);
|
|
4859
|
+
```
|
|
4860
|
+
- **`msg.isForwarded`** / **`msg.forwardingScore`** — detect forwarded messages
|
|
4861
|
+
```js
|
|
4862
|
+
if (msg.isForwarded) console.log('Forwarded', msg.forwardingScore, 'times');
|
|
4863
|
+
```
|
|
4864
|
+
- **`msg.isMedia`** / **`msg.mediaType`** — quick media type check
|
|
4865
|
+
```js
|
|
4866
|
+
if (msg.isMedia) console.log(msg.mediaType); // 'image' | 'video' | 'audio' | ...
|
|
4867
|
+
```
|
|
4868
|
+
- **`msg.isEveryoneMention`** — detect incoming @everyone
|
|
4869
|
+
```js
|
|
4870
|
+
if (msg.isEveryoneMention) await msg.reply('Everyone was mentioned!');
|
|
4871
|
+
```
|
|
4872
|
+
|
|
4873
|
+
### ➕ Added — Events
|
|
4874
|
+
- **`reaction`** — someone reacted to a message
|
|
4875
|
+
```js
|
|
4876
|
+
bot.on('reaction', (r) => console.log(r.from, r.emoji, r.removed));
|
|
4877
|
+
```
|
|
4878
|
+
- **`call`** — incoming call detected
|
|
4879
|
+
```js
|
|
4880
|
+
bot.on('call', (call) => console.log(call.from, call.isVideo, call.status));
|
|
4881
|
+
```
|
|
4882
|
+
- **`typing`** — someone is typing
|
|
4883
|
+
```js
|
|
4884
|
+
bot.on('typing', ({ from, isTyping }) => console.log(from, isTyping));
|
|
4885
|
+
```
|
|
4886
|
+
- **`recording`** — someone is recording audio
|
|
4887
|
+
```js
|
|
4888
|
+
bot.on('recording', ({ from }) => console.log(from + ' is recording...'));
|
|
4889
|
+
```
|
|
4890
|
+
- **`message.delete`** — a message was deleted
|
|
4891
|
+
```js
|
|
4892
|
+
bot.on('message.delete', (item) => console.log('deleted:', item));
|
|
4893
|
+
```
|
|
4894
|
+
- **`group.update`** — group name/description changed
|
|
4895
|
+
```js
|
|
4896
|
+
bot.on('group.update', (u) => console.log(u.subject, u.desc));
|
|
4897
|
+
```
|
|
4898
|
+
- **`labels.association`** / **`labels.edit`** — WhatsApp Business label events
|
|
4899
|
+
```js
|
|
4900
|
+
bot.on('labels.association', (a) => console.log(a));
|
|
4901
|
+
bot.on('labels.edit', (l) => console.log(l));
|
|
4902
|
+
```
|
|
4903
|
+
|
|
4835
4904
|
*Made with ❤️ for WhatsApp Automation*
|
|
4836
4905
|
|
|
4837
4906
|
**Die mächtigste WhatsApp Bot Library - von 3-Zeilen-Bots bis zu KI-gestützten Enterprise Multi-Device Systemen mit vollständigem Plugin-Ecosystem (8 Plugins, 80+ Commands), 800+ Advanced Features in 16 Kategorien, Security Manager, Gaming Manager, Database Manager, A/B Testing, Reporting System, Cross-Platform Integration, UI Components, Hidetag, Sticker Creation, Visual Recording, Rich Content (Buttons, Lists, Carousels), Business Features, Privacy & Security, Analytics & Monitoring und Profile Picture API!**
|
package/README.md
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
# 🚀 WAEngine
|
|
1
|
+
# 🚀 WAEngine v2.5.1 - Fixed Retry Logic
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## 🆕 What's new in v2.5.0
|
|
6
|
+
|
|
7
|
+
### 🔧 Fixed
|
|
8
|
+
- **Connection recovery** — bot now retries every 5s indefinitely until internet is restored (no more "Recovery already in progress" deadlock)
|
|
2
9
|
|
|
3
10
|
[](https://www.npmjs.com/package/waengine)
|
|
4
11
|
[](https://www.npmjs.com/package/waengine)
|
|
@@ -1569,6 +1576,6 @@ console.log('Most Common:', stats.mostCommonError);
|
|
|
1569
1576
|
console.log('By Code:', stats.errorsByCode);
|
|
1570
1577
|
```
|
|
1571
1578
|
|
|
1572
|
-
**📖 Full Documentation:** [
|
|
1579
|
+
**📖 Full Documentation:** [FEATURES.md](./FEATURES.md)
|
|
1573
1580
|
|
|
1574
1581
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "waengine",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"description": "🚀 WAEngine - The most powerful WhatsApp Bot Library with 860+ Working Features, Complete Baileys Integration & Production-Ready Stability",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
package/src/client.js
CHANGED
|
@@ -1141,6 +1141,32 @@ export class WhatsAppClient {
|
|
|
1141
1141
|
|
|
1142
1142
|
this.socket.ev.on("presence.update", (update) => {
|
|
1143
1143
|
this.emit('presence.update', update);
|
|
1144
|
+
|
|
1145
|
+
// Tippen / Aufnehmen erkennen - sauber extrahiert
|
|
1146
|
+
if (update.presences) {
|
|
1147
|
+
Object.entries(update.presences).forEach(([jid, presence]) => {
|
|
1148
|
+
if (presence.lastKnownPresence === 'composing') {
|
|
1149
|
+
this.emit('typing', {
|
|
1150
|
+
from: jid,
|
|
1151
|
+
chat: update.id,
|
|
1152
|
+
isTyping: true
|
|
1153
|
+
});
|
|
1154
|
+
} else if (presence.lastKnownPresence === 'recording') {
|
|
1155
|
+
this.emit('recording', {
|
|
1156
|
+
from: jid,
|
|
1157
|
+
chat: update.id,
|
|
1158
|
+
isRecording: true
|
|
1159
|
+
});
|
|
1160
|
+
} else if (presence.lastKnownPresence === 'paused') {
|
|
1161
|
+
// Hat aufgehört zu tippen
|
|
1162
|
+
this.emit('typing', {
|
|
1163
|
+
from: jid,
|
|
1164
|
+
chat: update.id,
|
|
1165
|
+
isTyping: false
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
});
|
|
1169
|
+
}
|
|
1144
1170
|
});
|
|
1145
1171
|
|
|
1146
1172
|
this.socket.ev.on("group-participants.update", (update) => {
|
|
@@ -1154,6 +1180,67 @@ export class WhatsAppClient {
|
|
|
1154
1180
|
this.socket.ev.on("contacts.upsert", (contacts) => {
|
|
1155
1181
|
this.emit('contacts.upsert', contacts);
|
|
1156
1182
|
});
|
|
1183
|
+
|
|
1184
|
+
// Reaktionen auf Nachrichten erkennen
|
|
1185
|
+
this.socket.ev.on("messages.upsert", ({ messages }) => {
|
|
1186
|
+
messages.forEach(msg => {
|
|
1187
|
+
if (msg.message?.reactionMessage) {
|
|
1188
|
+
const reaction = msg.message.reactionMessage;
|
|
1189
|
+
this.emit('reaction', {
|
|
1190
|
+
from: msg.key.participant || msg.key.remoteJid,
|
|
1191
|
+
chat: msg.key.remoteJid,
|
|
1192
|
+
messageId: reaction.key?.id,
|
|
1193
|
+
emoji: reaction.text, // leer = Reaktion entfernt
|
|
1194
|
+
removed: reaction.text === '',
|
|
1195
|
+
timestamp: msg.messageTimestamp,
|
|
1196
|
+
raw: msg
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
});
|
|
1200
|
+
});
|
|
1201
|
+
|
|
1202
|
+
// Eingehende Anrufe erkennen
|
|
1203
|
+
this.socket.ev.on("call", (calls) => {
|
|
1204
|
+
calls.forEach(call => {
|
|
1205
|
+
this.emit('call', {
|
|
1206
|
+
id: call.id,
|
|
1207
|
+
from: call.chatId,
|
|
1208
|
+
isVideo: call.isVideo,
|
|
1209
|
+
isGroup: call.isGroup,
|
|
1210
|
+
status: call.status, // 'offer' | 'ringing' | 'accept' | 'timeout' | 'reject'
|
|
1211
|
+
timestamp: call.date,
|
|
1212
|
+
raw: call
|
|
1213
|
+
});
|
|
1214
|
+
});
|
|
1215
|
+
});
|
|
1216
|
+
|
|
1217
|
+
// Nachrichten gelöscht erkennen
|
|
1218
|
+
this.socket.ev.on("messages.delete", (item) => {
|
|
1219
|
+
this.emit('message.delete', item);
|
|
1220
|
+
});
|
|
1221
|
+
|
|
1222
|
+
// Gruppen-Info geändert (Name, Beschreibung, Bild)
|
|
1223
|
+
this.socket.ev.on("groups.update", (updates) => {
|
|
1224
|
+
updates.forEach(update => {
|
|
1225
|
+
this.emit('group.update', {
|
|
1226
|
+
id: update.id,
|
|
1227
|
+
subject: update.subject, // neuer Gruppenname
|
|
1228
|
+
desc: update.desc, // neue Beschreibung
|
|
1229
|
+
announce: update.announce, // nur Admins können schreiben
|
|
1230
|
+
restrict: update.restrict,
|
|
1231
|
+
raw: update
|
|
1232
|
+
});
|
|
1233
|
+
});
|
|
1234
|
+
});
|
|
1235
|
+
|
|
1236
|
+
// WhatsApp Business Labels
|
|
1237
|
+
this.socket.ev.on("labels.association", (association) => {
|
|
1238
|
+
this.emit('labels.association', association);
|
|
1239
|
+
});
|
|
1240
|
+
|
|
1241
|
+
this.socket.ev.on("labels.edit", (label) => {
|
|
1242
|
+
this.emit('labels.edit', label);
|
|
1243
|
+
});
|
|
1157
1244
|
}
|
|
1158
1245
|
|
|
1159
1246
|
parseMessage(msg) {
|
|
@@ -1178,15 +1265,57 @@ export class WhatsAppClient {
|
|
|
1178
1265
|
text = msg.message.templateButtonReplyMessage.selectedId;
|
|
1179
1266
|
}
|
|
1180
1267
|
|
|
1268
|
+
// @everyone / @all Erkennung (neue Baileys-Funktion)
|
|
1269
|
+
const mentionedJids = msg.message?.extendedTextMessage?.contextInfo?.mentionedJid || [];
|
|
1270
|
+
const isEveryoneMention = mentionedJids.includes('0@s.whatsapp.net') ||
|
|
1271
|
+
msg.message?.extendedTextMessage?.contextInfo?.mentionedJid?.some(j => j === '0@s.whatsapp.net') ||
|
|
1272
|
+
text?.includes('@everyone') ||
|
|
1273
|
+
text?.includes('@all');
|
|
1274
|
+
|
|
1275
|
+
// Reply / Zitat erkennen
|
|
1276
|
+
const contextInfo = msg.message?.extendedTextMessage?.contextInfo ||
|
|
1277
|
+
msg.message?.imageMessage?.contextInfo ||
|
|
1278
|
+
msg.message?.videoMessage?.contextInfo ||
|
|
1279
|
+
msg.message?.audioMessage?.contextInfo ||
|
|
1280
|
+
msg.message?.documentMessage?.contextInfo ||
|
|
1281
|
+
msg.message?.stickerMessage?.contextInfo || null;
|
|
1282
|
+
|
|
1283
|
+
const isReply = !!(contextInfo?.quotedMessage);
|
|
1284
|
+
const quotedMessage = isReply ? {
|
|
1285
|
+
id: contextInfo.stanzaId,
|
|
1286
|
+
from: contextInfo.participant || contextInfo.remoteJid,
|
|
1287
|
+
message: contextInfo.quotedMessage,
|
|
1288
|
+
text: contextInfo.quotedMessage?.conversation ||
|
|
1289
|
+
contextInfo.quotedMessage?.extendedTextMessage?.text ||
|
|
1290
|
+
contextInfo.quotedMessage?.imageMessage?.caption ||
|
|
1291
|
+
contextInfo.quotedMessage?.videoMessage?.caption || null
|
|
1292
|
+
} : null;
|
|
1293
|
+
|
|
1294
|
+
// Weitergeleitet erkennen
|
|
1295
|
+
const isForwarded = !!(contextInfo?.isForwarded);
|
|
1296
|
+
const forwardingScore = contextInfo?.forwardingScore || 0;
|
|
1297
|
+
|
|
1298
|
+
// Medientyp
|
|
1299
|
+
const mediaTypes = ['image', 'video', 'audio', 'document', 'sticker'];
|
|
1300
|
+
const msgType = this.getMessageType(msg.message);
|
|
1301
|
+
const isMedia = mediaTypes.includes(msgType);
|
|
1302
|
+
|
|
1181
1303
|
return {
|
|
1182
1304
|
id: msg.key.id,
|
|
1183
1305
|
from: msg.key.remoteJid,
|
|
1184
1306
|
fromMe: msg.key.fromMe,
|
|
1185
1307
|
text: text,
|
|
1186
1308
|
timestamp: msg.messageTimestamp,
|
|
1187
|
-
type:
|
|
1309
|
+
type: msgType,
|
|
1188
1310
|
isGroup: msg.key.remoteJid?.includes("@g.us"),
|
|
1189
|
-
participant: msg.key.participant,
|
|
1311
|
+
participant: msg.key.participant,
|
|
1312
|
+
isEveryoneMention,
|
|
1313
|
+
isReply,
|
|
1314
|
+
quotedMessage,
|
|
1315
|
+
isForwarded,
|
|
1316
|
+
forwardingScore,
|
|
1317
|
+
isMedia,
|
|
1318
|
+
mediaType: isMedia ? msgType : null,
|
|
1190
1319
|
raw: msg
|
|
1191
1320
|
};
|
|
1192
1321
|
}
|
|
@@ -107,7 +107,11 @@ export class ConnectionRecovery {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
console.log('⚠️ Health check failed:', error.message);
|
|
110
|
-
|
|
110
|
+
// Fire-and-forget: Recovery läuft unabhängig vom Health-Check-Timer
|
|
111
|
+
this.initiateRecovery(error).catch(e => {
|
|
112
|
+
console.log('🔴 Recovery loop crashed, resetting state:', e?.message || e);
|
|
113
|
+
this.state.isRecovering = false;
|
|
114
|
+
});
|
|
111
115
|
}
|
|
112
116
|
}
|
|
113
117
|
|
|
@@ -121,19 +125,33 @@ export class ConnectionRecovery {
|
|
|
121
125
|
this.state.isRecovering = true;
|
|
122
126
|
this.state.lastError = error;
|
|
123
127
|
this.state.failureHistory.push({
|
|
124
|
-
error: error
|
|
128
|
+
error: error?.message || String(error),
|
|
125
129
|
timestamp: Date.now(),
|
|
126
130
|
retryCount: this.state.retryCount
|
|
127
131
|
});
|
|
128
132
|
|
|
129
133
|
console.log('🛡️ Initiating connection recovery...');
|
|
130
134
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
let attempt = 0;
|
|
136
|
+
|
|
137
|
+
// Endlose Retry-Schleife: läuft so lange bis Verbindung wieder steht
|
|
138
|
+
while (this.state.isRecovering) {
|
|
139
|
+
attempt++;
|
|
140
|
+
console.log(`🔁 Recovery attempt #${attempt}...`);
|
|
141
|
+
try {
|
|
142
|
+
await this.executeRecoveryStrategies();
|
|
143
|
+
// Erfolgreich verbunden
|
|
144
|
+
this.state.isRecovering = false;
|
|
145
|
+
console.log(`✅ Connection restored after ${attempt} attempt(s)`);
|
|
146
|
+
return;
|
|
147
|
+
} catch (recoveryError) {
|
|
148
|
+
const msg = recoveryError?.message || String(recoveryError);
|
|
149
|
+
console.log(`❌ Recovery attempt #${attempt} failed: ${msg}`);
|
|
150
|
+
console.log('🌐 Waiting for internet... retrying in 5s');
|
|
151
|
+
// Retrycount zurücksetzen damit nächste Runde wieder alle Strategien versucht
|
|
152
|
+
this.state.retryCount = 0;
|
|
153
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
154
|
+
}
|
|
137
155
|
}
|
|
138
156
|
}
|
|
139
157
|
|
|
@@ -147,10 +165,6 @@ export class ConnectionRecovery {
|
|
|
147
165
|
];
|
|
148
166
|
|
|
149
167
|
for (const strategy of strategies) {
|
|
150
|
-
if (this.state.retryCount >= this.options.maxRetries) {
|
|
151
|
-
throw new Error('Max retries exceeded');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
168
|
try {
|
|
155
169
|
console.log(`🔧 Trying strategy: ${strategy.name}`);
|
|
156
170
|
await strategy.fn();
|
|
@@ -281,7 +295,7 @@ export class ConnectionRecovery {
|
|
|
281
295
|
console.log('🔄 Recovery state reset');
|
|
282
296
|
}
|
|
283
297
|
|
|
284
|
-
// Cleanup
|
|
298
|
+
// Cleanup - setzt isRecovering auf false, damit die Retry-Schleife stoppt
|
|
285
299
|
cleanup() {
|
|
286
300
|
this.stopHealthMonitoring();
|
|
287
301
|
this.state.isRecovering = false;
|
package/src/message.js
CHANGED
|
@@ -13,6 +13,13 @@ export class Message {
|
|
|
13
13
|
this.timestamp = data.timestamp;
|
|
14
14
|
this.type = data.type;
|
|
15
15
|
this.isGroup = data.isGroup;
|
|
16
|
+
this.isEveryoneMention = data.isEveryoneMention || false;
|
|
17
|
+
this.isReply = data.isReply || false;
|
|
18
|
+
this.quotedMessage = data.quotedMessage || null;
|
|
19
|
+
this.isForwarded = data.isForwarded || false;
|
|
20
|
+
this.forwardingScore = data.forwardingScore || 0;
|
|
21
|
+
this.isMedia = data.isMedia || false;
|
|
22
|
+
this.mediaType = data.mediaType || null;
|
|
16
23
|
this.raw = data.raw;
|
|
17
24
|
|
|
18
25
|
// Command Properties (werden vom Client gesetzt)
|
|
@@ -336,6 +343,38 @@ export class Message {
|
|
|
336
343
|
}
|
|
337
344
|
return results;
|
|
338
345
|
}
|
|
346
|
+
// PTV = Personal/Private To View - runde Video-Bubble im Chat
|
|
347
|
+
async sendPTV(videoSource, mentions = []) {
|
|
348
|
+
try {
|
|
349
|
+
// Unterstützt: Dateipfad (string), URL (string), Buffer, Base64-String
|
|
350
|
+
let videoData;
|
|
351
|
+
if (Buffer.isBuffer(videoSource)) {
|
|
352
|
+
videoData = videoSource;
|
|
353
|
+
} else if (typeof videoSource === 'string' && videoSource.startsWith('data:')) {
|
|
354
|
+
// Base64 data URL: "data:video/mp4;base64,..."
|
|
355
|
+
const base64 = videoSource.split(',')[1];
|
|
356
|
+
videoData = Buffer.from(base64, 'base64');
|
|
357
|
+
} else {
|
|
358
|
+
// Dateipfad oder URL
|
|
359
|
+
videoData = { url: videoSource };
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const message = {
|
|
363
|
+
video: videoData,
|
|
364
|
+
ptv: true,
|
|
365
|
+
mimetype: 'video/mp4'
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
if (mentions.length > 0) {
|
|
369
|
+
message.mentions = mentions;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return await this.client.socket.sendMessage(this.from, message);
|
|
373
|
+
} catch (error) {
|
|
374
|
+
console.error('❌ Fehler beim Senden des PTV:', error);
|
|
375
|
+
throw error;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
339
378
|
|
|
340
379
|
async sendGif(gifPath, caption = "", mentions = []) {
|
|
341
380
|
const message = {
|
|
@@ -951,6 +990,61 @@ export class Message {
|
|
|
951
990
|
return await this.reply(mentionText, allMembers);
|
|
952
991
|
}
|
|
953
992
|
|
|
993
|
+
// @everyone / @all - neue native WhatsApp Funktion (Baileys: mention 0@s.whatsapp.net)
|
|
994
|
+
async sendAll(text) {
|
|
995
|
+
if (!this.isGroup) {
|
|
996
|
+
throw new Error('sendAll funktioniert nur in Gruppen');
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
return await this.client.socket.sendMessage(this.from, {
|
|
1000
|
+
text: text,
|
|
1001
|
+
mentions: ['0@s.whatsapp.net']
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
// Reaktion entfernen
|
|
1006
|
+
async remReact() {
|
|
1007
|
+
return await this.client.socket.sendMessage(this.from, {
|
|
1008
|
+
react: { text: '', key: this.raw.key }
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
// View-Once senden (Bild, Video oder Audio das sich nach einmaligem Ansehen löscht)
|
|
1013
|
+
async sendViewOnce(mediaSource, type = 'image', caption = '') {
|
|
1014
|
+
try {
|
|
1015
|
+
let mediaData;
|
|
1016
|
+
if (Buffer.isBuffer(mediaSource)) {
|
|
1017
|
+
mediaData = mediaSource;
|
|
1018
|
+
} else {
|
|
1019
|
+
mediaData = { url: mediaSource };
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
const message = {};
|
|
1023
|
+
if (type === 'image') {
|
|
1024
|
+
message.image = mediaData;
|
|
1025
|
+
message.caption = caption;
|
|
1026
|
+
message.viewOnce = true;
|
|
1027
|
+
} else if (type === 'video') {
|
|
1028
|
+
message.video = mediaData;
|
|
1029
|
+
message.caption = caption;
|
|
1030
|
+
message.viewOnce = true;
|
|
1031
|
+
message.mimetype = 'video/mp4';
|
|
1032
|
+
} else if (type === 'audio') {
|
|
1033
|
+
message.audio = mediaData;
|
|
1034
|
+
message.viewOnce = true;
|
|
1035
|
+
message.mimetype = 'audio/ogg; codecs=opus';
|
|
1036
|
+
message.ptt = true;
|
|
1037
|
+
} else {
|
|
1038
|
+
throw new Error('sendViewOnce: type muss "image", "video" oder "audio" sein');
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
return await this.client.socket.sendMessage(this.from, message);
|
|
1042
|
+
} catch (error) {
|
|
1043
|
+
console.error('❌ Fehler beim Senden der View-Once Nachricht:', error);
|
|
1044
|
+
throw error;
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
|
|
954
1048
|
// Mention mit Typing - Neue Funktion für bessere UX
|
|
955
1049
|
async slowTypeWithMention(text, userJid) {
|
|
956
1050
|
const senderName = userJid.split('@')[0];
|