update
This commit is contained in:
parent
2a59c059fc
commit
a99e9cbf2e
21
Dockerfile
21
Dockerfile
@ -1,27 +1,10 @@
|
|||||||
FROM node:20
|
FROM node:20
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
COPY package.json yarn.lock ./
|
||||||
COPY package.json ./
|
|
||||||
COPY yarn.lock ./
|
|
||||||
RUN yarn install
|
RUN yarn install
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Puppeteer/Chrome deps
|
EXPOSE 3000
|
||||||
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
|
|
||||||
CMD ["yarn", "start"]
|
CMD ["yarn", "start"]
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
version: '3.8'
|
version: '3.8'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
whatsapp-bot:
|
wweb:
|
||||||
build: .
|
build: .
|
||||||
container_name: whatsapp-bot
|
|
||||||
ports:
|
ports:
|
||||||
- "3001:3001"
|
- "3001:3001"
|
||||||
volumes:
|
volumes:
|
||||||
- ./tokens:/app/tokens
|
- .wweb-session:/root/.wwebjs_auth
|
||||||
- ./session-web-api:/app/session-web-api
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
.wweb-session:
|
||||||
|
|||||||
160
index.js
160
index.js
@ -1,143 +1,69 @@
|
|||||||
const { create } = require('venom-bot');
|
import { Client, LocalAuth, Buttons } from 'whatsapp-web.js';
|
||||||
const express = require('express');
|
import express from 'express';
|
||||||
const path = require('path');
|
import qrcode from 'qrcode';
|
||||||
|
import path from 'path';
|
||||||
let client;
|
import { fileURLToPath } from 'url';
|
||||||
let qrCodeBase64 = null;
|
|
||||||
let isConnected = false;
|
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(express.static('public'));
|
app.use(express.static('public'));
|
||||||
app.use(express.json());
|
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) => {
|
app.get('/login', (req, res) => {
|
||||||
res.sendFile(path.join(__dirname, 'public', 'login.html'));
|
res.sendFile(path.join(__dirname, 'public', 'login.html'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// 📄 Page "connecté"
|
|
||||||
app.get('/connected', (req, res) => {
|
app.get('/connected', (req, res) => {
|
||||||
res.sendFile(path.join(__dirname, 'public', 'connected.html'));
|
res.sendFile(path.join(__dirname, 'public', 'connected.html'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// 🔄 QR code en base64 + état de connexion
|
|
||||||
app.get('/api/qrcode', (req, res) => {
|
app.get('/api/qrcode', (req, res) => {
|
||||||
res.json({ qr: qrCodeBase64, connected: isConnected });
|
res.json({ qr: qrCodeData, connected: clientReady });
|
||||||
});
|
|
||||||
|
|
||||||
// ✅ 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' });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- API ENVOI TEXTE ---
|
||||||
app.post('/sendText', async (req, res) => {
|
app.post('/sendText', async (req, res) => {
|
||||||
const { phone, message } = req.body;
|
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 {
|
try {
|
||||||
await client.sendText(`${phone}@c.us`, message);
|
await client.sendMessage(`${phone}@c.us`, message);
|
||||||
res.json({ success: true });
|
res.json({ success: true });
|
||||||
} catch (error) {
|
} catch (e) {
|
||||||
console.error('❌ Erreur sendText:', error);
|
res.status(500).json({ error: e.message });
|
||||||
res.status(500).json({ error: error.message || 'Erreur interne' });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// ✅ 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 {
|
try {
|
||||||
await client.sendListMenu(
|
const formatted = new Buttons(message, buttons.map(b => b.text), title, '');
|
||||||
`${phone}@c.us`,
|
await client.sendMessage(`${phone}@c.us`, formatted);
|
||||||
title,
|
|
||||||
subtitle,
|
|
||||||
description,
|
|
||||||
buttonText,
|
|
||||||
sections
|
|
||||||
);
|
|
||||||
res.json({ success: true });
|
res.json({ success: true });
|
||||||
} catch (error) {
|
} catch (e) {
|
||||||
console.error('❌ Erreur sendListMenu:', error);
|
res.status(500).json({ error: e.message });
|
||||||
res.status(500).json({ error: error.message || 'Erreur interne' });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.listen(3000, () => console.log('🚀 Serveur démarré sur http://localhost:3000/login'));
|
||||||
|
|
||||||
// ▶️ 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'));
|
|
||||||
|
|||||||
10
package.json
10
package.json
@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "whatsappServer",
|
"name": "whatsapp-wweb",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"license": "MIT",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node index.js"
|
"start": "node index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"body-parser": "^2.2.0",
|
"express": "^4.18.4",
|
||||||
"express": "^5.1.0",
|
"qrcode": "^1.5.1",
|
||||||
"venom-bot": "^5.3.0"
|
"whatsapp-web.js": "^1.21.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,32 +1,18 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head><title>Connexion WhatsApp</title></head>
|
||||||
<title>Connexion WhatsApp</title>
|
|
||||||
<style>
|
|
||||||
body { font-family: sans-serif; text-align: center; margin-top: 50px; }
|
|
||||||
img { width: 300px; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<h1>Scannez ce QR Code</h1>
|
<h1>Scanne le QR Code</h1>
|
||||||
<div id="qr-container">Chargement du QR Code...</div>
|
<div id="qr">Chargement...</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
async function fetchQR() {
|
async function refreshQR() {
|
||||||
const res = await fetch('/api/qrcode');
|
const res = await fetch('/api/qrcode');
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
|
if (data.connected) location.href = '/connected';
|
||||||
if (data.connected) {
|
else if (data.qr) document.getElementById('qr').innerHTML = `<img src="${data.qr}" />`;
|
||||||
window.location.href = '/connected';
|
setTimeout(refreshQR, 3000);
|
||||||
} else if (data.qr) {
|
|
||||||
document.getElementById('qr-container').innerHTML =
|
|
||||||
`<img src="${data.qr}" alt="QR Code WhatsApp">`;
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(fetchQR, 3000);
|
|
||||||
}
|
}
|
||||||
|
refreshQR();
|
||||||
fetchQR();
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user