Reading emails with NodeJS in 2017

By | October 25, 2017

I get a simple objective, read emails from GMail and send them as SMS. So I started searching for available libraries, and I finished with node-imap and mailparser.
Now, let’s go to make it with promises and meet semistandard rules

const Bluebird = require('bluebird');
const Imap = require('imap');
const MailParser = require('mailparser').MailParser;

// Creating IMAP instance with configuration
const imap = new Imap({
  user: 'youremail@gmail.com',
  password: 'password',
  host: 'imap.gmail.com',
  port: 993,
  tls: true
});

//Promisifying IMAP
Bluebird.promisifyAll(imap);

imap.once('ready', () => {
  // open Inbox
  imap.openBoxAsync('INBOX', true)
    .then((box) => {
      // creating new promise for processing the messages
      return new Bluebird((resolve, reject) => {
        let messages = [];
        // fetching messages
        let f = imap.seq.fetch((box.messages.total - 3) + ':' + box.messages.total, {
          bodies: ['']
        });
        f.on('message', (msg, seqno) => {
          let message = {
            sequenceNumber: seqno,
            headers: null,
            data: []
          };
          let mp = new MailParser();
          mp.on('headers', (headers) => {
            message.headers = headers;
          }).on('data', (obj) => {
            message.data.push(obj);
          });

          msg.on('body', (stream, info) => {
            stream.pipe(mp);
          }).on('end', () => {
            messages.push(message);
          });
        }).on('end', function () {
          resolve(messages);
        });
      });
    })
    .each((message) => {
      //Here you have final form of message
      console.log('Message #%d', message.sequenceNumber);
      console.log('Subject %s', message.headers.get('subject'));
    })
    .then(() => {
      imap.end();
    })
    .catch((err) => {
      console.log('A error has occured: ', err);
    });
});

imap.once('error', (err) => {
  console.log('A error has occured: ', err);
});

imap.once('end', () => {
  console.log('Connection ended');
});

imap.connect();

The message structure is following: