Emanuele Rossi
Emanuele Rossi

Reputation: 41

Imap with Node.js, marking Email as read

I'm using Imap with node.js, and every time i connect it, it fetch al the emails from a data i gave it, but doens't mark them as read, so the following time it re-fecth them again.

Here is my code(All the functions implemented here are called in a main.js file), what can I change to mark the e-mail I'm fetching as read?

I've tried to do like written here (how to mark unseen email as seen with node-imap in node.js) but it didn't work..

var Imap = require('imap');
var inspect = require('util').inspect;
var formatter = require('./formatter.js');

var mailError = exports.mailError = [];

var imap = new Imap({
  user: '[email protected]',
  password: 'xxxxxxx',
  host: 'imap.gmail.com',
  port: 993,    //Perchè non 143, standard IMAP?
  tls: true,
  markSeen: true
});

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


var onBodyCb = exports.onBodyCb = function(parsedHeaders, body){
    var pos = (body.indexOf("Delivery to the following recipient failed permanently:") + 55);
    var address = body.substr(pos,50);
    var at = address.indexOf("@");
    address = address.substr(0,at+formatter.company.length+formatter.domain.length+2);
    address = address.replace(/ /g,'');
    address = address.replace(/(\r\n|\n|\r)/gm,"");
    console.log("onBodyCB:  "+address+'\n');
    mailError.push(address);    
};

var onFinishedFetching = exports.onFinishedFetching = function(){};

imap.once('ready', function() {
    var fs = require('fs'), fileStream;

    openInbox(function(err, box) {
      if (err) throw err;
      imap.search([ 'UNSEEN', ['SINCE', 'July 10, 2014'] ], function(err, results) {
        if (err) throw err;
        // a questo abbiamo la box a cui possiamo accedere
        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');
            var buffer = '';
             stream.on('data', function(chunk) {
              buffer += chunk.toString('utf8');
            });
            //console.log(buffer);
            stream.once('end', function() {
              //console.log(prefix + 'Parsed header: %s', inspect());
              var header = Imap.parseHeader(buffer);
              exports.onBodyCb(header, buffer);
            });
          });
          //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.end();
          exports.onFinishedFetching();
        });
      });
    });
});

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

imap.once('end', function() {
  console.log('Connection ended');

});

exports.connect = function(){
    imap.connect();
};

EDIT:

I've changed as suggested but it still doesn't work...

var Imap = require('imap');
var inspect = require('util').inspect;
var formatter = require('./formatter.js');

var mailError = exports.mailError = [];

var imap = new Imap({
  user: '[email protected]',
  password: 'coci2014',
  host: 'imap.gmail.com',
  port: 993,    //Perchè non 143, standard IMAP?
  tls: true,
  markSeen : true,
  markRead : true
});

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


var onBodyCb = exports.onBodyCb = function(parsedHeaders, body){
    var pos = (body.indexOf("Delivery to the following recipient failed permanently:") + 55);
    var address = body.substr(pos,50);
    var at = address.indexOf("@");
    address = address.substr(0,at+formatter.company.length+formatter.domain.length+2);
    address = address.replace(/ /g,'');
    address = address.replace(/(\r\n|\n|\r)/gm,"");
    console.log("onBodyCB:  "+address+'\n');
    mailError.push(address);    
};

var onFinishedFetching = exports.onFinishedFetching = function(){};

imap.once('ready', function() {
    var fs = require('fs'), fileStream;

    openInbox(function(err, box) {
      if (err) throw err;
      imap.search([ 'UNSEEN', ['SINCE', 'July 10, 2014'] ], function(err, results) {
        if (err) throw err;
        // a questo abbiamo la box a cui possiamo accedere
        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');
            var buffer = '';
             stream.on('data', function(chunk) {
              buffer += chunk.toString('utf8');
            });
            //console.log(buffer);
            stream.once('end', function() {
              //console.log(prefix + 'Parsed header: %s', inspect());
              var header = Imap.parseHeader(buffer);
              exports.onBodyCb(header, buffer);
            });
          });
          //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.end();
          exports.onFinishedFetching();
        });
      });
    },false);
});

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

imap.once('end', function() {
  console.log('Connection ended');

});

exports.connect = function(){
    imap.connect();
};

Upvotes: 3

Views: 10492

Answers (3)

Ranjan
Ranjan

Reputation: 448

Here is a working example to do the same.

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

var imap = new Imap({
    user: 'USERNAME',
    password: 'PASSWORD',
    host: 'IMAP_HOST',
    port: 993, // Default port is 993
    tls: true,
    tlsOptions: {rejectUnauthorized: false}
});

function openInbox(cb) {
    // openReadOnly = false
    imap.openBox('Inbox', false, cb);
}

imap.once('ready', function () {
openInbox(function (err, box) {
    if (err) throw err;

    // Search emails having "Some Subject" in their Subject headers
    imap.search([['HEADER', 'SUBJECT', 'Some Subject']], function (err, results) {
        if (err) throw err;

        try {
            var f = imap.fetch(results, {bodies: 'TEXT'});
            f.on('message', function (msg, seqno) {
                msg.on('body', function (stream, info) {
                    var buffer = '';
                    stream.on('data', function (chunk) {
                        buffer += chunk.toString('utf8');
                    });
                    stream.once('end', function () {

                        // Mark the above mails as read
                        msg.once('attributes', function (attrs) {

                            let uid = attrs.uid;
                            imap.addFlags(uid, ['\\Seen'], function (err) {
                                if (err) {
                                    console.log(err);
                                } else {
                                    console.log("Marked as read!")
                                }
                            });

                        });

                    });
                });
            });
            f.once('end', function () {
                imap.end();
            });
        } catch (errorWhileFetching) {
            console.log(errorWhileFetching.message);
            imap.end();
        }

    });
});
});


 imap.connect();

Upvotes: 2

Ankit Kumar
Ankit Kumar

Reputation: 1775

var Imap = require("imap");
var MailParser = require("mailparser").MailParser;
var Promise = require("bluebird");
Promise.longStackTraces();

var imapConfig = {
    user: 'USERNAME',
    password: 'PASSWORD',
    host: 'HOST',
    port: 993,
    tls: true
};

var imap = new Imap(imapConfig);
Promise.promisifyAll(imap);

imap.once("ready", execute);
imap.once("error", function(err) {
    log.error("Connection error: " + err.stack);
});

imap.connect();

function execute() {
    imap.openBox("INBOX", false, function(err, mailBox) {
        if (err) {
            console.error(err);
            return;
        }
        imap.search(["UNSEEN"], function(err, results) {
            if(!results || results.length){console.log("No unseen email available"); imap.end();return;}     

            imap.setFlags(results, ['\\Seen'], function(err) {
                if (!err) {
                    console.log("marked as read");
                } else {
                    console.log(JSON.stringify(err, null, 2));
                }
            });

            var f = imap.fetch(results, { bodies: "" });
            f.on("message", processMessage);
            f.once("error", function(err) {
                return Promise.reject(err);
            });
            f.once("end", function() {
                console.log("Done fetching all unseen messages.");
                imap.end();
            });
        });
    });
}


function processMessage(msg, seqno) {
    console.log("Processing msg #" + seqno);
    // console.log(msg);

    var parser = new MailParser();
    parser.on("headers", function(headers) {
        console.log("Header: " + JSON.stringify(headers));
    });

    parser.on('data', data => {
        if (data.type === 'text') {
            console.log(seqno);
            console.log(data.text);  /* data.html*/
        }

        // if (data.type === 'attachment') {
        //     console.log(data.filename);
        //     data.content.pipe(process.stdout);
        //     // data.content.on('end', () => data.release());
        // }
     });

    msg.on("body", function(stream) {
        stream.on("data", function(chunk) {
            parser.write(chunk.toString("utf8"));
        });
    });
    msg.once("end", function() {
        // console.log("Finished msg #" + seqno);
        parser.end();
    });
}

{markRead: true} flag sometime it doesn't work, so you need to call set imap.setFlags([uuids], ['\Seen'], cb) explicitly

Upvotes: 11

Reza
Reza

Reputation: 867

This is old question, but I had the same problem today. in the imap.seq.fetch call, there needs to be markSeen:true besides the bodies:"" . it should look like fetch(results,{bodies:"", markSeen:true}) –

And don't forget to open the Inbox in read-write mode as so many have said. imap.openBox('INBOX', false, cb)

Upvotes: 4

Related Questions