whatsapp/index.js
2025-05-06 16:25:49 +02:00

210 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { default: makeWASocket, useMultiFileAuthState, DisconnectReason, fetchLatestBaileysVersion, proto, generateWAMessageFromContent, generateWAMessageContent ,prepareWAMessageMedia} = require('@fizzxydev/baileys-pro');
const express = require('express');
const { Boom } = require('@hapi/boom');
const qrcode = require('qrcode');
const path = require('path');
const fs = require('fs');
const app = express();
app.use(express.json());
app.use(express.static('public'));
let sock;
let qrData = null;
let isConnected = false;
const initBaileys = async () => {
const { version } = await fetchLatestBaileysVersion();
const { state, saveCreds } = await useMultiFileAuthState('auth');
sock = makeWASocket({
version,
auth: state,
printQRInTerminal: false
});
sock.ev.on('connection.update', async (update) => {
const { connection, lastDisconnect, qr } = update;
if (qr) {
qrData = await qrcode.toDataURL(qr);
isConnected = false;
}
if (connection === 'close') {
const shouldReconnect = lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut;
if (shouldReconnect) {
console.log('🔁 Reconnexion...');
initBaileys();
} else {
console.log('❌ Déconnecté.');
}
} else if (connection === 'open') {
console.log('✅ Connecté à WhatsApp');
isConnected = true;
}
});
sock.ev.on('creds.update', saveCreds);
};
initBaileys();
app.get('/login', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'login.html'));
});
app.get('/api/qrcode', (req, res) => {
res.json({ qr: qrData, connected: isConnected });
});
app.post('/sendText', async (req, res) => {
const { phone, message } = req.body;
if (!sock || !isConnected) return res.status(400).json({ error: 'Non connecté' });
try {
await sock.sendMessage(`${phone}@s.whatsapp.net`, { text: message });
res.json({ success: true });
} catch (e) {
res.status(500).json({ error: e.message });
}
});
app.post('/sendButtons', async (req, res) => {
const { phone } = req.body;
if (!sock || !isConnected) return res.status(400).json({ error: 'Non connecté' });
try {
const content = {
message: {
interactiveMessage: proto.Message.InteractiveMessage.create({
body: { text: "Bienvenue sur notre service !" },
footer: { text: "Choisis une action ci-dessous" },
header: {
title: "Menu principal",
hasMediaAttachment: false
},
nativeFlowMessage: {
buttons: [
{
name: "cta_reply",
buttonParamsJson: JSON.stringify({
display_text: "📩 Contacter support",
id: "support_action"
})
},
{
name: "cta_url",
buttonParamsJson: JSON.stringify({
display_text: "🌐 Voir notre site",
url: "https://canguidev.fr",
merchant_url: "https://canguidev.fr"
})
},
{
name: "cta_call",
buttonParamsJson: JSON.stringify({
display_text: "📞 Appeler le support",
id: "+33612345678"
})
}
]
}
})
}
};
const msg = generateWAMessageFromContent(`${phone}@s.whatsapp.net`, content, {});
await sock.relayMessage(`${phone}@s.whatsapp.net`, msg.message, { messageId: msg.key.id });
res.json({ success: true });
} catch (e) {
console.error('❌ Erreur bouton actif :', e);
res.status(500).json({ error: e.message });
}
});
app.post('/sendInteractiveImage', async (req, res) => {
const { phone, caption, title, subtitle, footer } = req.body;
if (!sock || !isConnected) {
return res.status(400).json({ error: 'Non connecté' });
}
try {
// 1) Lire limage en Buffer
const imagePath = path.join(__dirname, 'public', 'logo-merlo-cs-FR.jpg');
const imageBuffer = fs.readFileSync(imagePath);
// 2) Envoyer un message interactif AVEC MEDIA
await sock.sendMessage(
`${phone}@s.whatsapp.net`,
{
// on passe le Buffer directement (pas d'objet url)
image: imageBuffer,
caption: caption || 'Description par défaut',
title: title || 'Titre par défaut',
subtitle: subtitle || 'Sous-titre',
footer: footer || 'Pied de page',
media: true, // active len-tête média
interactiveButtons: [
{
name: 'cta_url',
buttonParamsJson: JSON.stringify({
display_text: '📄 Proposition',
url: 'https://merlo-ch.com/uploads/proposition/f_p_250505_0000136_00008_EB00001909.pdf'
})
},
{
name: 'cta_url',
buttonParamsJson: JSON.stringify({
display_text: '🔧 Spécifications',
url: 'https://merlo-ch.com/uploads/proposition/d_p_250505_0000136_00008_EB00001909.pdf'
})
}
]
}
);
return res.json({ success: true });
} catch (e) {
console.error('❌ Erreur interactive image :', e);
return res.status(500).json({ error: e.message });
}
});
// app.post('/sendInteractiveImage', async (req, res) => {
// const { phone, caption, title, subtitle, footer } = req.body;
// if (!sock || !isConnected) return res.status(400).json({ error: 'Non connecté' });
// try {
// const imagePath = path.join(__dirname, 'public', 'logo-merlo-cs-FR.jpg');
// const resizedBuffer = fs.readFileSync(imagePath);
// await sock.sendMessage(`${phone}@s.whatsapp.net`, {
// image: resizedBuffer,
// caption: caption || 'Description par défaut',
// title: title || 'Titre par défaut',
// subtitle: subtitle || 'Sous-titre',
// footer: footer || 'Pied de page',
// media: true,
// interactiveButtons: [
// {
// name: 'cta_url',
// buttonParamsJson: JSON.stringify({
// display_text: 'Proposition',
// url: 'https://merlo-ch.com/uploads/proposition/f_p_250505_0000136_00008_EB00001909.pdf'
// })
// },
// {
// name: 'cta_url',
// buttonParamsJson: JSON.stringify({
// display_text: 'Spec machine',
// url: 'https://merlo-ch.com/uploads/proposition/d_p_250505_0000136_00008_EB00001909.pdf'
// })
// }
// ]
// });
// res.json({ success: true });
// } catch (e) {
// console.error('❌ Erreur interactive image :', e);
// res.status(500).json({ error: e.message });
// }
// });
app.listen(3001, () => console.log('🚀 Serveur Baileys démarré sur http://localhost:3001'));