I'm trying to attach some files to the email I'm sending via NodeMailer. Checking the sent email, the attached files are empty (i.e. 0 bytes). If I download the attachments, I end up with empty text files. What am I missing?
Here is my code:
const nodemailer = require('nodemailer')
const lessSecureAuth = {
user: "sender@email.com",
pass: "password123"
}
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: lessSecureAuth
});
const mailOptions = {
from: 'sender@email.com',
to: 'recipient@email.com',
subject: 'Email Subject',
html: `
<h3>Hello World!</h3>
<p>
the quick brown fox jumps over the lazy dog
</p>
`,
attachments: [
{
filename: 'attachFileTest.docx',
filePath: '../uploads/attachFileTest.docx',
contentType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
},
{
filename: 'attachFileTest.pdf',
filePath: '../uploads/attachFileTest.pdf',
contentType: 'application/pdf'
},
{
filename: 'attachImageTest.png',
filePath: '../uploads/attachImageTest.png',
contentType: 'image/png'
}
]
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log("[ ERR ]", error);
} else {
console.log('Email sent: ' + info.response);
}
});
NodeJS: v12.16.1
nodemailer: v6.6.0
Edit#1
After doing some digging in the docs and other stackoverflow posts, I found the answer:
Using the absolute path instead of a relative path to the file to be attached, along with using the attachment.path
property instead of the attachment.filePath
property did the trick.
Basically, changing this:
{
filename: 'attachFileTest.pdf',
filePath: '../uploads/attachFileTest.pdf',
contentType: 'application/pdf'
},
to this:
{
path: __dirname + '/../uploads/attachFileTest.pdf' // string concatination
// path: `${__dirname}/../uploads/attachFileTest.pdf` // or string interpolation (ES6)
}
Both attachment.filename
and attachment.contentType
are unnecessary in this case, since according to the docs:
{ // filename and content type is derived from path path: '/path/to/file.txt' }