This commit is contained in:
julien 2025-05-06 11:54:23 +02:00
parent 2a59c059fc
commit a99e9cbf2e
5 changed files with 62 additions and 168 deletions

View File

@ -1,27 +1,10 @@
FROM node:20
WORKDIR /app
COPY package.json ./
COPY yarn.lock ./
COPY package.json yarn.lock ./
RUN yarn install
COPY . .
# Puppeteer/Chrome deps
RUN apt-get update && apt-get install -y \
libnss3 \
libxss1 \
libasound2 \
libatk-bridge2.0-0 \
libgtk-3-0 \
libgbm1 \
libx11-xcb1 \
libxcomposite1 \
libxdamage1 \
libxrandr2 \
xdg-utils \
--no-install-recommends
EXPOSE 3001
EXPOSE 3000
CMD ["yarn", "start"]

View File

@ -1,12 +1,11 @@
version: '3.8'
services:
whatsapp-bot:
wweb:
build: .
container_name: whatsapp-bot
ports:
- "3001:3001"
volumes:
- ./tokens:/app/tokens
- ./session-web-api:/app/session-web-api
- .wweb-session:/root/.wwebjs_auth
restart: unless-stopped
volumes:
.wweb-session:

160
index.js
View File

@ -1,143 +1,69 @@
const { create } = require('venom-bot');
const express = require('express');
const path = require('path');
let client;
let qrCodeBase64 = null;
let isConnected = false;
import { Client, LocalAuth, Buttons } from 'whatsapp-web.js';
import express from 'express';
import qrcode from 'qrcode';
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const app = express();
app.use(express.static('public'));
app.use(express.json());
// 📄 Page avec QR Code
let qrCodeData = null;
let clientReady = false;
const client = new Client({
authStrategy: new LocalAuth(),
puppeteer: {
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
}
});
client.on('qr', async (qr) => {
qrCodeData = await qrcode.toDataURL(qr);
clientReady = false;
});
client.on('ready', () => {
console.log('✅ WhatsApp prêt');
clientReady = true;
});
client.initialize();
// --- QR PAGE ---
app.get('/login', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'login.html'));
});
// 📄 Page "connecté"
app.get('/connected', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'connected.html'));
});
// 🔄 QR code en base64 + état de connexion
app.get('/api/qrcode', (req, res) => {
res.json({ qr: qrCodeBase64, connected: isConnected });
});
// ✅ API POST : envoie message avec boutons
app.post('/sendButtons', async (req, res) => {
const { phone, title, message, buttons } = req.body;
console.log('📥 Requête reçue :');
console.log('Phone:', phone);
console.log('Title:', title);
console.log('Message:', message);
console.log('Buttons brut:', buttons);
if (!client) return res.status(500).json({ error: 'Client WhatsApp non initialisé' });
if (!phone || !message || !title || !Array.isArray(buttons)) {
return res.status(400).json({ error: 'Paramètres manquants ou invalides' });
}
try {
const formattedButtons = buttons.map(btn => ({
buttonText: { displayText: btn.text }
}));
console.log('✅ Boutons formatés pour Venom :', formattedButtons);
await client.sendButtons(
`${phone}@c.us`,
title, // ✅ OBLIGATOIRE en 1er
message, // ✅ Description
formattedButtons // ✅ Format conforme
);
res.json({ success: true });
} catch (error) {
console.error('❌ Erreur sendButtons:', error);
res.status(500).json({ error: error.message || 'Erreur interne' });
}
res.json({ qr: qrCodeData, connected: clientReady });
});
// --- API ENVOI TEXTE ---
app.post('/sendText', async (req, res) => {
const { phone, message } = req.body;
console.log('📥 Requête TEXT :');
console.log('Phone:', phone);
console.log('Message:', message);
if (!client) return res.status(500).json({ error: 'Client WhatsApp non initialisé' });
if (!phone || !message) {
return res.status(400).json({ error: 'Paramètres manquants' });
}
try {
await client.sendText(`${phone}@c.us`, message);
await client.sendMessage(`${phone}@c.us`, message);
res.json({ success: true });
} catch (error) {
console.error('❌ Erreur sendText:', error);
res.status(500).json({ error: error.message || 'Erreur interne' });
} catch (e) {
res.status(500).json({ error: e.message });
}
});
// ✅ API POST : envoie un menu interactif (liste)
app.post('/sendListMenu', async (req, res) => {
const { phone, title, subtitle, description, buttonText, sections } = req.body;
console.log('📥 Requête LIST MENU :');
console.log('Phone:', phone);
console.log('Title:', title);
console.log('Subtitle:', subtitle);
console.log('Description:', description);
console.log('ButtonText:', buttonText);
console.log('Sections:', sections);
if (!client) return res.status(500).json({ error: 'Client WhatsApp non initialisé' });
// --- API ENVOI BOUTONS ---
app.post('/sendButtons', async (req, res) => {
const { phone, title, message, buttons } = req.body;
try {
await client.sendListMenu(
`${phone}@c.us`,
title,
subtitle,
description,
buttonText,
sections
);
const formatted = new Buttons(message, buttons.map(b => b.text), title, '');
await client.sendMessage(`${phone}@c.us`, formatted);
res.json({ success: true });
} catch (error) {
console.error('❌ Erreur sendListMenu:', error);
res.status(500).json({ error: error.message || 'Erreur interne' });
} catch (e) {
res.status(500).json({ error: e.message });
}
});
// ▶️ Démarrage + QR code init
create({
session: 'session-web-api',
multidevice: false,
catchQR: (base64Qrimg, asciiQR) => {
qrCodeBase64 = base64Qrimg;
isConnected = false;
},
puppeteerOptions: {
headless: 'new',
args: ['--no-sandbox', '--disable-setuid-sandbox']
}
}).then((cl) => {
client = cl;
client.onStateChange((state) => {
if (state === 'CONNECTED') isConnected = true;
});
client.onStreamChange((state) => {
if (state === 'CONNECTED') isConnected = true;
});
}).catch((err) => {
console.error('Erreur init Venom:', err);
});
app.listen(3001, () => console.log('🚀 Serveur lancé sur http://localhost:3001/login'));
app.listen(3000, () => console.log('🚀 Serveur démarré sur http://localhost:3000/login'));

View File

@ -1,14 +1,14 @@
{
"name": "whatsappServer",
"name": "whatsapp-wweb",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"type": "module",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"body-parser": "^2.2.0",
"express": "^5.1.0",
"venom-bot": "^5.3.0"
"express": "^4.18.4",
"qrcode": "^1.5.1",
"whatsapp-web.js": "^1.21.0"
}
}

View File

@ -1,32 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>Connexion WhatsApp</title>
<style>
body { font-family: sans-serif; text-align: center; margin-top: 50px; }
img { width: 300px; }
</style>
</head>
<head><title>Connexion WhatsApp</title></head>
<body>
<h1>Scannez ce QR Code</h1>
<div id="qr-container">Chargement du QR Code...</div>
<h1>Scanne le QR Code</h1>
<div id="qr">Chargement...</div>
<script>
async function fetchQR() {
async function refreshQR() {
const res = await fetch('/api/qrcode');
const data = await res.json();
if (data.connected) {
window.location.href = '/connected';
} else if (data.qr) {
document.getElementById('qr-container').innerHTML =
`<img src="${data.qr}" alt="QR Code WhatsApp">`;
}
setTimeout(fetchQR, 3000);
if (data.connected) location.href = '/connected';
else if (data.qr) document.getElementById('qr').innerHTML = `<img src="${data.qr}" />`;
setTimeout(refreshQR, 3000);
}
fetchQR();
refreshQR();
</script>
</body>
</html>