mscdex / node-imap

An IMAP client module for node.js.
MIT License
2.17k stars 382 forks source link

I seem to have some trouble understanding connection events #823

Closed ghost closed 4 years ago

ghost commented 4 years ago

I connect to gmail and can open Inbox. It works to fetch emails. But the mail event gets only fired once at start, when i fetch mails, it does not get fired when i send a new mail.

imap.once('mail', function(numNewMsgs) {
    l('NEW MESSAGE', numNewMsgs);
});

also subscribing does not seem to have any effect. I have all connection events logging their args to console, but they never get fired. My understanding would have been, that not ending imap would keep the connection open and new mail to a subscribed box would trigger mail or update or any other event. But nothing happens. What am I getting wrong?

This is my whole testcode:

global.l = console.log;
import Imap from 'imap';
import { inspect } from 'util';

const imap = new Imap({
    user: 'xxx@gmail.com',
    password: 'xxx',
    host: 'imap.gmail.com',
    port: 993,
    tls: true,
    tlsOptions: { servername: 'imap.gmail.com' },
    debug: console.log
});

imap.once('ready', function() {
    imap.getBoxes(function(error, boxes) {
        if (error) throw error;
//l('BOXES', boxes);
        for (let box in boxes) {
            imap.subscribeBox(box);
            l('SUBSCRIBED TO', box);
        }
    });
    imap.openBox('INBOX', true, function(error, box) {
        if (error) throw error;

        var f = imap.seq.fetch('1:50', {
            bodies: 'HEADER.FIELDS (FROM TO SUBJECT DATE)',
            struct: true
        });
        f.on('message', function(msg, seqno) {
            console.log('Message #%d', seqno);
            var prefix = '(#' + seqno + ') ';
            msg.on('body', function(stream, info) {
                var buffer = '';
                stream.on('data', function(chunk) {
                    buffer += chunk.toString('utf8');
                });
                stream.once('end', function() {
                    console.log(prefix + 'Parsed header: %s', inspect(Imap.parseHeader(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();
        });

    });
});

imap.once('mail', function(numNewMsgs) {
    l('NEW MESSAGE', numNewMsgs);
});

imap.once('update', function(seqno, info) {
    l('UPDATE', seqno, info);
});

imap.once('expunge', function(seqno) {
    l('expunge', seqno);
});

imap.once('alert', function(message) {
    l('alert', message);
});

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

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

imap.connect();
mscdex commented 4 years ago

Do you see updates when you set keepalive: { forceNoop: true } in your connection config object?

ghost commented 4 years ago

No, no change, did it like this:

const imap = new Imap({
    user: 'xxx@gmail.com',
    password: 'xxx',
    host: 'imap.gmail.com',
    port: 993,
    tls: true,
    tlsOptions: { servername: 'imap.gmail.com' },
    keepalive: { forceNoop: true }
});
mscdex commented 4 years ago

Oh I see the issue now, you're using imap.once() instead of imap.on(). Change that and you should see the new mail notifications.

ghost commented 4 years ago

Ah, I see, once like “one time” not like “once it happens” :) Sorry no native english speaker.

Yes, now the new mail event is triggered, also when i move something out of inbox the expunge event gets triggered.

but when i move something from one subscribed folder to another nothing happens. how do I keep track of whats happening in the other boxes? What do i subscribe for?

mscdex commented 4 years ago

subscribeBox() doesn't do what you're thinking it does. If you want to monitor other mailboxes (efficiently), you will need separate connections.

ghost commented 4 years ago

I see, subscribe is only to mark mailboxes, it does not have any technical consequence. Those old protocols are kinda weird. Thanks for your help!

mscdex commented 4 years ago

Actually subscribeBox() is a bit of a relic back when the creators of IMAP envisioned some sort of Usenet-like "mailbox" subscription experience.