Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js and Nodemailer: Can we attached PDF documents to emails?

I am wanting to attach a PDF document using nodemailer and node.js, however, the only examples I am finding for attachments with nodemailer is with .txt files (here).

Does anyone know if PDF document attachment is supported with nodemailer?

Initially it appears a PDF can be attached, yet the PDF file that arrives through the email appears to be damaged (see image).

enter image description here

Code: (Adapted from Mahesh's answer)

fs.readFile('/filePath/fileName.pdf', function (err, data) {
if (err) throw err;                                                  
var mailOptions = {
    from: 'Test <[email protected]>', // sender address                                   
    to: 'toPersonName <[email protected]>', // list of receivers                                 
    subject: 'Attachment', // Subject line                                                 
    text: 'Hello world attachment test', // plaintext body                                                 
    html: '<b>Hello world attachment test HTML</b>', // html body                                               
    attachments: [
        {
            filename: 'fileName.pdf',                                         
            contentType: 'application/pdf'
        }]
};

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

Terminal Response:

<Buffer 25 50 44 46 2d 31 2e 33 0a 25 c4 e5 f2 e5 eb a7 f3 a0 d0 c4 c6 0a 34 20 30 20 6f 62 6a 0a 3c 3c 20 2f 4c 65 6e 67 74 68 20 35 20 30 20 52 20 2f 46 69 ... >
Message sent: 250 2.0.0 OK 1443026036 hq8sm3016566pad.35 - gsmtp
like image 579
Val Avatar asked Sep 23 '15 03:09

Val


4 Answers

Yes you can. You have to add the path of the file which you are trying to attach.

transporter.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'An Attached File',
  text: 'Check out this attached pdf file',
  attachments: [{
    filename: 'file.pdf',
    path: 'C:/Users/Username/Desktop/somefile.pdf',
    contentType: 'application/pdf'
  }],
  function(err, info) {
    if (err) {
      console.error(err);
    } else {
      console.log(info);
    }
  }
});
like image 160
Vishnu Avatar answered Nov 08 '22 01:11

Vishnu


Yes you can attach pdf documents to the email, for the path you could use path and follow from your current file to the pdf you'd like to attach. This works for me.

// node-mailer.js
const nodemailer = require('nodemailer');
const path = require('path');
...
const mailOptions = {
    from: '',
    to: '',
    subject: '',
    text: '',
    html: '',
    attachments: [
        {
            filename: 'file-name.pdf', // <= Here: made sure file name match
            path: path.join(__dirname, '../output/file-name.pdf'), // <= Here
            contentType: 'application/pdf'
        }
    ]
};

transporter.sendMail(mailOptions, function(error, cb) {

});
  • My files structure/tree:
├── package-lock.json
├── package.json
├── output
│   └── file-name.pdf
├── routes
│   └── node-mailer.js <= Current file
└── server.js

Hope this helps someone :) Happy Coding!

like image 42
Mr. Dang Avatar answered Nov 08 '22 00:11

Mr. Dang


Two things to keep in mind.

  1. Provide the complete address of the pdf file. You can use __dirname (see below)

  2. The name of the pdf on the filename & path should be exact the same.

    let info = await transporter.sendMail({
      from: '"Subject Foo Bar" <[email protected]>', // sender address
      to: `[email protected], [email protected]`, // list of receivers
      subject: "Your's subject", // Subject line
      text: "Body of the email",
      attachments: [
        {
          filename: "Trial_Agreement.pdf",
          path: __dirname + "/Trial_Agreement.pdf",
        },
      ],
    });
    
like image 1
Ashish Avatar answered Nov 08 '22 01:11

Ashish


Yes, it is easily possible. I recently worked on a project that required the same kind of things, it worked fine for me. i used Gmail for sending mails here.

Importing Nodemailer

const nodemailer = require('nodemailer');

Main function to send Mail

const sendEmailWithPromiseWithDynamicData = async () => {        
    let mailOptions = mailOptionsForDynamicMail()
    return new Promise((resolve, reject) => {
    createEmailTranspoter().sendMail(mailOptions, async(error, info) => 
    {                      
        if (error) {
        reject(error);
    }
        resolve(info);
    });
  });
}

Mail options function

const mailOptionsForDynamicMail = async() => {            
            return {
                from: `"PROJECT NAME" <SENDER EMAIL ADDRESS>`, // sender address
                to: "RECEIVER EMAIL ADDRESS", // list of receivers
                subject: "Test Subject", // Subject line
                text: "Test Text", // plain text body
                html: generateEmailTemplateForDynamicMail(), // html body
                attachments: [
                    {   // utf-8 string as an attachment
                        filename: "YOUR ATTACHMENT FILE NAME", // file name, like 'test.pdf'
                        href: "LINK TO THE FILE" // link to the file, like http://example.com/invoices/test.pdf 
                    }
                ]
            };
        }
    }

Creating mail transporter

const createEmailTranspoter = () => {        
        return nodemailer.createTransport({
            host: 'smtp.gmail.com', //your smtp host name
            service: 'Gmail', // your service name
            port: 465,
            secure: true, // true for 465, false for other ports
            auth: {
                user: "SENDER MAIL",
                pass: "SENDER MAIL PASSWORD"
            },
            tls: {
                rejectUnauthorized: true
            }
        });
    
    }

Mail HTML Body

const generateEmailTemplateForDynamicMail = async() => {
            return `
      <h4>This is a test mail</h4>
      <h5>Testing for email Attachments</h5>
      <br>
      <br>
      <br>
      <p></p>
      <p>Thanks</p>
      <p>Test person</p>
      `;
}

Nodemailer Documentation link : https://nodemailer.com/message/attachments/

Thanks

like image 1
Sushil Avatar answered Nov 08 '22 00:11

Sushil