Receive Mail From Email Server Using Node Js

Introduction:

This topic is related to how we can fetch/send emails from an email server (gmail, yahoo, outlook, etc) with NodeJs.

IMAP (Internet message access protocol):

Introduction:

IMAP (Internet Message Access Protocol) is a standard email protocol that stores email messages on a mail server, but allows the end user to view and manipulate the messages as though they were stored locally on the end user's computing device(s). This allows users to organize messages into folders, have multiple client applications know which messages have been read, flag messages for urgency or follow-up and save draft messages on the server.

Installation:

npm install node-imap -save

SetUp you gmail For Creating Imap connection

1. On your computer, open Gmail.
2. In the top right, click Settings .
3. Click Settings.
4. Click the Forwarding and POP/IMAP tab.
5. In the “IMAP access” section, select Enable IMAP.
6. Click Save Changes

Setting up connection using imap

To setup imap connection in nodejs lets understand using an example

var Imap = require('imap');

var imap = new Imap({
  user: 'my[email protected]', // put your mail email
  password: 'mygmailpassword', // put your mail password or your mail app password
  host: 'imap.gmail.com', // put your mail host
  port: 993, // your mail host port
  tls: true 
})

now our connection is ready for use imap module work with events lets create few events to use the imap connection

imap.once('ready', function() { // this event will call once the imap is successfully made connection with imap host

})

imap.once('error', function(err) { // this event will call if there is any issue will come during making imap connection
  console.log(err);
});

imap.once('end', function() { // this event will call once the imap connection is closed
  console.log('Connection ended');
});

imap.connect() // this will call imap to connect to mail host using the mail credentials

let’s discuss more about the above events in details
1. error: in this event will call error occurs while making connection with imap credentials , like invalid email, password or invalid combination of host and port.
2. end: this event will call once we will close the imap connection
3. ready: this event is called when the connection is successfully made with the provided credentials. once the connection is made we can start fetching the emails from mailbox.
4. connect: this event is used for send event to imap make connection with provided credentials.

Subscribing the mailbox for start fetching the mail

once the imap connection is made successfully we are now able to fetch mail from mailbox lets understand it with an example

function openInbox(cb) {
  imap.openBox('INBOX', true, cb);
}

imap.once('ready', function() {
    openInbox(function(err, box) { // call function to select the mailbox inbox to fetch new emails from inbox 
       var f = imap.seq.fetch('1:3', {
                 bodies: 'HEADER.FIELDS (FROM TO SUBJECT DATE)',
                 struct: true
               });

       f.on('message', function(msg, seqno) {
       
       })

       f.once('error', function(err) {
         console.log('Fetch error: ' + err);
       });

       f.once('end', function() {
         console.log('Done fetching all messages!');
         imap.end();
      });
    })
})

Let’s discuss in details about the above code.
once the imap is ready for use then the very first step to start fetching email from mailbox to select the box from where we want to fetch the email like INBOX, SENTBOX etc.
The openInbox function is selecting the inbox from connected mailbox and then we are able to fetch the emails from inbox.

Now let’s understand various techniques by which we can fetch mails:

  1. Fetch all Mails by sequentially
  2. Fetch Unread Emails

Fetch All Mails by Sequentially:

In this manner we are fetching emails are in sequential manner, like we need first 3 messages from the beginning. the code should be like this:

// 1:3 means the mails from start to next 3 emails
var f = imap.seq.fetch('1:3', {
      bodies: 'HEADER.FIELDS (FROM TO SUBJECT DATE)',
      struct: true
});

// let's create events for incoming emails
// this event will call when we start reciving any email
f.on('message', function(msg, seqno) {
msg.on('body', function(stream, info) {
        var buffer = '';
        stream.on('data', function(chunk) {
          buffer += chunk.toString('utf8');
        });
        stream.once('end', function() {
          console.log(prefix + 'Parsed header: %s', 
          inspect(Imap.parseHeader(buffer)));
        });
      });
})
 // this will occurs when any error occurs while fetching emails
f.on('error', function(err){
console.log(err)
})

f.on('end', function(){

})

Fetch Unread mail

Now , i want to fetch the all unread mails from a specific date, let do this in a simple manner

openInbox(function(err, box) {
  if (err) throw err;
  imap.search([ 'UNSEEN', ['SINCE', 'May 20, 2010'] ], function(err, results) {
    if (err) throw err;
    var f = imap.fetch(results, { bodies: '' });
    f.on('message', function(msg, seqno) {
      console.log('Message #%d', seqno);
      var prefix = '(#' + seqno + ') ';
      msg.on('body', function(stream, info) {
        console.log(prefix + 'Body');
        stream.pipe(fs.createWriteStream('msg-' + seqno + '-body.txt'));
      });
      msg.once('attributes', function(attrs) {
        console.log(prefix + 'Attributes: %s', inspect(attrs, false, 8));
      });
      msg.once('end', function() {
        console.log(prefix + 'Finished');
      });
    });
    f.once('error', function(err) {
      console.log('Fetch error: ' + err);
    });
    f.once('end', function() {
      console.log('Done fetching all messages!');
      imap.end();
    });
  });
});

Parse Mail Content Using simpleParser

after getting the emails from imap we need to parse that stream into pure json format using simpleParser. let use simpleParser in above code.

// 1:3 means the mails from start to next 3 emails
var f = imap.seq.fetch('1:3', {
      bodies: 'HEADER.FIELDS (FROM TO SUBJECT DATE)',
      struct: true
});

// let's create events for incoming emails
// this event will call when we start reciving any email
f.on('message', function(msg, seqno) {
msg.on('body', function(stream, info) {
        let parsed = await simpleParser(source);
         // the parsed will contains all information is in json object format
      });
})
 // this will occurs when any error occurs while fetching emails
f.on('error', function(err){
console.log(err)
})

f.on('end', function(){

})

References:

  1. https://github.com/mscdex/node-imap
  2. https://nodemailer.com/extras/mailparser/#simpleparser
excellence-social-linkdin
excellence-social-facebook
excellence-social-instagram
excellence-social-skype