Automate Email Handling in Node.js: Reading, Marking as Seen, and Auto-Replying
In this post, I’ll show you how to automate the process of reading emails, marking them as seen, and replying to them with a standard message using Node.js. This is particularly useful for customer support or any other scenario where you need to handle incoming emails automatically. We’ll break down the process into several steps to make it easier to follow and explain the code in detail.
Prerequisites
Node.js: Make sure you have Node.js installed.
IMAP: You’ll need to use the IMAP protocol to read emails.
Packages: Install the following npm packages:
- imap: For connecting to the email inbox.
- mailparser: To parse the email content.
- nodemailer: For sending replies.
IMAP Connection and Operations Overview
- Setting Up the IMAP Connection
The Imap library is used to interact with the email server:
JavaScript
const imap = new Imap({
user: 'your-email@gmail.com',
password: 'your-password',
host: 'imap.gmail.com',
port: 993,
tls: true,
tlsOptions: { rejectUnauthorized: false },
});
- This configuration connects to Gmail’s IMAP server.
- user and password are your email credentials.
- host and port specify the server address and port for IMAP.
- tls ensures the connection is secure.
2.Opening the Inbox
The openInbox function opens the inbox for operations:
JavaScript
function openInbox(cb) {
imap.openBox('INBOX', false, cb);
}
- imap.openBox(‘INBOX’, false, cb): Opens the ‘INBOX’ folder to read emails. The false argument indicates that the mailbox is not read-only i.e. both read and write operations can be performed.
3.Searching for Unseen Emails
Now, the next step is to search the unread email and fetch them for further processing.
JavaScript
imap.search(['UNSEEN'], function (err, results) {
if (err) throw err;
if (results.length > 0) {
var f = imap.fetch(results, { bodies: '' });
// Fetch and process emails
} else {
console.log('No unseen messages');
}
});
- imap.search([‘UNSEEN’], callback): Finds all emails that haven’t been read.
- imap.fetch(results, { bodies: ” }): Fetches the content of the emails.
4. Fetching and Processing Emails
This step involved handling of the unread fetched email.
JavaScript
f.on('message', function (msg, seqno) {
msg.on('body', function (stream, info) {
simpleParser(stream, async (err, mail) => {
if (err) throw err;
// Process the email & send reply
});
});
msg.once('attributes', function (attrs) {
imap.setFlags(attrs.uid, ['\\Seen'], function (err) {
if (err) console.log('Error setting flags: ', err);
});
});
});
- msg.on(‘body’, callback): Handles the email body and parses it.
- msg.once(‘attributes’, cb): Event emitted when message attributes (e.g., UID) are available. Use this to mark the email as seen.
imap.setFlags(attrs.uid, [‘\\Seen’], callback): Marks the email as read.
5. Error Handling and Connection Management
This step involves handling any error that occurred during fetching or processing and closing of connection once task is accomplished.
JavaScript
imap.once('error', function (err) {
console.log(err);
});
imap.once('end', function () {
console.log('Connection ended');
});
- imap.once(‘error’, callback): Handles connection errors.
- imap.once(‘end’, callback): Executes when the connection is closed.
Final Code
Here is the consolidated version of the code:
JavaScript
const Imap = require('imap');
const inspect = require('util').inspect;
const simpleParser = require('mailparser').simpleParser;
const nodeMailer = require('nodemailer');
const emailService = async () => {
try {
const imap = new Imap({
user: 'your-email@gmail.com',
password: 'your-password',
host: 'imap.gmail.com',
port: 993,
tls: true,
tlsOptions: { rejectUnauthorized: false },
});
imap.connect();
function openInbox(cb) {
imap.openBox('INBOX', false, cb);
}
async function replyToEmail(mail) {
let transporter = nodeMailer.createTransport({
service: 'gmail',
auth: {
user: 'your-email@gmail.com',
pass: 'your-password'
}
});
let mailOptions = {
from: '"Your Name" <your-email@gmail.com>',
to: mail.from.text,
subject: 'Re: ' + mail.subject,
text: 'Hi, Thanks for your query, our team will contact you soon'
};
let info = await transporter.sendMail(mailOptions);
console.log('Message sent: ', info.messageId);
}
imap.once('ready', function () {
openInbox(function (err, box) {
if (err) throw err;
imap.search(['UNSEEN'], function (err, results) {
if (err) throw err;
if (results.length > 0) {
var f = imap.fetch(results, { bodies: '' });
f.on('message', function (msg, seqno) {
console.log('Message #', seqno);
var prefix = '(#' + seqno + ') ';
msg.on('body', function (stream, info) {
simpleParser(stream, async (err, mail) => {
if (err) throw err;
console.log('Message content: ', inspect(mail.text));
await replyToEmail(mail);
});
});
msg.once('attributes', function (attrs) {
imap.setFlags(attrs.uid, ['\\Seen'], function (err) {
if (err) console.log('Error setting flags: ', err);
else console.log('Marked as seen', seqno);
});
});
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();
});
} else {
console.log('No unseen messages');
imap.end();
}
});
});
});
imap.once('error', function (err) {
console.log(err);
});
imap.once('end', function () {
console.log('Connection ended');
});
} catch (e) {
throw e;
}
}
module.exports = { emailService };
Usage Instructions
To use the emailService function:
- Import the function into your script:
JavaScript
const { emailService } = require('./path-to-your-file');
2. Call the function to start processing emails:
JavaScript
emailService();
This will connect to your email server, check for unseen emails, process them, and send replies. Make sure to replace placeholder email credentials with your actual details.
Conclusion
By following these steps, you’ve set up an automated system that reads emails from your inbox, marks them as seen, and replies with a standard message. This is particularly useful for handling customer support queries or automating responses to common inquiries.