diff --git a/index.js b/index.js index ce61b4b..ca92913 100644 --- a/index.js +++ b/index.js @@ -161,432 +161,17 @@ app.post('/sendText', async (req, res) => { res.status(500).json({ error: e.message }); } }); -app.post('/testButtons', async (req, res) => { - const { phone } = req.body; - - if (!sock || !isConnected) { - return res.status(400).json({ error: 'Non connecté' }); - } - - const jid = `${phone}@s.whatsapp.net`; - - try { - await sock.sendMessage(jid, { - image: { url : "https://wa.canguidev.fr/static/logo-merlo-cs-FR.jpg" }, // Can buffer - text: "Hello Wolrd !;", - caption: "Description Of Messages", //Additional information - footer: "© Fizzxy Dev", - media:true, - image: { - url: 'https://wa.canguidev.fr/static/logo-merlo-cs-FR.jpg' - }, - buttons: [ - { - buttonId: '.tes', - buttonText: { - displayText: 'TESTING BOT' - }, - type: 1 - }, - { - buttonId: ' ', - buttonText: { - displayText: 'PRIVATE SCRIPT' - }, - type: 1 - }, - { - buttonId: 'action', - buttonText: { - displayText: 'ini pesan interactiveMeta' - }, - type: 4, - nativeFlowInfo: { - name: 'single_select', - paramsJson: JSON.stringify({ - title: 'message', - sections: [ - { - title: 'FizzxyDev - 2025', - highlight_label: '😜', - rows: [ - { - header: 'HEADER', - title: 'TITLE', - description: 'DESCRIPTION', - id: 'YOUR ID 1' - }, - { - header: 'HEADER', - title: 'TITLE', - description: 'DESCRIPTION', - id: 'YOUR ID 2' - } - ] - } - ] - }) - } - } - ], - headerType: 1, - viewOnce: true - }, { - quoted: null // ou tu peux injecter un msg pour reply ici - }); - - res.json({ success: true }); - } catch (e) { - console.error('❌ Erreur testButtons :', 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é' }); - } - - const BASE_URL = process.env.BASE_URL || 'https://wa.canguidev.fr'; - const imageUrl = `${BASE_URL}/static/logo-merlo-cs-FR.jpg`; - const jid = `${phone}@s.whatsapp.net`; - - try { - const content = { - viewOnceMessage: { - message: { - messageContextInfo: { - deviceListMetadata: {}, - deviceListMetadataVersion: 2 - }, - interactiveMessage: proto.Message.InteractiveMessage.create({ - body: { text: "Bienvenue sur notre service !" }, - footer: { text: "Choisis une action ci-dessous" }, - header: { - hasMediaAttachment: true, - imageMessage: { url: imageUrl } - }, - 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" - }) - }, - { - name: "cta_call", - buttonParamsJson: JSON.stringify({ - display_text: "📞 Appeler le support", - id: "+33612345678" - }) - } - ] - } - }) - } - } - }; - - const msg = generateWAMessageFromContent(jid, content, {}); - await sock.relayMessage(jid, 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 }); - } -}); - - -// Votre route POST -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é à WhatsApp' }); - } - - try { - const BASE_URL = process.env.BASE_URL || 'https://wa.canguidev.fr'; - const imageUrl = `${BASE_URL}/static/logo-merlo-cs-FR.jpg`; - - // Construire le Header correct - const header = proto.Message.InteractiveMessage.create({ - // ici on injecte l'image dans le header sans besoin de type explicite - header: proto.Message.InteractiveMessage.Header.create({ - title: 'Igna', - subtitle: 'test' - }), - }) - // Body et Footer - const body = proto.Message.InteractiveMessage.Body.create({ - text: caption || 'Description par défaut' - }); - const foot = proto.Message.InteractiveMessage.Footer.create({ - text: footer || 'Pied de page' - }); - - // Vos boutons URL - const nativeFlow = proto.Message.InteractiveMessage.NativeFlowMessage.create({ - buttons: [ - { - name: 'cta_url', - buttonParamsJson: JSON.stringify({ - display_text: '📄 Voir 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' - }) - } - ] - }); - - // Construire l'InteractiveMessage complet - const interactiveMsg = proto.Message.InteractiveMessage.create({ - header, - body, - footer: foot, - nativeFlowMessage: nativeFlow - }); - - // Envelopper (ici dans viewOnceMessage, comme dans votre exemple) - const raw = { - viewOnceMessage: { - message: { - messageContextInfo: { - deviceListMetadata: {}, - deviceListMetadataVersion: 2 - }, - interactiveMessage: interactiveMsg - } - } - }; - - // Générer et relayer - const jid = `${phone}@s.whatsapp.net`; - const msg = generateWAMessageFromContent(jid, raw, {}); - await sock.relayMessage(jid, msg.message, { messageId: msg.key.id }); - - return res.json({ success: true }); - } catch (e) { - console.error('❌ Erreur /sendInteractiveImage :', e); - return res.status(500).json({ error: e.message }); - } -}); - -app.post('/sendInteractiveImage2', 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.post('/sendProductMessage', async (req, res) => { - // On vérifie sock et isConnected, pas client - if (!sock || !isConnected) { - return res.status(400).json({ error: 'Non connecté à WhatsApp' }); - } - - const { - phone, - productImageUrl, - productImageCount, - productTitle, - productDescription, - priceAmount1000, - currencyCode, - retailerId, - productUrl, - businessOwnerJid, - caption, - messageTitle, - footer, - interactiveButtons = [], - quoted - } = req.body; - - try { - const jid = `${phone}@s.whatsapp.net`; - - await sock.sendMessage( - jid, - { - product: { - productImage: { url: productImageUrl }, - productImageCount, - title: productTitle, - description: productDescription, - priceAmount1000, - currencyCode, - retailerId, - url: productUrl, - }, - businessOwnerJid, - caption, - title: messageTitle, - footer, - media: true, - interactiveButtons - }, - quoted ? { quoted } : {} - ); - - - return res.json({ success: true }); - } catch (e) { - console.error('❌ Erreur /sendProductMessage :', e); - return res.status(500).json({ error: e.message }); - } -}); -app.post('/testViewOnce', async (req, res) => { - const { phone } = req.body; - - if (!sock || !isConnected) { - return res.status(400).json({ error: 'Non connecté' }); - } - - const jid = `${phone}@s.whatsapp.net`; - - try { - await sock.sendMessage(jid, { - image: { - url: 'https://wa.canguidev.fr/static/logo-merlo-cs-FR.jpg' // Ton image publique - }, - viewOnce: true, - caption: 'Voici une image à affichage unique 📷' - }); - - res.json({ success: true }); - } catch (e) { - console.error('❌ Erreur testViewOnce :', e); - res.status(500).json({ error: e.message }); - } -}); - - -app.post('/testHeaderImage', async (req, res) => { - const { phone } = req.body; - - if (!sock || !isConnected) { - return res.status(400).json({ error: 'Non connecté' }); - } - - const jid = `${phone}@s.whatsapp.net`; - - try { - // 1. Charger l'image locale - const imagePath = path.join(__dirname, 'public/logo-merlo-cs-FR.jpg'); - const imageBuffer = fs.readFileSync(imagePath); - - - const generate = async (type, url) => { - const generated = await generateWAMessageContent({ - [type]: { url } - }, { - upload: sock.waUploadToServer - }) - return generated[`${type}Message`] - } - // 3. Créer le message interactif avec image dans le header - - const msg = generateWAMessageFromContent(jid.remoteJid, { - viewOnceMessage: { - message: { - messageContextInfo: { - deviceListMetadata: {}, - deviceListMetadataVersion: 2 - }, - interactiveMessage: proto.Message.InteractiveMessage.create({ - body: proto.Message.InteractiveMessage.Body.create({ - text: "body text (optional)" - }), - footer: proto.Message.InteractiveMessage.Footer.create({ - text: "footer text (optional)" - }), - header: proto.Message.InteractiveMessage.Header.create({ - title: "some title", - hasMediaAttachment: false, // false if you don't want to send media with it - //imageMessage: generate("image", "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/TEIDE.JPG/500px-TEIDE.JPG"), - //videoMessage: generate("video", "url/path to video"), // if it's an video - }), - nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ - buttons: [{ - name: "quick_reply", - buttonParamsJson: JSON.stringify({ - display_text: "button 1", // <-- displayed text - id: ".menu" // <-- this is the id or you may call it command 🤷‍♂️ - }) // REMEMBER TO USE "JSON.stringify()" BECAUSE "buttonParamsJson" ONLY ACCEPTING STIRNG JSON, NOT AN OBJECT - },{ - name: "cta_url", - buttonParamsJson: JSON.stringify({ - display_text: "subscribe my Youtube!", - url: "https://youtube.com/@fannmods", - merchant_url: "https://youtube.com" - }) - }] - }) - }) - } - } - }, {}) - console.log(msg.message) - // 4. Envoyer le message - await sock.relayMessage(jid, msg.message, { messageId: msg.key.id }); - - res.json({ success: true }); - } catch (e) { - console.error('❌ Erreur testHeaderImage :', e); - res.status(500).json({ error: e.message }); - } -}); +//// ***** bonne route ****** /// +/* exemple de json +*{ + "phone": "33617452235", + "imageUrl": "https://wa.canguidev.fr/static/logo-merlo-cs-FR.jpg", + "caption": "🟢 Offre spéciale !\n📅 Merlo2025\n\nBonjour M. Jérôme VANDEMEULEBROUCK,\n\nSuite à nos échanges, je vous transmets l'offre que je vous propose.\nVous trouverez ci-joint votre offre au format PDF.\n\n📄 Proposition : https://pvmel.fr/V5Pi\n🛠️ Descriptif machine : \n\n—\nCanguilième Julien\n📎 Votre offre en PDF ci-joint." +} +* +*/ app.post('/sendImageWithBaileysPro', async (req, res) => { if (!sock || !isConnected) { return res.status(400).json({ error: 'Non connecté à WhatsApp' }); @@ -623,9 +208,6 @@ app.post('/sendImageWithBaileysPro', async (req, res) => { } }); - - -// 5) 404 et gestion des erreurs app.use((req, res) => res.status(404).json({ error: 'Ressource introuvable' })); app.use((err, req, res, next) => { console.error('Middleware d’erreur :', err); diff --git a/old.js b/old.js new file mode 100644 index 0000000..e3d22f9 --- /dev/null +++ b/old.js @@ -0,0 +1,424 @@ +app.post('/testButtons', async (req, res) => { + const { phone } = req.body; + + if (!sock || !isConnected) { + return res.status(400).json({ error: 'Non connecté' }); + } + + const jid = `${phone}@s.whatsapp.net`; + + try { + await sock.sendMessage(jid, { + image: { url : "https://wa.canguidev.fr/static/logo-merlo-cs-FR.jpg" }, // Can buffer + text: "Hello Wolrd !;", + caption: "Description Of Messages", //Additional information + footer: "© Fizzxy Dev", + media:true, + image: { + url: 'https://wa.canguidev.fr/static/logo-merlo-cs-FR.jpg' + }, + buttons: [ + { + buttonId: '.tes', + buttonText: { + displayText: 'TESTING BOT' + }, + type: 1 + }, + { + buttonId: ' ', + buttonText: { + displayText: 'PRIVATE SCRIPT' + }, + type: 1 + }, + { + buttonId: 'action', + buttonText: { + displayText: 'ini pesan interactiveMeta' + }, + type: 4, + nativeFlowInfo: { + name: 'single_select', + paramsJson: JSON.stringify({ + title: 'message', + sections: [ + { + title: 'FizzxyDev - 2025', + highlight_label: '😜', + rows: [ + { + header: 'HEADER', + title: 'TITLE', + description: 'DESCRIPTION', + id: 'YOUR ID 1' + }, + { + header: 'HEADER', + title: 'TITLE', + description: 'DESCRIPTION', + id: 'YOUR ID 2' + } + ] + } + ] + }) + } + } + ], + headerType: 1, + viewOnce: true + }, { + quoted: null // ou tu peux injecter un msg pour reply ici + }); + + res.json({ success: true }); + } catch (e) { + console.error('❌ Erreur testButtons :', 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é' }); + } + + const BASE_URL = process.env.BASE_URL || 'https://wa.canguidev.fr'; + const imageUrl = `${BASE_URL}/static/logo-merlo-cs-FR.jpg`; + const jid = `${phone}@s.whatsapp.net`; + + try { + const content = { + viewOnceMessage: { + message: { + messageContextInfo: { + deviceListMetadata: {}, + deviceListMetadataVersion: 2 + }, + interactiveMessage: proto.Message.InteractiveMessage.create({ + body: { text: "Bienvenue sur notre service !" }, + footer: { text: "Choisis une action ci-dessous" }, + header: { + hasMediaAttachment: true, + imageMessage: { url: imageUrl } + }, + 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" + }) + }, + { + name: "cta_call", + buttonParamsJson: JSON.stringify({ + display_text: "📞 Appeler le support", + id: "+33612345678" + }) + } + ] + } + }) + } + } + }; + + const msg = generateWAMessageFromContent(jid, content, {}); + await sock.relayMessage(jid, 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 }); + } + }); + + + // Votre route POST + 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é à WhatsApp' }); + } + + try { + const BASE_URL = process.env.BASE_URL || 'https://wa.canguidev.fr'; + const imageUrl = `${BASE_URL}/static/logo-merlo-cs-FR.jpg`; + + // Construire le Header correct + const header = proto.Message.InteractiveMessage.create({ + // ici on injecte l'image dans le header sans besoin de type explicite + header: proto.Message.InteractiveMessage.Header.create({ + title: 'Igna', + subtitle: 'test' + }), + }) + // Body et Footer + const body = proto.Message.InteractiveMessage.Body.create({ + text: caption || 'Description par défaut' + }); + const foot = proto.Message.InteractiveMessage.Footer.create({ + text: footer || 'Pied de page' + }); + + // Vos boutons URL + const nativeFlow = proto.Message.InteractiveMessage.NativeFlowMessage.create({ + buttons: [ + { + name: 'cta_url', + buttonParamsJson: JSON.stringify({ + display_text: '📄 Voir 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' + }) + } + ] + }); + + // Construire l'InteractiveMessage complet + const interactiveMsg = proto.Message.InteractiveMessage.create({ + header, + body, + footer: foot, + nativeFlowMessage: nativeFlow + }); + + // Envelopper (ici dans viewOnceMessage, comme dans votre exemple) + const raw = { + viewOnceMessage: { + message: { + messageContextInfo: { + deviceListMetadata: {}, + deviceListMetadataVersion: 2 + }, + interactiveMessage: interactiveMsg + } + } + }; + + // Générer et relayer + const jid = `${phone}@s.whatsapp.net`; + const msg = generateWAMessageFromContent(jid, raw, {}); + await sock.relayMessage(jid, msg.message, { messageId: msg.key.id }); + + return res.json({ success: true }); + } catch (e) { + console.error('❌ Erreur /sendInteractiveImage :', e); + return res.status(500).json({ error: e.message }); + } + }); + + app.post('/sendInteractiveImage2', 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.post('/sendProductMessage', async (req, res) => { + // On vérifie sock et isConnected, pas client + if (!sock || !isConnected) { + return res.status(400).json({ error: 'Non connecté à WhatsApp' }); + } + + const { + phone, + productImageUrl, + productImageCount, + productTitle, + productDescription, + priceAmount1000, + currencyCode, + retailerId, + productUrl, + businessOwnerJid, + caption, + messageTitle, + footer, + interactiveButtons = [], + quoted + } = req.body; + + try { + const jid = `${phone}@s.whatsapp.net`; + + await sock.sendMessage( + jid, + { + product: { + productImage: { url: productImageUrl }, + productImageCount, + title: productTitle, + description: productDescription, + priceAmount1000, + currencyCode, + retailerId, + url: productUrl, + }, + businessOwnerJid, + caption, + title: messageTitle, + footer, + media: true, + interactiveButtons + }, + quoted ? { quoted } : {} + ); + + + return res.json({ success: true }); + } catch (e) { + console.error('❌ Erreur /sendProductMessage :', e); + return res.status(500).json({ error: e.message }); + } + }); + app.post('/testViewOnce', async (req, res) => { + const { phone } = req.body; + + if (!sock || !isConnected) { + return res.status(400).json({ error: 'Non connecté' }); + } + + const jid = `${phone}@s.whatsapp.net`; + + try { + await sock.sendMessage(jid, { + image: { + url: 'https://wa.canguidev.fr/static/logo-merlo-cs-FR.jpg' // Ton image publique + }, + viewOnce: true, + caption: 'Voici une image à affichage unique 📷' + }); + + res.json({ success: true }); + } catch (e) { + console.error('❌ Erreur testViewOnce :', e); + res.status(500).json({ error: e.message }); + } + }); + + + app.post('/testHeaderImage', async (req, res) => { + const { phone } = req.body; + + if (!sock || !isConnected) { + return res.status(400).json({ error: 'Non connecté' }); + } + + const jid = `${phone}@s.whatsapp.net`; + + try { + // 1. Charger l'image locale + const imagePath = path.join(__dirname, 'public/logo-merlo-cs-FR.jpg'); + const imageBuffer = fs.readFileSync(imagePath); + + + const generate = async (type, url) => { + const generated = await generateWAMessageContent({ + [type]: { url } + }, { + upload: sock.waUploadToServer + }) + return generated[`${type}Message`] + } + // 3. Créer le message interactif avec image dans le header + + const msg = generateWAMessageFromContent(jid.remoteJid, { + viewOnceMessage: { + message: { + messageContextInfo: { + deviceListMetadata: {}, + deviceListMetadataVersion: 2 + }, + interactiveMessage: proto.Message.InteractiveMessage.create({ + body: proto.Message.InteractiveMessage.Body.create({ + text: "body text (optional)" + }), + footer: proto.Message.InteractiveMessage.Footer.create({ + text: "footer text (optional)" + }), + header: proto.Message.InteractiveMessage.Header.create({ + title: "some title", + hasMediaAttachment: false, // false if you don't want to send media with it + //imageMessage: generate("image", "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/TEIDE.JPG/500px-TEIDE.JPG"), + //videoMessage: generate("video", "url/path to video"), // if it's an video + }), + nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ + buttons: [{ + name: "quick_reply", + buttonParamsJson: JSON.stringify({ + display_text: "button 1", // <-- displayed text + id: ".menu" // <-- this is the id or you may call it command 🤷‍♂️ + }) // REMEMBER TO USE "JSON.stringify()" BECAUSE "buttonParamsJson" ONLY ACCEPTING STIRNG JSON, NOT AN OBJECT + },{ + name: "cta_url", + buttonParamsJson: JSON.stringify({ + display_text: "subscribe my Youtube!", + url: "https://youtube.com/@fannmods", + merchant_url: "https://youtube.com" + }) + }] + }) + }) + } + } + }, {}) + console.log(msg.message) + // 4. Envoyer le message + await sock.relayMessage(jid, msg.message, { messageId: msg.key.id }); + + res.json({ success: true }); + } catch (e) { + console.error('❌ Erreur testHeaderImage :', e); + res.status(500).json({ error: e.message }); + } + }); \ No newline at end of file