Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get new email with node-imap nodejs

Tags:

node.js

I retrieved new email from a gmail account with node-imap. How do I keep a node-worker waiting for any new email and take an immediate action instead of cron jobs?

I don't want to keep hitting the page every few minuets, kind of defeats the purpose of node js.

Here's my code so far

var Imap = require('imap'),
inspect = require('util').inspect;

var imap = new Imap({
    user: '[email protected]',
    password: 'xxxx',
    host: 'imap.gmail.com',
    port: 993,
    tls: true,
    tlsOptions: { rejectUnauthorized: false }
});

var fs = require('fs'), fileStream;

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

imap.once('ready', function() {
    openInbox(function(err, box) {
        if (err) throw err;
        imap.search([ 'UNSEEN', ['SINCE', 'October 2, 2013'] ], function(err, results) {
            if (err) {
                console.log('you are already up to date');
            }
            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.connect();
like image 724
Jack Dre Avatar asked Oct 04 '13 04:10

Jack Dre


1 Answers

So, theoretically you could use the IMAP IDLE command to do this.

However, it's worth noting several things:

  1. IDLE will just tell you that new messages have arrived, it won't tell you what those messages are
  2. I don't think you can send commands (like search commands) when IMAP idling, so you may need create another process to gather the messages somehow.

Another (maybe better) way would be to use some Javascript on the front end to either refresh the page every minute or so, or make an AJAX request every minute or so and refresh the message list part of the page. (By "better" I mean simplier. I've done IMAP IDLE implementations before and usually ended up deleting that code because IDLE sucked for me.)

If you do go for this polling, client side or server side, you probably want to look into setInterval. (Since this is a Javascript thing in general, not client or Node specific, it'll work whereever).

like image 68
RyanWilcox Avatar answered Nov 04 '22 17:11

RyanWilcox