使用nodemailer发送ejs模板

Sending ejs template using nodemailer

我正在尝试使用 express.js 构建 Web 应用程序。在我的应用程序中,我使用 nodemailer 发送邮件。如果我只是用它来发送基本邮件,它就可以正常工作;但是,当我尝试使用 nodemailer 发送呈现的 ejs 文件时,收件人只收到一封空邮件。所以这里是我的代码的详细信息:

var transporter = nodemailer.createTransport({
                host: 'smtp.zoho.com',
                port: 465,
                secure: true, // use SSL
                auth: {
                    user: 'testmail@zoho.com',
                    pass: '123456'
                }
            });
fs.readFile('/test.ejs', 'utf8', function (err, data) {
                if (err) {
                    return console.log(err);
                }
                var mainOptions = {
                    from: '"Tester" testmail@zoho.com',
                    to: email,
                    subject: 'Hello, world'
                    html: ejs.render(data, {name: 'Stranger'});
                };
                console.log(mainOptions.html);
});
transporter.sendMail(mainOptions, function (err, info) {
                            if (err) {
                                console.log(err);
                            } else {
                                console.log('Message sent: ' + info.response);
                            }
                        });

这里的test.ejs(另外,结果console.log(mainOptions.html)很好,因为它正确地打印出了渲染的ejs文件的字符串(<%= name %>替换为 'Stranger')

<style type="text/css">
  .header {
    background: #8a8a8a;
  }
  .header .columns {
    padding-bottom: 0;
  }
  .header p {
    color: #fff;
    padding-top: 15px;
  }
  .header .wrapper-inner {
    padding: 20px;
  }
  .header .container {
    background: transparent;
  }
  table.button.facebook table td {
    background: #3B5998 !important;
    border-color: #3B5998;
  }
  table.button.twitter table td {
    background: #1daced !important;
    border-color: #1daced;
  }
  table.button.google table td {
    background: #DB4A39 !important;
    border-color: #DB4A39;
  }
  .wrapper.secondary {
    background: #f3f3f3;
  }
</style>



<wrapper class="header">
  <container>
    <row class="collapse">
      <columns small="6">
        <img src="http://placehold.it/200x50/663399">
      </columns>
      <columns small="6">
        <p class="text-right">BASIC</p>
      </columns>
    </row>
  </container>
</wrapper>

<container>

  <spacer size="16"></spacer>

  <row>
    <columns small="12">

      <h1>Hi, <%= name %></h1>
      <p class="lead">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Magni, iste, amet consequatur a veniam.</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut optio nulla et, fugiat. Maiores accusantium nostrum asperiores provident, quam modi ex inventore dolores id aspernatur architecto odio minima perferendis, explicabo. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima quos quasi itaque beatae natus fugit provident delectus, magnam laudantium odio corrupti sit quam. Optio aut ut repudiandae velit distinctio asperiores?</p>
      <callout class="primary">
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit repellendus natus, sint ea optio dignissimos asperiores inventore a molestiae dolorum placeat repellat excepturi mollitia ducimus unde doloremque ad, alias eos!</p>
      </callout>
    </columns>
  </row>
  <wrapper class="secondary">

    <spacer size="16"></spacer>

    <row>
      <columns large="6">
        <h5>Connect With Us:</h5>
        <button class="facebook expand" href="http://zurb.com">Facebook</button>
        <button class="twitter expand" href="http://zurb.com">Twitter</button>
        <button class="google expand" href="http://zurb.com">Google+</button>
      </columns>
      <columns large="6">
        <h5>Contact Info:</h5>
        <p>Phone: 408-341-0600</p>
        <p>Email: <a href="mailto:foundation@zurb.com">foundation@zurb.com</a></p>
      </columns>
    </row>
  </wrapper>
</container>

如果我用简单的内容替换mainOptions.html,例如:<b>Hello, world!</b>收件人将准确地收到内容。但是,如果我使用上面的代码,收件人将只会收到一封内容为空的电子邮件(收件人仍能正确收到发件人、主题和其他信息)。我尝试用文本替换 html 以将呈现的字符串作为纯文本而不是 html 发送,但收到的邮件仍然包含空内容。我现在可以提供我的问题的所有细节。因此,如果有人知道我的代码有什么问题,请为我指出。

在此先感谢您提供的任何帮助。

问题是 sendMailfs.readFile 完成之前执行。

实际上,readFile 可以替换为 ejs.renderFile,它读取文件并呈现 HTML 字符串。请尝试以下重构代码。

var fs = require("fs");
var nodemailer = require("nodemailer");
var ejs = require("ejs");
var transporter = nodemailer.createTransport({
    host: 'smtp.zoho.com',
    port: 465,
    secure: true, // use SSL
    auth: {
        user: 'testmail@zoho.com',
        pass: '123456'
    }
});

ejs.renderFile(__dirname + "/test.ejs", { name: 'Stranger' }, function (err, data) {
if (err) {
    console.log(err);
} else {
    var mainOptions = {
        from: '"Tester" testmail@zoho.com',
        to: "totest@zoho.com",
        subject: 'Hello, world',
        html: data
    };
    console.log("html data ======================>", mainOptions.html);
    transporter.sendMail(mainOptions, function (err, info) {
        if (err) {
            console.log(err);
        } else {
            console.log('Message sent: ' + info.response);
        }
    });
}

});

我已经使用 ES6 和 ES8 功能更新了答案,以防万一有人需要它。

不要忘记在 async 函数中使用它。

const fs = require("fs");
const nodemailer = require("nodemailer");
const ejs = require("ejs");

const transporter = nodemailer.createTransport({
  host: 'smtp.zoho.com',
  port: 465,
  secure: true,
  auth: {
    user: 'testmail@zoho.com',
    pass: '123456'
  }
});

const data = await ejs.renderFile(__dirname + "/test.ejs", { name: 'Stranger' });

const mainOptions = {
  from: '"Tester" testmail@zoho.com',
  to: 'totest@zoho.com',
  subject: 'Hello, world!',
  html: data
};

transporter.sendMail(mainOptions, (err, info) => {
  if (err) {
    console.log(err);
  } else {
    console.log('Message sent: ' + info.response);
  }
});