Chris Chris - 1 year ago 322
Node.js Question

nodemailer: cannot send pdf attachment

I am just starting to learn javascript and I wanted to try building some small projects to get by feet wet. As part of my first stab, I'm building a command line tool that will send out pdf attachments. The script should send email with a pdf attachment based on an argument passed to the javascript. I found some code by googling around and tweaked it to meet my needs since I wanted to accept arguments from the command line. I have included the code I'm using below. It's supposed to take the pdf file name (test.pdf) as an argument and then send email to the designated recipients with that file attached. If I run it with my code as shown, I receive the email but the attachment received says "undefined.pdf" and cannot be opened.

It only works if I change the

path: '/home/user/attachments/' + myArgs[3],
line to be
path: '/home/user/attachments/test.pdf',
which ruins the point of the script because I don't want to hard code the file name in the "path" to attach the pdf file.

(For testing I am running the script from the same directory as the attachments \home\user\attachments.)

Can anyone point out what I'm doing wrong? I am a newbie to javascript so I am guessing I'm missing something obvious :]....

var nodemailer = require('nodemailer');
var myArgs = process.argv.slice(2);
console.log('myArgs: ', myArgs);

// create reusable transporter object using SMTP transport
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: '',
pass: 'secret'

// NB! No need to recreate the transporter object. You can use
// the same transporter object for all e-mails

// setup e-mail data with unicode symbols

var mailOptions = {
from: 'Somebody <>', // sender address
to: ',', // list of receivers
subject: 'Hello', // Subject line
text: 'Hello world', // plaintext body
html: '<b>Hello world</b>', // html body

attachments: [
{ // filename and content type is derived from path
filename: myArgs[3],
path: '/home/user/attachments/' + myArgs[3],
contentType: 'application/pdf'

// send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info){
return console.log(error);
console.log('Message sent: ' + info.response);



Answer Source

Let us suppose, that you run such a command from the console:

node script.js file.pdf

process.argv returns an array containing the command line arguments. So, it would be:

process.argv[0] = 'node'
process.argv[1] = 'path/to/script.js'
process.argv[2] = 'file.pdf

By applying slice(2), process.argv transforms into an array with just one element:

process.argv[0] = 'file.pdf';

So, it's most probably that you should change myArgs[3] to myArgs[0]. Or you should add more arguments so that file arg becomes the sixth one. For example:

node script.js email subject file.pdf