web-dev-qa-db-fra.com

Passer la variable au template HTML dans nodemailer

Je veux envoyer un email avec nodemailer en utilisant un modèle HTML. Dans ce modèle, je dois injecter dynamiquement des variables et je ne peux vraiment pas le faire. Mon code:

var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');

smtpTransport = nodemailer.createTransport(smtpTransport({
    Host: mailConfig.Host,
    secure: mailConfig.secure,
    port: mailConfig.port,
    auth: {
        user: mailConfig.auth.user,
        pass: mailConfig.auth.pass
    }
}));
var mailOptions = {
    from: '[email protected]',
    to : '[email protected]',
    subject : 'test subject',
    html : { path: 'app/public/pages/emailWithPDF.html' }
};
smtpTransport.sendMail(mailOptions, function (error, response) {
    if (error) {
        console.log(error);
        callback(error);
    }
});

Disons que je veux dans emailWithPDF.html quelque chose comme ceci:

Hello {{username}}!

J'ai trouvé quelques exemples, où était par exemple:

...
html: '<p>Hello {{username}}</p>'
...

mais je le veux dans un fichier HTML séparé. C'est possible?

15
Wacław Łabuda

Ce que vous pouvez faire est de lire le fichier HTML en utilisant le module fs dans le noeud, puis de remplacer les éléments que vous souhaitez modifier dans la chaîne html en utilisant handlebars

var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');
var handlebars = require('handlebars');
var fs = require('fs');

var readHTMLFile = function(path, callback) {
    fs.readFile(path, {encoding: 'utf-8'}, function (err, html) {
        if (err) {
            throw err;
            callback(err);
        }
        else {
            callback(null, html);
        }
    });
};

smtpTransport = nodemailer.createTransport(smtpTransport({
    Host: mailConfig.Host,
    secure: mailConfig.secure,
    port: mailConfig.port,
    auth: {
        user: mailConfig.auth.user,
        pass: mailConfig.auth.pass
    }
}));

readHTMLFile(__dirname + 'app/public/pages/emailWithPDF.html', function(err, html) {
    var template = handlebars.compile(html);
    var replacements = {
         username: "John Doe"
    };
    var htmlToSend = template(replacements);
    var mailOptions = {
        from: '[email protected]',
        to : '[email protected]',
        subject : 'test subject',
        html : htmlToSend
     };
    smtpTransport.sendMail(mailOptions, function (error, response) {
        if (error) {
            console.log(error);
            callback(error);
        }
    });
});
27
Ananth Pai

Si vous utilisez Nodemailer 2.0.0 ou supérieur, consultez cette documentation: https://community.nodemailer.com/2-0-0-beta/templating/ Ils expliquent comment utiliser de rendu externe avec des modèles comme celui-ci:

// external renderer
var EmailTemplate = require('email-templates').EmailTemplate;
var send = transporter.templateSender(new EmailTemplate('template/directory'));

Ils donnent aussi cet exemple:

// create template based sender function
// assumes text.{ext} and html.{ext} in template/directory
var sendPwdReminder = transporter.templateSender(new EmailTemplate('template/directory'), {
    from: '[email protected]',
});

où vous voyez comment passer des variables.

Vous aurez besoin du module email-templates: https://github.com/crocodilejs/node-email-templates et d'un moteur de template de votre choix.

Vous trouverez également dans la documentation de email-templates comment structurer votre fichier afin de pouvoir retrouver vos modèles:

html. {{ext}} (requis) - pour le format HTML de l'email 

text. {{ext}} (facultatif) - pour le format de texte du style de courrier électronique.

{{ext}} (facultatif) - styles pour le sujet au format HTML.

{{ext}} (facultatif) - pour objet du courrier électronique

Consultez les moteurs de modèles pris en charge pour connaître les extensions possibles (par exemple .ejs, .jade, .nunjucks) à utiliser pour la valeur de {{ext}} ci-dessus.

Vous pouvez préfixer tout nom de fichier avec tout ce que vous voulez pour vous aider à identifier les fichiers plus facilement dans votre IDE. La seule exigence est que le nom de fichier contienne HTML, texte, style et sujet. respectivement.

3
Michael Troger

Pour ceux qui utilisent le carlin comme moteur de gabarit

Juste un moyen rapide de rendre un modèle dans un fichier séparé en utilisant la fonction de rendu de pug:

// function to send an e-mail. Assumes you've got nodemailer and pug templating engine installed. 
// transporter object relates to nodemailer, see nodemailer docs for details
const nodemailer = require('nodemailer');
const pug = require('pug');
function send_some_mail(iterable){
var message = {
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Message title',
  html: pug.renderFile(__dirname + 'path_to_template.pug', {iterable: iterable})
};
transporter.sendMail(message, function(err, info){...})
}

// template.pug
each item in iterable
li
  p #{item.name}

Voir https://pugjs.org/api/getting-started.html pour plus de détails. Notez que cela entraînera une nouvelle compilation du modèle chaque fois qu'un message est envoyé. Cela convient pour les envois occasionnels par courrier électronique. Si vous envoyez des tonnes d'e-mails, vous pouvez mettre en cache le modèle compilé pour résoudre ce problème. Consultez la documentation sur le merlin pour cette configuration si vous en avez besoin. 

1
wondersz1

Vous pouvez utiliser Web Request pour créer un modèle HTML à l'aide de handlebars ou de tout autre moteur.

Créer un modèle

Tout d'abord, vous devez créer un modèle html pour le corps de l'e-mail. Dans cet exemple, j'ai utilisé un fichier hbs de guidons.

 enter image description here

Faites votre travail de conception avec HTML et ajoutez les variables dont vous aurez besoin dans le message:

   <!DOCTYPE html>
   <html>
    <head>
        <meta name="viewport" content="width=device-width">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Welcome Email Template</title>
    </head>
    <body>
     <p style="font-size: 14px; font-weight: normal;">Hi {{data.name}}</p>
    </body>
   </html>

Créer une demande de modèle

Vous devez créer l'accès à cette vue. Ensuite, une demande est créée et nous pouvons envoyer le nom du modèle en tant que paramètre url pour que celle-ci soit paramétrable pour d’autres modèles.

const web = express.Router()

web.post('/template/email/:template', function(req, res) {
  res.render(`templates/email/${req.params.template}`, {
    data: req.body        
  })
})

Fonction mail

Enfin, vous pouvez envoyer le courrier électronique après avoir effectué la demande auprès du modèle. Vous pouvez utiliser une fonction comme celle-ci:

const nodemailer = require('nodemailer')
const request = require("request")

function sendEmail(toEmail, subject, templateFile) {
    var options = {
        uri: `http://localhost:3000/template/email/${templateFile}`,
        method: 'POST',
        json: { name: "Jon Snow" } // All the information that needs to be sent
    };  
    request(options, function (error, response, body) {
        if (error) console.log(error)
        var transporter = nodemailer.createTransport({
            Host: mailConfig.Host,
            port: mailConfig.port,
            secure: true,
            auth: {
                user: mailConfig.account,
                pass: mailConfig.password
            }
        })
        var mailOptions = {
            from: mailConfig.account,
            to: toEmail,
            subject: subject,
            html: body
        }       
        transporter.sendMail(mailOptions, function(error, info) {
            if (error) console.log(error)
        })
    })
}
1
J.C. Gras

Cela peut être fait sans modèles. 

Essayez de le changer en ceci:

`Hello ${username}!`

Assurez-vous que ce ne sont pas des virgules inverses, mais des ticks arrière.

0
Kullya