const { default: makeWASocket, DisconnectReason, useMultiFileAuthState, fetchLatestBaileysVersion } = require('@whiskeysockets/baileys'); const QRCode = require('qrcode-terminal'); const qrcode = require('qrcode'); const axios = require('axios'); const crypto = require('crypto'); // TAMBAHIN INI const fs = require('fs'); const express = require('express'); const pino = require('pino'); const app = express(); const PORT = process.env.PORT || 7860; const HF_TOKEN = process.env.HF_TOKEN || 'hf_LMbsGCSfszThllrjJzi'; let sock = null; let qrCodeData = null; let pairingCode = null; let status = 'connecting'; // Web UI app.get('/', async (req, res) => { // Kalau connected if (status === 'connected') { res.send(`

āœ… Bot Connected!

Siap menerima pesan WhatsApp

`); return; } // Kalau ada pairing code if (pairingCode) { res.send(`

šŸ”¢ Pairing Code

${pairingCode}

Cara pakai:

  1. Buka WhatsApp
  2. Menu → Linked Devices
  3. Link with phone number
  4. Masukin kode di atas

Atau tunggu QR code di bawah...

`); return; } // Kalau ada QR if (qrCodeData) { const qr = await qrcode.toDataURL(qrCodeData); res.send(`

šŸ“· Scan QR Code

WhatsApp → Menu → Linked Devices → Scan

`); return; } // Loading res.send(`

ā³ Status: ${status}

Menyiapkan koneksi...

Refresh dalam 5 detik

`); }); app.listen(PORT, () => console.log(`🌐 Web: http://localhost:${PORT}`)); // Bot async function startBot() { console.log('šŸš€ Starting bot...'); const { state, saveCreds } = await useMultiFileAuthState('./auth'); const { version } = await fetchLatestBaileysVersion(); sock = makeWASocket({ version, logger: pino({ level: 'silent' }), printQRInTerminal: true, auth: state, browser: ['Ubuntu', 'Chrome', '20.0.04'], }); // Pairing code (dengan error handling) if (!state.creds.registered) { setTimeout(async () => { try { // Coba pairing code const code = await sock.requestPairingCode('6282117207534'); // GANTI NOMOR! pairingCode = code; console.log('\nšŸ”¢ PAIRING CODE:', code); console.log('šŸ‘‰ Masukin ke WhatsApp → Linked Devices → Link with phone number\n'); } catch (e) { console.log('āš ļø Pairing code gagal, pake QR aja'); console.log('šŸ‘‰ Tunggu QR code muncul...\n'); // QR akan muncul otomatis di event connection.update } }, 3000); } sock.ev.on('connection.update', async (update) => { const { connection, lastDisconnect, qr } = update; if (qr) { qrCodeData = qr; status = 'qr_ready'; console.log('\nšŸ”„ QR CODE READY'); console.log('šŸ‘‰ Scan pakai WhatsApp\n'); QRCode.generate(qr, { small: true }); } if (connection === 'open') { status = 'connected'; qrCodeData = null; pairingCode = null; console.log('\nāœ… CONNECTED!'); console.log('šŸ“± Bot siap dipake\n'); try { await sock.sendMessage(sock.user.id, { text: 'šŸ¤– *Bot Aktif!*\n\nKetik !help untuk bantuan' }); } catch (e) {} } else if (connection === 'close') { const statusCode = lastDisconnect?.error?.output?.statusCode; const shouldReconnect = statusCode !== DisconnectReason.loggedOut; console.log('\nāŒ Disconnected:', statusCode); status = 'disconnected'; qrCodeData = null; pairingCode = null; if (shouldReconnect) { console.log('šŸ”„ Reconnecting in 5s...\n'); setTimeout(startBot, 5000); } } }); sock.ev.on('creds.update', saveCreds); sock.ev.on('messages.upsert', async ({ messages, type }) => { if (type !== 'notify') return; const msg = messages[0]; if (!msg.message || msg.key.fromMe) return; const sender = msg.key.remoteJid; const text = msg.message.conversation || msg.message.extendedTextMessage?.text || ''; if (!text.startsWith('!')) return; const cmd = text.slice(1).split(' ')[0].toLowerCase(); const args = text.slice(1).split(' ').slice(1).join(' '); if (cmd === 'ai' && args) { await sock.sendMessage(sender, { text: 'ā³ AI mikir...' }); try { const res = await axios.post( '/static-proxy?url=https%3A%2F%2Fapi-inference.huggingface.co%2Fmodels%2Fmistralai%2FMistral-7B-Instruct-v0.2', { inputs: `[INST] ${args} [/INST]`, parameters: { max_new_tokens: 500 } }, { headers: { 'Authorization': `Bearer ${HF_TOKEN}` }, timeout: 30000 } ); let reply = res.data[0]?.generated_text || 'Gagal'; reply = reply.replace(/\[INST\].*?\[\/INST\]\s*/, ''); await sock.sendMessage(sender, { text: reply.substring(0, 1000) }); } catch (e) { await sock.sendMessage(sender, { text: 'āŒ AI sibuk, coba lagi' }); } } else if (cmd === 'help') { await sock.sendMessage(sender, { text: '!ai [tanya] - Tanya AI\n!status - Cek status' }); } else if (cmd === 'status') { await sock.sendMessage(sender, { text: `Status: ${status}` }); } }); } startBot();