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

问题描述 投票:0回答:12

我想使用 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);
    }
});

假设我想在 emailWithPDF.html 中添加如下内容:

Hello {{username}}!

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

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

但我想要它在单独的 html 文件中。可以吗?

javascript html node.js express nodemailer
12个回答
98
投票

您可以做的是使用节点中的

fs
模块读取HTML文件,然后使用
handlebars

替换html字符串中要更改的元素
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) {
           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) {
    if (err) {
       console.log('error reading file', err);
       return;
    }
    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);
        }
    });
});

23
投票

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

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 __dirname = path.resolve();
  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/");

}

11
投票

String replace 不是一个好主意,因为您必须恢复旧字符串或创建备份文件才能再次更改它们,而且它不会异步,并且会在各个方面导致问题! 你可以做到更容易并且更干净

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

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

下一步要做的事情是打开 html 文件并调用变量,如下所示:

{{用户名}}


8
投票
创建一个文件

emailTemplates.js

您可以将每个模板存储为函数

emailTemplates.js

const newsLetterEmail = (clientName) => `<p>Hi ${clientName}, here you have today news.</p>` const welcomeEmail = (clientName, username) => `<p>Welcome ${clientName}, your username is ${username}.</p>` export {newsLetterEmail, welcomeEmail}
然后在控制器中调用任何 templateFunction 并存储在输出变量中

控制器.js

import {welcomeEmail} from './emailTeamplates.js' const registerUser = async(req, res) => { const {name, usename, email} = req.body // User register code.... const output = welcomeEmail(name, username) let mailOptions = { from: '"Welcome" <[email protected]>', to: '[email protected]', subject: 'Welcome email!', text: 'Hello World', html: output, }
    

6
投票
如果您使用 Nodemailer 2.0.0 或更高版本,请查看此文档:

https://community.nodemailer.com/2-0-0-beta/template/ 他们解释了如何使用这样的模板进行外部渲染:

// external renderer var EmailTemplate = require('email-templates').EmailTemplate; var send = transporter.templateSender(new EmailTemplate('template/directory'));
他们还举了这个例子:

// 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]', });
您可以在其中看到如何传递变量。

您将需要

email-templates

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

此外,在

email-templates

 的文档中,您还可以找到如何创建文件结构以便可以找到您的模板:

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

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

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

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

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

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


4
投票

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

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

请参阅

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


3
投票
您可以使用

Web 请求 使用 handlebars

 或任何其他引擎构建 html 模板。

创建模板

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

hbs

 文件。

使用 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>
创建模板请求

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

const web = express.Router() web.post('/template/email/:template', function(req, res) { res.render(`templates/email/${req.params.template}`, { data: req.body }) })
邮件功能

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

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

2
投票
无需模板即可完成此操作。

尝试将其更改为:

`Hello ${username}!`

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


2
投票
有一种简单的方法可以在 Nodemailer 的 html 中插入变量。

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

0
投票
您还可以使用 async/await 语法或 Promise 并避免使用回调,就像我在这里所做的那样,使用 async/await:

const fs = require("fs").promises; const path = require("path"); const handlebars = require("handlebars"); const relativeTemplatePath = "../../html/reset-pw-email-template.html"; function sendEmail(){ const templatePath = path.join(__dirname, relativeTemplatePath); const templateFile = await fs.readFile(templatePath, 'utf-8'); const template = handlebars.compile(templateFile); const replacements = { username:"" }; const finalHtml = template(replacements); const mailOptions = { from: "", to: "", subject: "", html: finalHtml, }; }
    

0
投票
对于哈巴狗模板:

#{}

方式可能无法得到很好的支持。

- var url = thisIsTheVariable; a(href='/' + url) Link
文档在

这里


0
投票
这是我的方法,我尝试尽可能简单,所以如果需要更多东西,例如额外的错误检查,您可以添加

import fs from 'fs'; import Handlebars from 'handlebars'; import nodemailer from 'nodemailer'; const transporter = nodemailer.createTransport({ host: 'smtp.ethereal.email', port: 587, auth: { user: '[email protected]', pass: 'qZjeVE5F3WQWwdBmek', }, }); const readFileSync = (path: string) => { return fs.readFileSync(__dirname + path, { encoding: 'utf-8' }); }; export const registerMail = async (user) => { const template = Handlebars.compile(readFileSync('/test.html')); const mailOptions = { from: '"Info" <[email protected]>', to: '[email protected]', subject: 'Validate your email address', html: template({ username: user.name }), }; transporter.sendMail(mailOptions, (err, res) => { if (err) console.log(err); }); };
    
© www.soinside.com 2019 - 2024. All rights reserved.