Spaces:
Running
Running
File size: 5,260 Bytes
9a324ed ae8711c 4537df0 ae8711c 4537df0 ae8711c 20ea9ad ae8711c 20ea9ad 9a324ed 4537df0 20ea9ad b7dbfad 4537df0 b7dbfad 5182a50 b7dbfad 20ea9ad 33199bf 4537df0 b7dbfad 20ea9ad 9a324ed d527c30 20ea9ad 4537df0 20ea9ad ae8711c 20ea9ad 4537df0 ae8711c 9a324ed 20ea9ad 4537df0 2f71ff4 20ea9ad 5182a50 20ea9ad 4537df0 5182a50 20ea9ad 5182a50 ae8711c 20ea9ad ae8711c 20ea9ad 5182a50 4537df0 20ea9ad 4537df0 20ea9ad ae8711c b7dbfad 20ea9ad 4537df0 20ea9ad 5182a50 20ea9ad 4537df0 20ea9ad ae8711c 20ea9ad 4537df0 ae8711c 20ea9ad | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | import fs from "fs";
import express from "express";
import * as wppconnect from '@wppconnect-team/wppconnect';
import path from "path";
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
let wppClient = null;
let currentStatus = 'DISCONNECTED';
let qrCodeBase64 = '';
let logs = [];
function addLog(msg) {
const timestamp = new Date().toLocaleTimeString();
const fullMsg = `[${timestamp}] ${msg}`;
logs.push(fullMsg);
if (logs.length > 100) logs.shift();
console.log(fullMsg);
}
const app = express();
const PORT = process.env.PORT || 7860;
app.use(express.json());
// Helper to check passkey
function isValidPasskey(provided) {
const envPasskey = process.env.PASSKEY;
if (!envPasskey) return true;
return provided === envPasskey || provided === `Bearer ${envPasskey}`;
}
// Middleware
function checkPasskey(req, res, next) {
const provided = req.headers['x-passkey'] || req.headers['authorization'] || req.query.passkey;
if (isValidPasskey(provided)) return next();
res.status(401).json({ error: 'Unauthorized' });
}
app.get("/health", (req, res) => res.send("OK"));
app.post('/api/login', (req, res) => {
const { passkey } = req.body;
if (isValidPasskey(passkey)) {
addLog("Successful login attempt.");
res.json({ success: true });
} else {
addLog(`Failed login attempt.`);
res.status(401).json({ success: false, error: 'Invalid passkey' });
}
});
app.get("/api/status", checkPasskey, (req, res) => {
res.json({ status: currentStatus, qrCode: qrCodeBase64, logs });
});
app.get("/api/groups", checkPasskey, async (req, res) => {
if (!wppClient || currentStatus !== 'CONNECTED') return res.status(400).json({ error: 'Not connected' });
try {
const groups = await wppClient.getAllGroups();
res.json({ success: true, groups });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.post('/api/start', checkPasskey, async (req, res) => {
if (currentStatus === 'CONNECTED' || currentStatus === 'INITIALIZING') {
return res.json({ success: true, status: currentStatus });
}
currentStatus = 'INITIALIZING';
qrCodeBase64 = '';
addLog('Initializing WPPConnect session...');
res.json({ success: true });
try {
const sessionPath = path.join(__dirname, 'tokens', 'gradio-session');
if (fs.existsSync(sessionPath)) {
try {
fs.rmSync(sessionPath, { recursive: true, force: true });
addLog("Cleared stale session tokens.");
} catch (e) {
addLog(`Warning: Could not clear session path: ${e.message}`);
}
}
wppClient = await wppconnect.create({
session: 'gradio-session',
autoClose: 0,
updatesLog: true,
catchQR: (base64Qr) => {
currentStatus = 'QR_CODE';
qrCodeBase64 = base64Qr;
addLog("QR Code generated.");
},
statusFind: (statusSession) => {
addLog(`Session Status: ${statusSession}`);
if (['isLogged', 'inChat', 'qrReadSuccess', 'chatsAvailable'].includes(statusSession)) {
currentStatus = 'CONNECTED';
qrCodeBase64 = '';
addLog("WhatsApp connection established.");
}
},
headless: true,
puppeteerOptions: {
executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || '/usr/bin/chromium',
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-gpu',
'--no-zygote'
]
}
});
// Listen for interface changes to catch the 'MAIN' state
wppClient.onInterfaceChange((state) => {
addLog(`Interface state: ${state.display || state.mode}`);
if (state.display === 'MAIN') {
currentStatus = 'CONNECTED';
qrCodeBase64 = '';
addLog("WhatsApp reached MAIN interface.");
}
});
const isLogged = await wppClient.isLoggedIn();
if (isLogged) {
currentStatus = 'CONNECTED';
addLog("Validated: User is logged in.");
}
} catch (error) {
addLog(`WPPConnect Error: ${error.message}`);
currentStatus = 'ERROR';
wppClient = null;
}
});
app.post('/api/send', checkPasskey, async (req, res) => {
if (!wppClient || currentStatus !== 'CONNECTED') return res.status(400).json({ error: 'Not connected' });
const { phone, message, isGroup } = req.body;
try {
let recipient = phone;
if (!phone.includes('@')) recipient = isGroup ? `${phone}@g.us` : `${phone}@c.us`;
addLog(`Sending message to ${recipient}...`);
const result = await wppClient.sendText(recipient, message);
addLog("Message sent!");
res.json({ success: true, result });
} catch (error) {
addLog(`Send Error: ${error.message}`);
res.status(500).json({ error: error.message });
}
});
const distPath = path.join(__dirname, 'dist');
if (fs.existsSync(distPath)) {
app.use(express.static(distPath));
app.get('*', (req, res) => {
if (req.path.startsWith('/api/')) return res.status(404).json({ error: 'API route not found' });
res.sendFile(path.join(distPath, 'index.html'));
});
}
app.listen(PORT, "0.0.0.0", () => {
console.log(`Server running on port ${PORT}`);
});
|