Sending Email attachments with percentage progress bar using NodeMailer

Many times in projects you have to send email with attachments using Node Mailer module in Node.js or Electron project.

In my recent project I have to send email with heavy images. But you know heavy full HD images takes time to get attached to email. So it is better to show progress bar during this for the sake of better user experience.So I implemented solution for this one I hope this will be helpful for you as well.

First of all you need to install nodemailer module using npm.

     npm i nodemailer --save

Then you have to import it into file where do you want to use it.

    var nodemailer = require('nodemailer');

You need to create a transporter to configure email settings. I am using Gmail SMTP for this.

var transporter = nodemailer.createTransport({
                        host: 'smtp.gmail.com',
                        port: 465,
                        secure: true, // use SSL
                        auth: {
                            user:,
                            pass:
                        }
                    });

We are using progress stream for showing progress. This is the code snippet we are using

sendMessage = () => {
        var emails = this.state.to.split(',');
        var invalidEmails = [];
        for (var i = 0; i < emails.length; i++) {
            if (!this.validateEmail(emails[i].trim())) {
                invalidEmails.push(emails[i].trim())
            }
        }
        if (invalidEmails.length > 0) {
            this.setState({ emailError: invalidEmails + " must be valid email address/addresses" });
            return;
        }
        var progress = require('progress-stream');
        var stat = fs.statSync(this.state.selectedFile.path);
        var str = progress({
                            length: stat.size,
                            time: 1 /* ms */
                        });
        var attachments = [];
        str.on('progress', (progress)=> {
            if(parseInt(progress.percentage)==100){
                this.setState({showProgress:false,progress:parseInt(progress.percentage),openEmailDL: false});
            }else{
                this.setState({showProgress:true,progress:parseInt(progress.percentage)});
            }
        });

        attachments.push({ filename: this.state.selectedFile.name, content: fs.createReadStream(this.state.selectedFile.path).pipe(str),filePath:this.state.selectedFile.path });
        var mailOptions = {
            from: this.state.account + '<' + this.state.email + '>', // sender address (who sends)
            to: this.state.to, // list of receivers (who receives)
            subject: this.state.subject, // Subject line
            html: this.state.body,
            attachments: attachments
        };
            transporter.sendMail(mailOptions, (error, info) => {
                if (error) {
                    console.log(error);
                   
                } else {
                    console.log("sent successfully");
                }
            });
        
    }

 validateEmail(email) {
        var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
        return re.test(email);
    }

If you want to know How progress stream module works then must go through the link below

https://www.npmjs.com/package/progress-stream

What we are doing really is we are having list of email in state object to whom we want to send email. First we split with comma(,) and then store in array.

after that we check whether all emails are valid if they are then go otherwise return.

after that we when we are pushing images into attachments array then fs.createReadStream is called and all of the progress is presented through callbacks. If you are React.Js and Node.js developer you will able to understand it in very clear way.
I was using material progress bar to show progress you may go with of your choice .

I hope you are going to enjoy this code. If you find any problem in implementation then you may ask for help by commenting below.

Thanks for being here.


Tagged with:
CodeNextGen
Written by Sanjeev Kumar

Get notifications about new posts on Twitter, RSS or Email.