DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Reading email data withΒ Node.Js
Olumide Akinremi
Olumide Akinremi

Posted on

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
Enter fullscreen mode Exit fullscreen mode

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

const Imap = require('imap');
const {simpleParser} = require('mailparser');
const imapConfig = {
  user: 'youremail@gmail.com',
  password: 'secret',
  host: 'imap.gmail.com',
  port: 993,
  tls: true,
};
Enter fullscreen mode Exit fullscreen mode

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();

Enter fullscreen mode Exit fullscreen mode

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

node index.js
Enter fullscreen mode Exit fullscreen mode

Let's do a bit of explanation.

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

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) => {}
Enter fullscreen mode Exit fullscreen mode

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'], () => {}
Enter fullscreen mode Exit fullscreen mode

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

References
https://www.npmjs.com/package/imap
https://www.npmjs.com/package/mailparser

Top comments (9)

Collapse
 
surya63572659 profile image
Surya

Throwing error if there are no unseen mails, and by that my app is crashing,how to fix or handle that error,pls let me know

Collapse
 
akinmyde profile image
Olumide Akinremi Author

Hey Surya, I saw your email and I believed my recommended solution works

Collapse
 
arbaz2002 profile image
Arbaz Khan

i need the solution too for this sir

Collapse
 
arbaz2002 profile image
Arbaz Khan

I am also facing the same problem how to solve it ???

Collapse
 
akinmyde profile image
Olumide Akinremi Author

Hello Arbaz,

You can use try/catch or .catch to handle errors. See the attached some code snippets that can help you handle errors.

Image description

Image description

Thread Thread
 
arbaz2002 profile image
Arbaz Khan

thank you sir how we will fetch the attachments from the email sir can you share this to me plz?????

Thread Thread
 
akinmyde profile image
Olumide Akinremi Author

You can get the attachment from the "parsed" object.

example is:

const {from, subject, textAsHtml, text, attachments} = parsed; 
Enter fullscreen mode Exit fullscreen mode

Check the mailparser documentation for more information

Thread Thread
 
arbaz2002 profile image
Arbaz Khan

thank you so much sir

Thread Thread
 
akinmyde profile image
Olumide Akinremi Author

You are welcome sir

🌚 Browsing with dark mode makes you a better developer.

It's a scientific fact.