Javascript 将变量传递给 nodemailer 中的 html 模板

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39489229/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:37:45  来源:igfitidea点击:

Pass variable to html template in nodemailer

javascripthtmlnode.jsexpressnodemailer

提问by Wac?aw ?abuda

I want to send email with nodemailer using html template. In that template I need to inject some dynamically some variables and I really can't do that. My code:

我想使用 html 模板使用 nodemailer 发送电子邮件。在那个模板中,我需要动态注入一些变量,但我真的做不到。我的代码:

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);
    }
});

Let's say I want in emailWithPDF.html something like this:

假设我想要在 emailWithPDF.html 中是这样的:

Hello {{username}}!

I've found some examples, where was smth like this:

我找到了一些例子,哪里是这样的:

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

but I want it in separate html file. Is it possible?

但我希望它在单独的 html 文件中。是否可以?

回答by Ananth Pai

What you can do is read the HTML file using fsmodule in node and then replace the elements that you want changed in the html string using handlebars

您可以做的是使用fsnode 中的模块读取 HTML 文件,然后使用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);
        }
    });
});

回答by Michael Troger

If you're using Nodemailer 2.0.0 or higher, check this documentation: https://community.nodemailer.com/2-0-0-beta/templating/There they explain how to make use of external rendering with templates like that:

如果您使用的是 Nodemailer 2.0.0 或更高版本,请查看此文档:https://community.nodemailer.com/2-0-0-beta/templating/ 在那里他们解释了如何使用带有此类模板的外部渲染:

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

They also give this example:

他们还举了这个例子:

// 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]',
});

where you see how to pass variables.

在这里您可以看到如何传递变量。

You will need the email-templatesmodule: https://github.com/crocodilejs/node-email-templatesand a template engine of your choice.

您将需要该email-templates模块:https: //github.com/crocodilejs/node-email-templates和您选择的模板引擎。

Also in the documentation of email-templatesyou'll find how to make your file structure in order that your templates can be found:

同样在email-templates您的文档中,您将找到如何制作文件结构以便可以找到您的模板:

html.{{ext}} (required) - for html format of email

text.{{ext}} (optional) - for text format of email style.

{{ext}}(optional) - styles for html format subject.

{{ext}}(optional) - for subject of email

See supported template engines for possible template engine extensions (e.g. .ejs, .jade, .nunjucks) to use for the value of {{ext}} above.

You may prefix any file name with anything you like to help you identify the files more easily in your IDE. The only requirement is that the filename contains html., text., style., and subject. respectively.

html.{{ext}} (required) - 用于 html 格式的电子邮件

text.{{ext}} (optional) - 用于电子邮件样式的文本格式。

{{ext}}(可选)- html 格式主题的样式。

{{ext}}(可选) - 用于电子邮件主题

请参阅支持的模板引擎以获取可能的模板引擎扩展名(例如 .ejs、.jade、.nunjucks)以用于上述 {{ext}} 的值。

您可以在任何文件名前加上您喜欢的任何内容,以帮助您在 IDE 中更轻松地识别文件。唯一的要求是文件名包含 html.、text.、style. 和 subject。分别。

回答by J.C. Gras

You can use a Web Requestto build an html template using handlebarsor any other engine.

您可以使用Web 请求handlebars或任何其他引擎来构建 html 模板。

Create a template

创建模板

First you must create an html template for the email body. In this example I used a handlebars hbsfile.

首先,您必须为电子邮件正文创建一个 html 模板。在这个例子中,我使用了一个把手hbs文件。

enter image description here

在此处输入图片说明

Do your design stuff with html and add the variables that you will need in the message:

使用 html 进行设计并在消息中添加您需要的变量:

   <!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>

Create a template request

创建模板请求

You must create the access to this view. Then a request is created where we can send the the template name as an url parameter to make the request parameterizable for other templates.

您必须创建对此视图的访问权限。然后创建一个请求,我们可以在其中将模板名称作为 url 参数发送,以使请求可参数化为其他模板。

const web = express.Router()

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

Mail function

邮件功能

Finally you can send the email after making the request to the template. You can use a function like the following:

最后,您可以在向模板发出请求后发送电子邮件。您可以使用如下函数:

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)
        })
    })
}

回答by Umut Yerebakmaz

I use it in all my projects. more clean and up to date and understandable. callback hell doesn't exist. sendMail.tsThe html file reads with handlebar, puts the relevant variables into the contents, and sends.

我在所有项目中都使用它。更干净、最新且易于理解。回调地狱不存在。 sendMail.ts用handlebar读取html文件,将相关变量放入内容中,发送。

import * as nodemailer from 'nodemailer';
import * as handlebars from 'handlebars';
import * as fs from 'fs';
import * as path from 'path';

export async function sendEmail(email: string, subject: string, url: string) {
  const filePath = path.join(__dirname, '../emails/password-reset.html');
  const source = fs.readFileSync(filePath, 'utf-8').toString();
  const template = handlebars.compile(source);
  const replacements = {
    username: "Umut YEREBAKMAZ"
  };
  const htmlToSend = template(replacements);
  const transporter = nodemailer.createTransport({
    host: "smtp.mailtrap.io",
    port: 2525, // 587
    secure: false,
    auth: {
      user: "fg7f6g7g67",
      pass: "asds7ds7d6"
    }
  });
  const mailOptions = {
    from: '"[email protected]" <[email protected]>',
    to: email,
    subject: subject,
    text: url,
    html: htmlToSend
  };
  const info = await transporter.sendMail(mailOptions);
  console.log("Message sent: %s", info.messageId);
  console.log("Preview URL: %s", "https://mailtrap.io/inboxes/test/messages/");

}

回答by larachiwnl

String replaceisn't a good idea because you'll have to restore old strings or create a backup file to be able to change them another time, also it won't be asynchrone and it will cause a problem in every way! you can do it much easierand more cleaner:

字符串替换不是一个好主意,因为您必须恢复旧字符串或创建一个备份文件才能再次更改它们,而且它不会是异步的,并且会导致各个方面的问题!您可以更轻松更清洁地做到这一点

just go to your mail optionsand add contextwith your variables:

只需转到您的邮件选项并使用您的变量添加上下文

var mailOptions = {
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Sending email',
  template: 'yourTemplate',
  context: {                  // <=
    username: username,
    whatever: variable
  }
};

next thingto do is openning your html file and call your variables like:

接下来要做的是打开您的 html 文件并调用您的变量,例如:

{{username}}

{{用户名}}

回答by wondersz1

For those using pug as templating engine

对于那些使用 pug 作为模板引擎的人

Just a quick way to render a template in a separate file using pug's render function:

只是使用 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}

See https://pugjs.org/api/getting-started.htmlfor further details. Note that this will cause template re-compilation every time a message is sent. That is fine for occasional e-mail deliveries. If you send tons of e-mails, you can cache the compiled template to work around that. Check out pug docs for that set up if you need it.

有关更多详细信息,请参阅https://pugjs.org/api/getting-started.html。请注意,这将导致每次发送消息时重新编译模板。这对于偶尔发送电子邮件来说很好。如果您发送大量电子邮件,您可以缓存已编译的模板来解决这个问题。如果需要,请查看该设置的 pug 文档。

回答by Kullya

This can be done without templates.

这可以在没有模板的情况下完成。

Try changing it to this:

尝试将其更改为:

`Hello ${username}!`

Make sure that these are not inverted commas but back ticks.

确保这些不是引号,而是反引号。

回答by Ranjit Kumar Pandit

There is one easy way to insert variable inside html in nodemailer.

有一种简单的方法可以在 nodemailer 的 html 中插入变量。

    html:"<p>Your message "+variable1+".Message continueous "+variable 2+"</p>"