web-dev-qa-db-ja.com

nodemailerを使用してejsテンプレートを送信する

Express.jsを使用してWebアプリケーションを構築しようとしています。私のアプリケーションでは、メールの送信にnodemailerを使用しています。基本的なメールを送信するのに使用するだけで問題ありません。ただし、nodemailerを使用してレンダリングされたejsファイルを送信しようとすると、受信者は空のメールしか受信しません。だからここに私のコードの詳細:

var transporter = nodemailer.createTransport({
                Host: 'smtp.zoho.com',
                port: 465,
                secure: true, // use SSL
                auth: {
                    user: '[email protected]',
                    pass: '123456'
                }
            });
fs.readFile('/test.ejs', 'utf8', function (err, data) {
                if (err) {
                    return console.log(err);
                }
                var mainOptions = {
                    from: '"Tester" [email protected]',
                    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:[email protected]">[email protected]</a></p>
      </columns>
    </row>
  </wrapper>
</container>

MainOptions.htmlを単純なコンテンツに置き換えた場合、たとえば:<b>Hello, world!</b>受信者はコンテンツを正確に受け取ります。ただし、上記のコードを使用した場合、受信者は空の内容のメールのみを受信します(受信者は送信者、件名、およびその他の情報を正しく受信します)。レンダリングされた文字列をhtmlではなくプレーンテキストとして送信するために、htmlをテキストに置き換えようとしましたが、受信したメールにはまだ空のコンテンツが含まれています。現時点で提供できる私の問題のすべての詳細。ですから、誰かが私のコードの何が悪いのかを知っているなら、私にそれを指摘してください。

あなたが提供できるあらゆる助けを前もって感謝します。

14
Blue Bird

問題は、fs.readFileが完了する前にsendMailが実行されることです。

実際には、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: '[email protected]',
        pass: '123456'
    }
});

ejs.renderFile(__dirname + "/test.ejs", { name: 'Stranger' }, function (err, data) {
if (err) {
    console.log(err);
} else {
    var mainOptions = {
        from: '"Tester" [email protected]',
        to: "[email protected]",
        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);
        }
    });
}

});
21
notionquest

誰かがそれを必要とする場合に備えて、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: '[email protected]',
    pass: '123456'
  }
});

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

const mainOptions = {
  from: '"Tester" [email protected]',
  to: '[email protected]',
  subject: 'Hello, world!',
  html: data
};

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