whatsapp/index.js

167 lines
4.4 KiB
JavaScript
Raw Normal View History

2025-05-06 17:58:53 +00:00
const venom = require('venom-bot');
2025-05-06 14:04:11 +00:00
const express = require('express');
const qrcode = require('qrcode');
const path = require('path');
const fs = require('fs');
2025-05-06 10:12:55 +00:00
2025-05-06 14:04:11 +00:00
const app = express();
app.use(express.json());
app.use(express.static('public'));
2025-05-06 08:51:13 +00:00
2025-05-06 17:58:53 +00:00
let client;
2025-05-06 14:04:11 +00:00
let qrData = null;
let isConnected = false;
2025-05-06 08:51:13 +00:00
2025-05-06 17:58:53 +00:00
// Initialisation Venom-bot
const initVenom = async () => {
client = await venom.create({
session: 'whatsapp-session',
disableSpins: true,
logQR: false,
catchQR: (base64Qrimg) => {
qrcode.toDataURL(base64Qrimg, (err, url) => {
if (err) {
console.error('Erreur QR code:', err);
return;
}
qrData = url;
isConnected = false;
});
}
2025-05-06 14:04:11 +00:00
});
2025-05-06 08:51:13 +00:00
2025-05-06 17:58:53 +00:00
client.onStateChange((state) => {
console.log('État de connexion:', state);
isConnected = state === 'CONNECTED';
if (state === 'DISCONNECTED') {
console.log('🔁 Tentative de reconnexion...');
setTimeout(initVenom, 5000);
2025-05-06 10:12:55 +00:00
}
2025-05-06 14:04:11 +00:00
});
};
2025-05-06 10:12:55 +00:00
2025-05-06 17:58:53 +00:00
initVenom();
// Routes Express
2025-05-06 14:31:16 +00:00
app.use('/static', express.static(path.join(__dirname, 'public')));
2025-05-06 08:51:13 +00:00
2025-05-06 09:54:23 +00:00
app.get('/login', (req, res) => {
2025-05-06 14:04:11 +00:00
res.sendFile(path.join(__dirname, 'public', 'login.html'));
});
2025-05-06 10:12:55 +00:00
2025-05-06 09:54:23 +00:00
app.get('/api/qrcode', (req, res) => {
2025-05-06 14:04:11 +00:00
res.json({ qr: qrData, connected: isConnected });
});
2025-05-06 08:51:13 +00:00
2025-05-06 09:38:23 +00:00
app.post('/sendText', async (req, res) => {
2025-05-06 14:04:11 +00:00
const { phone, message } = req.body;
2025-05-06 17:58:53 +00:00
if (!client || !isConnected) return res.status(400).json({ error: 'Non connecté' });
2025-05-06 09:38:23 +00:00
try {
2025-05-06 17:58:53 +00:00
await client.sendText(`${phone}@c.us`, message);
2025-05-06 14:04:11 +00:00
res.json({ success: true });
2025-05-06 09:54:23 +00:00
} catch (e) {
2025-05-06 14:04:11 +00:00
res.status(500).json({ error: e.message });
2025-05-06 09:38:23 +00:00
}
2025-05-06 14:04:11 +00:00
});
2025-05-06 09:43:48 +00:00
2025-05-06 09:54:23 +00:00
app.post('/sendButtons', async (req, res) => {
2025-05-06 14:04:11 +00:00
const { phone } = req.body;
2025-05-06 17:58:53 +00:00
if (!client || !isConnected) return res.status(400).json({ error: 'Non connecté' });
2025-05-06 12:00:21 +00:00
2025-05-06 11:53:28 +00:00
try {
2025-05-06 17:58:53 +00:00
const buttons = [
{ body: "📩 Contacter support" },
{ body: "🌐 Voir notre site" },
{ body: "📞 Appeler le support" }
];
await client.sendButtons(
`${phone}@c.us`,
"Bienvenue sur notre service !",
buttons,
"Choisis une action ci-dessous"
);
2025-05-06 14:04:11 +00:00
res.json({ success: true });
2025-05-06 11:53:28 +00:00
} catch (e) {
2025-05-06 17:58:53 +00:00
console.error('❌ Erreur boutons:', e);
2025-05-06 14:04:11 +00:00
res.status(500).json({ error: e.message });
2025-05-06 11:53:28 +00:00
}
2025-05-06 14:04:11 +00:00
});
2025-05-06 17:58:53 +00:00
2025-05-06 12:17:18 +00:00
app.post('/sendInteractiveImage', async (req, res) => {
2025-05-06 17:58:53 +00:00
const { phone, caption, footer } = req.body;
if (!client || !isConnected) return res.status(400).json({ error: 'Non connecté' });
2025-05-06 12:17:18 +00:00
try {
2025-05-06 17:49:13 +00:00
const imagePath = path.join(__dirname, 'public', 'logo-merlo-cs-FR.jpg');
const imageBuffer = fs.readFileSync(imagePath);
2025-05-06 17:58:53 +00:00
await client.sendImage(
`${phone}@c.us`,
imageBuffer,
'logo.jpg',
caption || 'Description par défaut',
{
footer: footer || 'Pied de page',
buttons: [
{ buttonId: 'id1', buttonText: { displayText: '📄 Voir proposition' }, type: 1 },
{ buttonId: 'id2', buttonText: { displayText: '🔧 Spécifications' }, type: 1 }
]
}
2025-05-06 17:49:13 +00:00
);
2025-05-06 17:58:53 +00:00
res.json({ success: true });
2025-05-06 14:04:11 +00:00
} catch (e) {
2025-05-06 17:58:53 +00:00
console.error('❌ Erreur image interactive:', e);
res.status(500).json({ error: e.message });
2025-05-06 12:17:18 +00:00
}
2025-05-06 14:04:11 +00:00
});
2025-05-06 14:52:28 +00:00
2025-05-06 15:28:38 +00:00
app.post('/sendProductMessage', async (req, res) => {
2025-05-06 17:58:53 +00:00
if (!client || !isConnected) return res.status(400).json({ error: 'Non connecté' });
2025-05-06 15:28:38 +00:00
const {
phone,
productImageUrl,
productTitle,
productDescription,
2025-05-06 17:58:53 +00:00
price,
productUrl
2025-05-06 15:28:38 +00:00
} = req.body;
2025-05-06 12:17:18 +00:00
2025-05-06 15:28:38 +00:00
try {
2025-05-06 17:58:53 +00:00
// Venom-bot n'a pas de méthode native pour les produits
// On simule avec une image et des boutons
const buttons = [
{ buttonId: 'buy', buttonText: { displayText: '🛒 Acheter' }, type: 1 },
{ buttonId: 'details', buttonText: { displayText: ' Détails' }, type: 1 }
];
const caption = `*${productTitle}*\n\n${productDescription}\n\nPrix: ${price}`;
await client.sendImage(
`${phone}@c.us`,
productImageUrl,
'product.jpg',
caption,
{ buttons }
2025-05-06 15:28:38 +00:00
);
2025-05-06 17:58:53 +00:00
res.json({ success: true });
2025-05-06 15:28:38 +00:00
} catch (e) {
2025-05-06 17:58:53 +00:00
console.error('❌ Erreur produit:', e);
res.status(500).json({ error: e.message });
2025-05-06 15:28:38 +00:00
}
});
2025-05-06 15:34:25 +00:00
2025-05-06 17:58:53 +00:00
// Gestion des erreurs
2025-05-06 15:34:25 +00:00
app.use((req, res) => res.status(404).json({ error: 'Ressource introuvable' }));
app.use((err, req, res, next) => {
2025-05-06 17:58:53 +00:00
console.error('Erreur:', err);
2025-05-06 15:34:25 +00:00
res.status(500).json({ error: err.message });
});
2025-05-06 17:58:53 +00:00
app.listen(3001, () => console.log('🚀 Serveur Venom démarré sur http://localhost:3001'));