0

I have been trying to use node-imap to move emails from my inbox into a folder i created called "processed". But whenever i run my code, a random number of emails were moved. Those emails that were not moved throws this error:

Error: Error in IMAP command MOVE: Invalid messageset (0.001 + 0.000 secs).

When i run my code again, a random number of those emails that previously were unable to move were moved and others throw the same error. Running my code a few more times after that eventually moved all the emails to my "processed" folder.

I have no idea why certain emails could not be moved on the first run and unable to find any resources about "Error in IMAP command MOVE: Invalid messageset". There were many resources about IMAP command FETCH but I couldn't find any about IMAP command MOVE.

My code is as below:

   function moveEmailToFolder(){
    const Imap = require('imap');
    const imap = new Imap({
        user: config.email.user,
        password: config.email.password,
        host: config.email.host,
        port: 993,
        tls: {
                secureProtocol: "TLSv1_method"
        }
    });
    imap.connect();
    imap.once('ready', function(){
        imap.openBox("INBOX", false, function(err, box) {
            imap.search([ 'ALL' ], function(err, results) {
                let mail_no = "1:*";
                var f = imap.seq.fetch(mail_no, {
                    bodies: "",
                    struct: true,
                    markSeen: true
                });
                let all_emails = [];
                f.on("message", function(msg, seqno) {
                    let move_email_fn_calls = 0;
                    function move_email(uid){
                        imap.seq.move(uid, "processed", function(err) {
                            if( !err ){
                                console.log(uid+": move success");
                            } else if( err && move_email_fn_calls < 3 ){
                                move_email_fn_calls++;
                                move_email(uid);
                                console.log(uid+": " + err);
                            } else if( err && move_email_fn_calls >= 3){
                                console.log(uid+": Unable to move");
                            }
                            console.log(move_email_fn_calls);
                        });
                    } 
                    move_email(seqno);
                });
                f.once("error", function(err) {
                    console.log(err);
                });
                f.once("end", function() {
                    imap.end();
                });
            });
        });
    });
    imap.once('error', function(err) {
        console.log(err);
    });
    imap.once('end', function() {
        console.log('Connection ended');
    });
}

Any help or advice is appreciated. Thanks all.

ikikika
  • 79
  • 6

1 Answers1

3

You are addressing the messages using sequence numbers while modifying the mailbox, which invalidates the sequence numbers.

Sequence numbers change. 4 means "the fourth message in the mailbox right now". If you move the second message elsewhere, the message that used to have number 4 now has number 3.

You have two options. First, you can use UIDs, which will work because UIDs are unique identifiers. Just delete both instances of .seq. Second, you can move all the messages using one command instead of looping and issuing an unholy number of single-message moves. imap.move(results, …, one command, or imap.seq.move(results, … which works because then you only reference messages before the modification changes the sequence numbers.

arnt
  • 8,949
  • 5
  • 24
  • 32