Reading email data with Node.Js

Have you ever thought of reading the data of your emails and making decisions like marking it as read or do whatever you choose? Perhaps you are working on a project that requires you to read users emails and then save the data to your database.

Enough of the talking, let's get to work……

First, open a connection to the email server using a protocol (SMTP, IMAP, POP) to read email(s) from the email service. The email service can be Gmail, yahoo, outlook. e.t.c.

This tutorial uses Imap to read emails and will be using two packages to get the magic started.

  1. imap: this helps us connect to the email server and retrieve emails as a stream

  2. mailparser: we are going to use this to parse the stream data into a readable format.

The first step is to run the following command to set up a project and install the necessary packages.

mkdir imap-client
npm init -y 
touch index.js
yarn add imap mailparser

Secondly, we need to add our email credentials to our index.js file.

const Imap = require('imap');
const {simpleParser} = require('mailparser');
const imapConfig = {
  user: '[email protected]',
  password: 'secret',
  host: 'imap.gmail.com',
  port: 993,
  tls: true,
};

Next, we write a script in the index.js file to read the email and then parse it to get the sender, subject and body.

const getEmails = () => {
  try {
    const imap = new Imap(imapConfig);
    imap.once('ready', () => {
      imap.openBox('INBOX', false, () => {
        imap.search(['UNSEEN', ['SINCE', new Date()]], (err, results) => {
          const f = imap.fetch(results, {bodies: ''});
          f.on('message', msg => {
            msg.on('body', stream => {
              simpleParser(stream, async (err, parsed) => {
                // const {from, subject, textAsHtml, text} = parsed;
                console.log(parsed);
                /* Make API call to save the data
                   Save the retrieved data into a database.
                   E.t.c
                */
              });
            });
            msg.once('attributes', attrs => {
              const {uid} = attrs;
              imap.addFlags(uid, ['\\Seen'], () => {
                // Mark the email as read after reading it
                console.log('Marked as read!');
              });
            });
          });
          f.once('error', ex => {
            return Promise.reject(ex);
          });
          f.once('end', () => {
            console.log('Done fetching all messages!');
            imap.end();
          });
        });
      });
    });

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

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

    imap.connect();
  } catch (ex) {
    console.log('an error occurred');
  }
};

getEmails();

Lastly, run and don't forget to turn of "less secure app" for gmail

node index.js

Let's do a bit of explanation.

imap.search(['UNSEEN', ['SINCE', new Date()]], (err, results) => {}

The above function goes through your mailbox and gets all the unseen/unread email for today. You have the liberty of changing the date filter to whatever date you want. Also, you can change the ‘SINCE’ attribute to ‘BEFORE’, ‘ON’. e.t.c.

You can change the ‘UNSEEN’ attribute to something like ‘ALL’, ‘NEW’. e.t.c.

simpleParser(stream, async (err, parsed) => {}

The simpleParser function returns a parsed data which contains details of the received email like (from, subject, textAsHtml, text) e.t.c.

imap.addFlags(uid, ['\\Seen'], () => {}

You can also decide to add a flag to the read email like marking it as seen, read.

Thats's All!!!

The entire course code can be viewed here

65