Spaces:
Paused
Paused
| 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(`<h1>β Bot Connected!</h1><p>Siap menerima pesan WhatsApp</p>`); | |||
| return; | |||
| } | |||
| // Kalau ada pairing code | |||
| if (pairingCode) { | |||
| res.send(` | |||
| <div style="text-align:center;font-family:Arial;padding:20px;"> | |||
| <h1>π’ Pairing Code</h1> | |||
| <div style="font-size:3em;letter-spacing:10px;background:#333;color:#0f0;padding:20px;border-radius:10px;margin:20px 0;"> | |||
| ${pairingCode} | |||
| </div> | |||
| <p>Cara pakai:</p> | |||
| <ol style="text-align:left;display:inline-block;"> | |||
| <li>Buka WhatsApp</li> | |||
| <li>Menu β Linked Devices</li> | |||
| <li>Link with phone number</li> | |||
| <li>Masukin kode di atas</li> | |||
| </ol> | |||
| <p>Atau tunggu QR code di bawah...</p> | |||
| <script>setTimeout(()=>location.reload(),5000)</script> | |||
| </div> | |||
| `); | |||
| return; | |||
| } | |||
| // Kalau ada QR | |||
| if (qrCodeData) { | |||
| const qr = await qrcode.toDataURL(qrCodeData); | |||
| res.send(` | |||
| <div style="text-align:center;font-family:Arial;padding:20px;"> | |||
| <h1>π· Scan QR Code</h1> | |||
| <img src="${qr}" width="300" style="margin:20px 0;"> | |||
| <p>WhatsApp β Menu β Linked Devices β Scan</p> | |||
| <script>setTimeout(()=>location.reload(),5000)</script> | |||
| </div> | |||
| `); | |||
| return; | |||
| } | |||
| // Loading | |||
| res.send(` | |||
| <div style="text-align:center;font-family:Arial;padding:20px;"> | |||
| <h1>β³ Status: ${status}</h1> | |||
| <p>Menyiapkan koneksi...</p> | |||
| <p>Refresh dalam 5 detik</p> | |||
| <script>setTimeout(()=>location.reload(),3000)</script> | |||
| </div> | |||
| `); | |||
| }); | |||
| 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%26%23x27%3B%3C%2Fspan%3E%2C%3C!----%3E%3C%2Ftd%3E%3C%2Ftr%3E%3Ctr id="L173"> | { inputs: `<s>[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(/<s>\[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(); | |||