Send E-mail with PDF attachment using Node.js

HiroshiFuu發表於2019-02-16

Background

As in the requirement, I am generating PDF document using PDFkit. Then I need to send the PDF file as attachment in E-mail.

Procedure

Since the data is tabled, I used Voilab-Pdf-Table which is a PdfKit wrapper that helps to draw information in simple tables. You may find installation and usage guide from its Github -> Here.
For the E-mailing part, I used Nodemailer to do the job. The official site -> Here.

My Way

Since I am using Gamil, so the configuration is as below.

  • Firstly define the transporter
var transporter = nodemailer.createTransport({
    pool: true,
    service: `gmail`,
    port: 587,
    secure: true,
    auth: {
        user: `username`,
        pass: `password`
    }
});
  • Then I created a genetic function for various purposes
function EmailService(mailOptions, req, res) {
    switch (SMTP_Status) {
        case 0:
            try {
                transporter.verify(function(error, success) {
                    if (error) {
                        SMTP_Status = 5;
                        console.log(error);
                        res.send("SMTP error " + error);
                    }
                    else {
                        SMTP_Status = 2;
                        console.log("SMTP is okay");
                    }
                });
            } catch (err) {
                SMTP_Status = 3;
                console.log(error);
                res.send("SMTP error " + error);
            }
        case 2:
            transporter.sendMail(mailOptions, (error, info) => {
                if (error) {
                    res.send(error);
                }
                res.send("Email " + info.messageId + " sent: " + info.response);
            });
            break;
        case 3:
        case 5:
            res.send("SMTP error");
            break;
    }
}
  • Finally, exports the sending
exports.EmergencyAlert = function(req, res) {
    var pdf = require(`../models/Model`).create();
    let buffers = [];
    pdf.on(`data`, buffers.push.bind(buffers));
    const fileName = "PDF.pdf";
    pdf.on(`end`, () => {
        let pdfData = Buffer.concat(buffers);
        let mailOptions = {
            from: `"Sender Name" <Email>`,
            to: `Recipient`,
            subject: `Subject`,
            attachments: [{
                filename: fileName,
                content: pdfData,
                contentType: `application/pdf`
            }]
        };
        EmailService(mailOptions, req, res);
    });
    pdf.pipe(res);
    pdf.end();
}

Takeaways

Sender name in Email

If you want to display a sender name instead of just the email address, you need to follow this format from: `"Sender Name" <Email>` for the from option in the mailOptions.

Send dynamically created PDF as attachment

In order to achieve this, you need to convert the PDFkit object to buffer and only send it when PDFkit finished writing. Since PDFkit writing is not pooling, if you didn`t put the sending part in the end event, the email might be sent before file has been written, so the file will be corrupted.

相關文章