From 3ec01054553ff5c8219cf5f82d61c92c5f4bc57b Mon Sep 17 00:00:00 2001 From: philc Date: Thu, 11 Jul 2024 13:29:54 +0200 Subject: [PATCH] modif for docapi --- models/Notifications.js | 148 ++++++++++++++++++++++++----------- routes/notifications.js | 169 ++++++++++++++++++++++++++-------------- 2 files changed, 212 insertions(+), 105 deletions(-) diff --git a/models/Notifications.js b/models/Notifications.js index 4c54b96..85031e9 100644 --- a/models/Notifications.js +++ b/models/Notifications.js @@ -30,47 +30,59 @@ Notifications.get = (alias, tribeId) => { /** * Get statistic of registering email phone */ -Notifications.statmaillist=(tribe)=>{ - const statinfo={} - let csv="email/phone;name;srckey\n" - const src=`../../${tribe}/objects/maillinglists/*.json` - console.log(path.resolve(src)) - glob.sync(src).forEach(f=>{ - const name=path.basename(f,".json"); - const mlst=fs.readJSONSync(f) - Object.keys(mlst).forEach(c=>{ - csv+=`"${c}";"${name}";"${mlst[c].srckeys.join('-')}"\n` - mlst[c].srckeys.forEach(s=>{ - if (!statinfo[s]) statinfo[s]={} - if (!statinfo[s][name]) statinfo[s][name]=0 - statinfo[s][name]++ - }) - }) - }) +Notifications.statmaillist = (tribe) => { + const statinfo = {}; + let csv = "email/phone;name;srckey\n"; + const src = `../../${tribe}/objects/maillinglists/*.json`; + console.log(path.resolve(src)); + glob.sync(src).forEach((f) => { + const name = path.basename(f, ".json"); + const mlst = fs.readJSONSync(f); + Object.keys(mlst).forEach((c) => { + csv += `"${c}";"${name}";"${mlst[c].srckeys.join("-")}"\n`; + mlst[c].srckeys.forEach((s) => { + if (!statinfo[s]) statinfo[s] = {}; + if (!statinfo[s][name]) statinfo[s][name] = 0; + statinfo[s][name]++; + }); + }); + }); // fichier csv stocker en local en attendant d'avoir un back pour stocker la reponse dans data.csv - fs.outputFileSync(`../../${tribe}/mailinglst.csv`,csv,"utf-8"); - return {status:200,ref:"Notifications",msg:"statistics",data:statinfo} -} + fs.outputFileSync(`../../${tribe}/mailinglst.csv`, csv, "utf-8"); + return { + status: 200, + ref: "Notifications", + msg: "statistics", + data: statinfo, + }; +}; /** * Register an typekey(email) or (phone) key into mailinglist for a tribe - * + * */ Notifications.registertolist = (key, typekey, tribe, mlist, srckey, uuid) => { key = key.toLowerCase(); - typekey= (typekey=="telephone")? "telephonefr":typekey; + typekey = typekey == "telephone" ? "telephonefr" : typekey; if (!Checkjson.testformat(key, typekey)) return { status: 400, ref: "Notifications", msg: "formaterror", - data: { fielderr: typekey, format: typekey } + data: { fielderr: typekey, format: typekey }, }; 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 {}`) - return {status:406,ref:"Notifications",msg:"destinnotallow",data:{destin}} + if (!fs.existsSync(destin)) { + console.log( + `######## Attention tentative d'ecriture non autorisé,le fichier n'existe pas ${destin} créer le à la main vide {}` + ); + return { + status: 406, + ref: "Notifications", + msg: "destinnotallow", + data: { destin }, + }; } const filestorage = fs.existsSync(destin) ? fs.readJsonSync(destin) : {}; @@ -81,28 +93,30 @@ Notifications.registertolist = (key, typekey, tribe, mlist, srckey, uuid) => { filestorage[key].srckeys.push(srckey); if (!filestorage[key].uuids.includes(uuid)) filestorage[key].uuids.push(uuid); - }else{ - filestorage[key]={} - filestorage[key].dt_create=dayjs().toISOString(); - filestorage[key].srckeys=[srckey]; - filestorage[key].uuids=[uuid] + } else { + filestorage[key] = {}; + filestorage[key].dt_create = dayjs().toISOString(); + filestorage[key].srckeys = [srckey]; + filestorage[key].uuids = [uuid]; } fs.outputJSONSync(destin, filestorage); - return {status:200,ref:"Notifications",msg:"registersuccess",data:{key, typekey, tribe, mlist, srckey, uuid}} -} + return { + status: 200, + ref: "Notifications", + msg: "registersuccess", + data: { key, typekey, tribe, mlist, srckey, uuid }, + }; +}; /** * Unsubscribe an eamil or phone from a mailinglist for a tribe */ -Notifications.unregisterfromlist = (key, typekey, tribe,mlist) => { +Notifications.unregisterfromlist = (key, typekey, tribe, mlist) => { key = key.toLowerCase(); - -} +}; /** * Message to send to an alias from an anonymous or not */ -Notifications.sendcontact = (body, header) => { - -} +Notifications.sendcontact = (body, header) => {}; Notifications.sendsms = async (data, tribeId) => { /** * Never use need wallet in mailjet to test @@ -138,11 +152,7 @@ Notifications.sendsms = async (data, tribeId) => { }; } let confsms = conf.sms; - if ( - fs.existsSync( - `../../itm/${req.session.header.xtribe}.json` - ) - ) { + if (fs.existsSync(`../../itm/${req.session.header.xtribe}.json`)) { const conftrib = fs.readJSONSync( `../../itm/${req.session.header.xtribe}.json` ); @@ -195,6 +205,49 @@ Notifications.sendsms = async (data, tribeId) => { */ }; +Notifications.manageemail = (data, template, tribe) => { + /** + * Manage email publipostage + * data must contain emailsto + * data optionaly can contain Cc,Bcc as array of emails and attachments as array of filename (into the server) + * Await the 1st email + */ + + if (!data.emailsto || data.emailsto.length == 0) { + return { + status: 406, + ref: "Notifications", + msg: "emailsmissing", + data: data, + }; + } + if (typeof data.emailsto === "string") data.emailsto = [data.emailsto]; + const tplemail = require(path.resolve(template)); + let sendit; + data.emailsto.forEach(async (e, i) => { + if (Checkjson.testformat(e, "email")) { + const dat = {}; + dat.to = e; + dat.subject = Mustache.render(tplemail.subject, data); + dat.html = Mustache.render(tplemail.subject, data); + dat.text = Mustache.render(tplemail.text, data); + dat.Cc = data.Cc ? tplemail.Cc.push(data.Cc) : tplemail.Cc; + dat.Bcc = data.Bcc ? tplemail.Bcc.push(data.Bcc) : tplemail.Bcc; + dat.attachments = tplemail.attachments.push(data.attachments); + const sendit = Notifications.sendmail(data, tribe); + if (i == 0) { + sendit = await Notifications.sendmail(data, tribe); + if (sendit.status != 200) return sendit; + } else { + Notifications.sendmail(data, tribe); + } + } else { + // not a well formated email + } + }); + return sendit; +}; + Notifications.sendmail = async (data, tribe) => { /** * See https://nodemailer.com/message/ for available fields to add @@ -205,7 +258,7 @@ Notifications.sendmail = async (data, tribe) => { * @param {string} data.text * @param {string} [data.Cc] list of email in copy * @param {string} [data.Bcc] list of email in hidden copy - * @param {string} [data.attachments] array of + * @param {string} [data.attachments] array of * {filename:'filename.txt',content:'txt'}, * {filename:'img.svg',path:"https://....svg", contentType:'image/svg'} * {filename:'img.svg',path:"https://....svg", contentType :'text/plain'} @@ -264,8 +317,9 @@ Notifications.sendmail = async (data, tribe) => { let missingfile = []; data.filelist.forEach((fo) => { if (fs.existsSync(fo.pathfile)) { - - } else { missingfile.push(fo.pathfile); } + } else { + missingfile.push(fo.pathfile); + } }); if (missingfile.lenght > 0) return { diff --git a/routes/notifications.js b/routes/notifications.js index 6b7172b..d0026a4 100644 --- a/routes/notifications.js +++ b/routes/notifications.js @@ -8,27 +8,24 @@ const isAuthenticated = require("../middlewares/isAuthenticated"); const router = express.Router(); - /** * wait Sagar feedback for language and label description * @ api {post} /api/notifications/backend - Notification Backend post * @apiName notifBackend * @apiDescription Send an api result {status,ref,msg,data} to get personnalize notification by header.xlang abd by data * @apiGroup Notification - * - * @apiBody {integer} status an http status + * + * @apiBody {integer} status an http status * @apiBody {string} ref an existing model name - * @apiBody {string} msg a key word existing in referentiual + * @apiBody {string} msg a key word existing in referentiual * */ -router.post("/backend", (req, res) => { - -}) +router.post("/backend", (req, res) => {}); /** - * @api {get} adminapi/notifications/:alias/:tribeId + * @api {get} adminapi/notifications/messages/:alias/:tribeId -Get message list for alias in tribe * @apiName notiflist - * @apiDescription Get list of notifications for an alias and a tribe + * @apiDescription Get list of notifications for an alias and a tribe * @apiGroup Notifications * * @apiParam {string} alias @@ -39,11 +36,49 @@ router.post("/backend", (req, res) => { * {status:200,ref:"Notification",msg:"Messagelist",data:{notif:[{tribeId,msg:{from(email or uuid or alias):[{dt,msg}]}}]} * bouture **/ -router.get("/:alias/:tribeId", (req, res) => { +router.get("/messages/:alias/:tribeId", (req, res) => { const getnot = Notification.get(req.params.alias, req.params.tribeId); res.status(getalias.status).send(getalias); }); +/** + * @api {POST} adminapi/notifications/sendmail/:tribe/:template -Send personnalize emails + * @apiName Sendmail + * @apiDescription Send personnalize email with data from template store in ../../{tribe}/template/{template}.json + * @apiGroup Notifications + * + * @apiParam {string} template + * @apiParam {string} tribe + * @apiBody {array} emails to send (array of valid email) + * @apiBody {object} Data to personnalize template + * + * @apiSuccess {object} notif content + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * {status:200,ref:"Notification",msg:"Messagelist",data:{notif:[{tribeId,msg:{from(email or uuid or alias):[{dt,msg}]}}]} + * bouture + */ +router.post( + "/sendmail/:tribe/:template/:await", + checkHeaders, + isAuthenticated, + (req, res) => { + const pathtpl = `../../${req.params.tribe}/${req.params.template}.js`; + if (fs.existsSync(pathtpl)) { + const sendemail = Notification.manageemail(req.body, pathtpl,req.params.tribe); + res.status(sendemail.status).send(sendemail); + } else { + res + .status(404) + .send({ + status: 404, + ref: "Notification", + msg: "templatenotfound", + data: { pathtpl }, + }); + } + } +); /** * @api {POST} adminapi/notifications/registeranonymous/:tribe/:mlist/:typekey/:data -Register email||phone to mlist @@ -51,60 +86,75 @@ router.get("/:alias/:tribeId", (req, res) => { * @apiGroup Notifications * @apiDescription Register an email or phone into a mailinglist mlist * @apiBody {string} tribe an existing tribe - * @apiBody {string} mlist a mailing list name + * @apiBody {string} mlist a mailing list name * @apiBody {string} key email or phone keyword - * @apiBod {string} srckey must exist in tribes/schema/lg/enumtrk_xx.json + * @apiBod {string} srckey must exist in tribes/schema/lg/enumtrk_xx.json * @apiParams {string} data the email or phone value * @apiSuccess {object} update mailinglist/{mlist}.json successfull * @apiSuccessExample {json} successfullmessage * HTTP/1.1 200 OK * {"status":200, "ref":"Notifications", "msg":"registersuccess", "data":{data, typekey, tribe, mlist, srckey, uuid}}} - * + * */ -router.post("/registeranonymous",checkHeaders,(req,res)=>{ +router.post("/registeranonymous", checkHeaders, (req, res) => { //console.log("list registration ",req.body) - if (!req.body.typekey || !['email','telephone'].includes(req.body.typekey) ){ - return res.status(406).json({status:406,ref:"Notifications",msg:"typekeyunknown",data:{typekey:req.body.typekey}}) + if (!req.body.typekey || !["email", "telephone"].includes(req.body.typekey)) { + return res + .status(406) + .json({ + status: 406, + ref: "Notifications", + msg: "typekeyunknown", + data: { typekey: req.body.typekey }, + }); } - const key= (req.body.contactpoint)?req.body.contactpoint:req.body[req.body.typekey]; - result= Notifications.registertolist( - key, - req.body.typekey, - req.body.tribe, - req.body.mlist, - req.body.srckey, - req.session.header.xuuid); - - res.status(result.status).json(result) -}) + const key = req.body.contactpoint + ? req.body.contactpoint + : req.body[req.body.typekey]; + result = Notifications.registertolist( + key, + req.body.typekey, + req.body.tribe, + req.body.mlist, + req.body.srckey, + req.session.header.xuuid + ); + + res.status(result.status).json(result); +}); /** - * @api {GET} adminapi/notifications/unregister/:tribe/:mlist/:typekey/:data/:validation -Unregister email o r phone from a mlist or all mlist + * @api {GET} adminapi/notifications/unregister/:tribe/:mlist/:typekey/:data/:validation -Unregister email or phone from a mlist or all mlist * @apiName unregister * @apiGroup Notifications * @apiDescription Register an email into a mailinglist mlist * @apiParams {string} tribe an existing tribe - * @apiParams {string} mlist a mailing list name + * @apiParams {string} mlist a mailing list name * @apiParams {string} key email or phone - * @apiParams {string} srckey must exist in tribes/schema/lg/enumtrk_xx.json + * @apiParams {string} srckey must exist in tribes/schema/lg/enumtrk_xx.json * @apiParams {string} data the email or phone - * @apiParams {string} validation a key store in /tmp waiting to be approved, if "request" then send an email for confirmation, else if exist then remove email from list. + * @apiParams {string} validation a key store in /tmp waiting to be approved, if "request" then send an email for confirmation, else if exist then remove email from list. * @apiSuccess {object} update mailinglist/{mlist}.json successfull * @apiSuccessExample {json} successfullmessage * HTTP/1.1 200 OK * {"status":200, "ref":"Notifications", "msg":"registersuccess", "data":{data, typekey, tribe, mlist, srckey, uuid}}} - * + * */ -router.get("/unregister/:tribe/:mlist/:typekey/:srckey/:data/:validation", checkHeaders, (req, res) => { - Notifications.registertolist = (typekey, tribe, mlist, srckey, uuid) - result= Notifications.registertolist( - req.params.typekey, - req.params.tribe, - req.params.mlist, - req.params.srckey, - req.session.header.xuuid); - res.status(result.status).json(result) -}) +router.get( + "/unregister/:tribe/:mlist/:typekey/:srckey/:data/:validation", + checkHeaders, + (req, res) => { + Notifications.registertolist = (typekey, tribe, mlist, srckey, uuid); + result = Notifications.registertolist( + req.params.typekey, + req.params.tribe, + req.params.mlist, + req.params.srckey, + req.session.header.xuuid + ); + res.status(result.status).json(result); + } +); /** * @api {GET} adminapi/notifications/stat/maillinglst/:tribe --Statistic maillinglst @@ -112,7 +162,7 @@ router.get("/unregister/:tribe/:mlist/:typekey/:srckey/:data/:validation", check * @apiGroup Notifications * @apiDescription Mailling list statistique * @apiParams {string} tribe an existing tribe - * + * * @apiSuccess {object} with data results * @apiSuccessExample {json} successfullmessage * HTTP/1.1 200 OK @@ -137,16 +187,14 @@ router.get("/unregister/:tribe/:mlist/:typekey/:srckey/:data/:validation", check * } * } *} - * + * */ router.get("/stat/maillinglst/:tribe", checkHeaders, async (req, res) => { - console.log('passe là'); - const resstat=Notifications.statmaillist(req.params.tribe) + console.log("passe là"); + const resstat = Notifications.statmaillist(req.params.tribe); res.status(resstat.status).json(resstat); }); - - /** * @api {POST} adminapi/notifications/contactanonymous/:tribe -Contact anonymous * @apiName contactanonymous @@ -156,12 +204,12 @@ router.get("/stat/maillinglst/:tribe", checkHeaders, async (req, res) => { * @apiBody {string} srckey: where it come from and eventualy email template name to use to send email , * @apiBody {string} email to recontact * @apiBody {string} others any other usefull key:value - * + * * @apiSuccess {object} create/update tribe/contacts/{}.json successfull * @apiSuccessExample {json} successfullmessage * HTTP/1.1 200 OK * {"status":200, "ref":"Contact", "msg":"success", "data":{"indexlist":[]}} - * + * */ router.post("/contactanonymous", checkHeaders, async (req, res) => { const done = Actions[req.body.order] @@ -173,16 +221,21 @@ router.post("/contactanonymous", checkHeaders, async (req, res) => { /** * Same as /copntactanonymous but for authenticated user => data are updated in persons/itm/alias.json */ -router.post("/contact/:tribe/:alias", checkHeaders, isAuthenticated, (req, res) => { - const done = Actions[req.body.order] - ? Actions[req.body.order](req.body, req.session.header) - : { status: 406, ref: "Actions", msg: "bodyerror", data: req.body }; - console.log(req.body); - res.status(done.status).json(done); -}); +router.post( + "/contact/:tribe/:alias", + checkHeaders, + isAuthenticated, + (req, res) => { + const done = Actions[req.body.order] + ? Actions[req.body.order](req.body, req.session.header) + : { status: 406, ref: "Actions", msg: "bodyerror", data: req.body }; + console.log(req.body); + res.status(done.status).json(done); + } +); router.get("/contact", checkHeaders, isAuthenticated, (req, res) => { res.status(200).json({ data: {} }); }); -module.exports = router; \ No newline at end of file +module.exports = router;