From 1af6a5e308c9c74d695524a5ca41abad8c0deaa7 Mon Sep 17 00:00:00 2001 From: philc Date: Fri, 10 Apr 2026 10:55:57 +0200 Subject: [PATCH] force subscribe in brevo from notification --- apxtri/models/Notifications.js | 81 +++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/apxtri/models/Notifications.js b/apxtri/models/Notifications.js index 38b71b6..3f87c2a 100644 --- a/apxtri/models/Notifications.js +++ b/apxtri/models/Notifications.js @@ -9,7 +9,9 @@ const Checkjson = require(`./Checkjson.js`); const nodemailer = require("nodemailer"); const conf = require(`../../../adminapi/objects/tribes/itm/adminapi.json`); const currentmod = "Notifications"; -const log = process.env.ACTIVELOG ? process.env.ACTIVELOG.split(',').includes(currentmod) : false; +const log = process.env.ACTIVELOG + ? process.env.ACTIVELOG.split(",").includes(currentmod) + : false; /** * To manage any communication between Pagan * mayor druid emailing/sms/paper from tribe register smtp, simcard, mail api to Person(s) / Pagan(s) @@ -76,7 +78,7 @@ Notifications.registertolist = (key, typekey, tribe, mlist, srckey, uuid) => { const destin = `../${tribe}/objects/maillinglists/${typekey}_${mlist}.json`; if (!fs.existsSync(destin)) { console.log( - `######## Attention tentative d'ecriture non autorisé,le fichier n'existe pas ${destin} créer le à la main vide {}` + `######## Attention tentative d'ecriture non autorisé,le fichier n'existe pas ${destin} créer le à la main vide {}`, ); return { status: 406, @@ -140,7 +142,7 @@ Notifications.sendsms = async (data, tribeId) => { }; } let missingk = []; - ["To", "Text"].forEach((k) => { + ["To", "Text"].forEach((k) => { if (!data[k]) { missingk.push(k); } @@ -156,11 +158,11 @@ Notifications.sendsms = async (data, tribeId) => { let confsms = conf.sms; if ( fs.existsSync( - `../adminapi/objects/tribes/itm/${req.session.header.xtribe}.json` + `../adminapi/objects/tribes/itm/${req.session.header.xtribe}.json`, ) ) { const conftrib = fs.readJSONSync( - `../adminapi/objects/tribes/itm/${req.session.header.xtribe}.json` + `../adminapi/objects/tribes/itm/${req.session.header.xtribe}.json`, ); if (conftrib.sms) confsms = conftrib.sms; } @@ -216,7 +218,7 @@ Notifications.manageemail = async ( tribe, lg, numberpersecond = 10, - profils = ["anonymous"] + profils = ["anonymous"], ) => { const sleep = (ms) => { return new Promise((resolve) => setTimeout(resolve, ms)); @@ -269,7 +271,7 @@ Notifications.manageemail = async ( }); const tplemail = require(path.resolve(tplpath)); // check allowed profil - if (!tplemail.allowedprofils){ + if (!tplemail.allowedprofils) { return { status: 406, ref: "Notification", @@ -277,14 +279,14 @@ Notifications.manageemail = async ( data: { template: tplpath }, }; } - if (!profils.includes('druid')){ - const setallow = new Set(tplemail.allowedprofils) - if (profils.filter(v=> setallow.has(v)).length==0){ + if (!profils.includes("druid")) { + const setallow = new Set(tplemail.allowedprofils); + if (profils.filter((v) => setallow.has(v)).length == 0) { return { status: 403, ref: "Notification", msg: "profilsnotallowed", - data: { template: tplpath,profils }, + data: { template: tplpath, profils }, }; } } @@ -340,7 +342,7 @@ Notifications.manageemail = async ( } fs.outputJSONSync( `../${tribe}/logs/campains/${templatename}_${lg}_${Date.now()}`, - results + results, ); return { status: 200, @@ -394,6 +396,26 @@ Notifications.sendmail = async (data, tribe) => { * * */ + async function ensureContact(email,BREVO_APIKEY) { + try { + await axios.post( + "https://api.brevo.com/v3/contacts", + { + email: email, + emailBlacklisted: false, + updateEnabled: true, + }, + { + headers: { + "api-key": BREVO_APIKEY, + "Content-Type": "application/json", + }, + }, + ); + } catch (err) { + console.log("Brevo contact error:", err.response?.data || err.message); + } + } if (!conf.smtp || !conf.emailcontact) { return { status: 412, @@ -408,7 +430,7 @@ Notifications.sendmail = async (data, tribe) => { } let missingk = []; - ["from", "to", "subject", "html", "text"].forEach((k) => { + ["from", "to", "subject", "html", "text"].forEach((k) => { if (!data[k]) { missingk.push(k); } @@ -437,6 +459,10 @@ Notifications.sendmail = async (data, tribe) => { if (!data.from || data.from == conf.emailcontact) data.from = conftrib.emailcontact; } + const toEmails = data.to.split(","); + for (const email of toEmails) { + await ensureContact(email,conftrib.BREVO.APIKEY); + } //console.log(confsmtp); const transporter = await nodemailer.createTransport(confsmtp); if (data.filelist) { @@ -447,7 +473,7 @@ Notifications.sendmail = async (data, tribe) => { data.attachments.push({ filename: fo.filename || path.basename(fo.pathfile), path: fo.pathfile, - contentType: fo.contenttype || 'application/octet-stream' + contentType: fo.contenttype || "application/octet-stream", }); } else { missingfile.push(fo.pathfile); @@ -482,7 +508,7 @@ Notifications.sendmail = async (data, tribe) => { */ fs.outputFile( `../${tribe}/logs/template/${data.templatename}_${data.lg}.html`, - data.html + data.html, ); try { @@ -494,15 +520,26 @@ Notifications.sendmail = async (data, tribe) => { } else { error = err; } - } - console.log("sendmail result:", res); + } + console.log("sendmail result:", res); if (res && res.accepted) { // Normalize emails for comparison - const normalizedAccepted = res.accepted.map(email => email.trim().toLowerCase()); - const toEmails = data.to.split(",").map(email => email.trim().toLowerCase()); - console.log("normalizedAccepted:", normalizedAccepted, "toEmails:", toEmails); - const allAccepted = toEmails.every(email => normalizedAccepted.includes(email)); - + const normalizedAccepted = res.accepted.map((email) => + email.trim().toLowerCase(), + ); + const toEmails = data.to + .split(",") + .map((email) => email.trim().toLowerCase()); + console.log( + "normalizedAccepted:", + normalizedAccepted, + "toEmails:", + toEmails, + ); + const allAccepted = toEmails.every((email) => + normalizedAccepted.includes(email), + ); + if (allAccepted && (!res.rejected || res.rejected.length === 0)) { data.accepted = res.accepted; data.rejected = res.rejected;