fluxy-bot 0.15.5 → 0.15.6
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/package.json +1 -1
- package/supervisor/channels/whatsapp.ts +25 -17
- package/supervisor/index.ts +45 -8
package/package.json
CHANGED
|
@@ -120,18 +120,11 @@ export class WhatsAppChannel implements ChannelProvider {
|
|
|
120
120
|
// If it's already a phone JID, return as-is
|
|
121
121
|
if (jid.endsWith('@s.whatsapp.net')) return jid;
|
|
122
122
|
|
|
123
|
-
// Check LID map
|
|
123
|
+
// Check LID map (only contains our own LID, mapped during connection)
|
|
124
124
|
const mapped = this.lidToPhoneMap.get(jid);
|
|
125
125
|
if (mapped) return mapped;
|
|
126
126
|
|
|
127
|
-
//
|
|
128
|
-
// LID JIDs typically end with @lid or have a long numeric format
|
|
129
|
-
if (this.ownPhoneJid && (jid.includes('@lid') || jid.match(/^\d{15,}@/))) {
|
|
130
|
-
log.info(`[whatsapp] Unmapped LID ${jid} — assuming self-chat, using own phone JID`);
|
|
131
|
-
this.lidToPhoneMap.set(jid, this.ownPhoneJid);
|
|
132
|
-
return this.ownPhoneJid;
|
|
133
|
-
}
|
|
134
|
-
|
|
127
|
+
// Unknown LID — don't guess. Return as-is so isSelfChat stays false.
|
|
135
128
|
return jid;
|
|
136
129
|
}
|
|
137
130
|
|
|
@@ -144,11 +137,18 @@ export class WhatsAppChannel implements ChannelProvider {
|
|
|
144
137
|
const phone = user.id.split(':')[0];
|
|
145
138
|
this.ownPhoneJid = `${phone}@s.whatsapp.net`;
|
|
146
139
|
|
|
147
|
-
// user.lid (if available) is the LID JID
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
140
|
+
// user.lid (if available) is the LID JID — map it and variations
|
|
141
|
+
const lid = (user as any).lid;
|
|
142
|
+
if (lid) {
|
|
143
|
+
// Map the exact LID
|
|
144
|
+
this.lidToPhoneMap.set(lid, this.ownPhoneJid);
|
|
145
|
+
// Also map the numeric part without @lid suffix (remoteJid may use @lid format)
|
|
146
|
+
const lidNum = lid.split(':')[0].split('@')[0];
|
|
147
|
+
this.lidToPhoneMap.set(`${lidNum}@lid`, this.ownPhoneJid);
|
|
148
|
+
log.info(`[whatsapp] LID map: ${lid} (and ${lidNum}@lid) → ${this.ownPhoneJid}`);
|
|
151
149
|
}
|
|
150
|
+
|
|
151
|
+
log.info(`[whatsapp] Own phone JID: ${this.ownPhoneJid}`);
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
private async connectInternal(): Promise<void> {
|
|
@@ -250,15 +250,23 @@ export class WhatsAppChannel implements ChannelProvider {
|
|
|
250
250
|
|
|
251
251
|
const fromMe = msg.key.fromMe || false;
|
|
252
252
|
const rawSender = msg.key.remoteJid || '';
|
|
253
|
+
const participant = msg.key.participant || '';
|
|
254
|
+
|
|
255
|
+
// Debug: log all available sender fields to find the actual sender
|
|
256
|
+
log.info(`[whatsapp] DEBUG msg.key: remoteJid=${rawSender} fromMe=${fromMe} participant=${participant}`);
|
|
257
|
+
log.info(`[whatsapp] DEBUG pushName=${msg.pushName || 'none'} verifiedBizName=${(msg as any).verifiedBizName || 'none'}`);
|
|
258
|
+
|
|
259
|
+
// The actual sender JID — use participant if available (newer protocol), fallback to remoteJid
|
|
260
|
+
const actualSender = participant || rawSender;
|
|
253
261
|
|
|
254
262
|
// Translate LID JIDs to phone JIDs
|
|
255
|
-
const sender = this.translateJid(
|
|
263
|
+
const sender = this.translateJid(actualSender);
|
|
256
264
|
const pushName = msg.pushName || undefined;
|
|
257
265
|
|
|
258
|
-
// Detect self-chat: remoteJid matches our own phone number
|
|
259
|
-
const isSelfChat = this.ownPhoneJid !== null &&
|
|
266
|
+
// Detect self-chat: remoteJid matches our own phone number AND no participant field
|
|
267
|
+
const isSelfChat = !participant && this.ownPhoneJid !== null && this.translateJid(rawSender) === this.ownPhoneJid;
|
|
260
268
|
|
|
261
|
-
log.info(`[whatsapp] Message from ${sender} (raw=${rawSender}, fromMe=${fromMe}, selfChat=${isSelfChat}): ${text.slice(0, 80)}`);
|
|
269
|
+
log.info(`[whatsapp] Message from ${sender} (raw=${rawSender}, participant=${participant}, fromMe=${fromMe}, selfChat=${isSelfChat}): ${text.slice(0, 80)}`);
|
|
262
270
|
|
|
263
271
|
this.onMessage(sender, pushName, text, fromMe, isSelfChat);
|
|
264
272
|
}
|
package/supervisor/index.ts
CHANGED
|
@@ -403,20 +403,57 @@ export async function startSupervisor() {
|
|
|
403
403
|
const status = channelManager.getStatus('whatsapp');
|
|
404
404
|
const connected = status?.connected || false;
|
|
405
405
|
res.writeHead(200);
|
|
406
|
+
const confettiHTML = Array.from({ length: 30 }, (_, i) => {
|
|
407
|
+
const colors = ['#04D1FE', '#AF27E3', '#FB4072', '#4ade80', '#facc15', '#818cf8'];
|
|
408
|
+
const color = colors[Math.floor(Math.random() * colors.length)];
|
|
409
|
+
const left = Math.random() * 100;
|
|
410
|
+
const delay = i * 0.04;
|
|
411
|
+
const drift = (Math.random() - 0.5) * 120;
|
|
412
|
+
const duration = 1.8 + Math.random() * 0.8;
|
|
413
|
+
return `<div class="confetti-dot" style="left:${left}%;background:${color};animation-delay:${delay}s;animation-duration:${duration}s;--drift:${drift}px"></div>`;
|
|
414
|
+
}).join('');
|
|
415
|
+
|
|
406
416
|
res.end(`<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
407
417
|
<title>WhatsApp QR</title>
|
|
418
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
419
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
420
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet">
|
|
408
421
|
<style>
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
.
|
|
412
|
-
|
|
413
|
-
.
|
|
422
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
423
|
+
body{background:#212121;color:#f5f5f5;font-family:'Inter',system-ui,-apple-system,sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;height:100dvh;margin:0;overflow:hidden}
|
|
424
|
+
.container{display:flex;flex-direction:column;align-items:center;max-width:360px;width:100%;padding:0 20px}
|
|
425
|
+
|
|
426
|
+
.qr-card{background:#2a2a2a;border:1px solid rgba(255,255,255,0.08);border-radius:20px;padding:28px;width:100%;box-shadow:0 0 0 1px rgba(175,39,227,0.1),0 0 20px -5px rgba(175,39,227,0.15);animation:fade-up .5s ease-out both}
|
|
427
|
+
.qr-inner{background:#fff;border-radius:12px;padding:16px}
|
|
428
|
+
.qr-inner svg{width:100%;height:auto;display:block}
|
|
429
|
+
|
|
430
|
+
.scan-hint{margin-top:20px;font-size:13px;color:#666;text-align:center;animation:fade-up .5s ease-out .2s both}
|
|
431
|
+
|
|
432
|
+
.confetti-wrap{position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;overflow:hidden}
|
|
433
|
+
.confetti-dot{position:absolute;width:8px;height:8px;border-radius:50%;top:-10px;animation:confetti-fall 2s ease-out forwards}
|
|
434
|
+
@keyframes confetti-fall{0%{opacity:1;transform:translateY(0) translateX(0) rotate(0) scale(1)}100%{opacity:0;transform:translateY(100vh) translateX(var(--drift)) rotate(360deg) scale(.5)}}
|
|
435
|
+
|
|
436
|
+
.video-wrap{margin-bottom:8px;animation:pop-in .5s cubic-bezier(.34,1.56,.64,1) forwards}
|
|
437
|
+
.video-wrap video{width:200px;object-fit:contain}
|
|
438
|
+
@keyframes pop-in{0%{transform:scale(0);opacity:0}100%{transform:scale(1);opacity:1}}
|
|
439
|
+
|
|
440
|
+
.text-wrap{text-align:center;animation:fade-up .5s ease-out .3s both}
|
|
441
|
+
.title{font-family:'Space Grotesk',sans-serif;font-size:22px;font-weight:700;background:linear-gradient(135deg,#04D1FE,#AF27E3,#FB4072);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;margin-bottom:8px}
|
|
442
|
+
.subtitle{font-size:14px;color:#999;line-height:1.5}
|
|
443
|
+
|
|
444
|
+
.loading{font-size:14px;color:#999;animation:pulse 2s ease-in-out infinite}
|
|
445
|
+
@keyframes pulse{0%,100%{opacity:.5}50%{opacity:1}}
|
|
446
|
+
@keyframes fade-up{0%{opacity:0;transform:translateY(10px)}100%{opacity:1;transform:translateY(0)}}
|
|
414
447
|
</style></head><body>
|
|
448
|
+
<div class="container">
|
|
415
449
|
${connected
|
|
416
|
-
?
|
|
450
|
+
? `<div class="confetti-wrap">${confettiHTML}</div>
|
|
451
|
+
<div class="video-wrap"><video autoplay muted playsinline><source src="/fluxy_happy_reappearing.mov" type='video/mp4; codecs="hvc1"'><source src="/fluxy_happy_reappearing.webm" type="video/webm"></video></div>
|
|
452
|
+
<div class="text-wrap"><div class="title">Connected!</div><p class="subtitle">WhatsApp is linked. You can close this page.</p></div>`
|
|
417
453
|
: qr
|
|
418
|
-
? `<div class="qr-
|
|
419
|
-
: '<p class="
|
|
454
|
+
? `<div class="qr-card"><div class="qr-inner">${qr}</div></div><p class="scan-hint">Scan with WhatsApp to link</p>`
|
|
455
|
+
: '<p class="loading">Starting WhatsApp... Refresh in a moment.</p>'}
|
|
456
|
+
</div>
|
|
420
457
|
${!connected ? '<script>setTimeout(()=>location.reload(),4000)</script>' : ''}
|
|
421
458
|
</body></html>`);
|
|
422
459
|
return;
|