Use node-imap to retrieve emails
Asked Answered
T

2

7

Here is a module retrieve_email.js which connects to my gmail account and download the UNSEEN emails after a date. The code is pretty much copied from the example of the [imap module]1.

const Imap = require('imap');
const inspect = require('util').inspect;
const simpleParser = require('mailparser').simpleParser;

const imap = new Imap({
  user: '[email protected]',
  password: 'mypassword',
  host: 'imap.gmail.com',
  port: 993,
  tls: true
});

function openInbox(callback) {
    imap.openBox('INBOX', true, callback);
};

async function parse_email(body) {
  let parsed = simpleParser(body);
  ...............
};

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

      imap.search(['UNSEEN', ['SINCE', 'May 20, 2018']], function(err, results){
        if (err) throw err;
        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) {
            if (info.which === 'TEXT')
              console.log(prefix + 'Body [%s] found, %d total bytes', inspect(info.which), info.size);
              var buffer = '', count = 0;
              stream.on('data', function(chunk) {
                count += chunk.length;
                buffer += chunk.toString('utf8');
                parse_email(buffer);
                if (info.which === 'TEXT')
                  console.log(prefix + 'Body [%s] (%d/%d)', inspect(info.which), count, info.size);
              });
              stream.once('end', function() {
                if (info.which !== 'TEXT')
                  console.log(prefix + 'Parsed header: %s', inspect(Imap.parseHeader(buffer)));
                else
                  console.log(prefix + 'Body [%s] Finished', inspect(info.which));
              });
          });
          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('error', function(err) {
    console.log(err);
  });

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

  imap.connect();
};

When the module is called in index.js, I can see in debug that code is scanned from top to the bottom and the last line of code scanned is imap.connect() and then back to the next line in index.js, with no connection to the gmail account and no action of retrieving the emails. What is wrong with the code above?

UPDATED: status after socket.connect() in debug: enter image description here

Tjon answered 29/12, 2018 at 7:7 Comment(6)
I don't know that library but i just made a functions to send emails with Gmail using Nodemailer and i am using Oauth to authenticate, the other option was to allow unsecured connection. I don't see anywhere you are using Oauth so did you authorised unsecured app connection to Gmail?Cobber
Simon Cadieux, there are signin information in imap definition. Nodemailer can't be used to retrieve imap emails as far as I understand.Tjon
Nothing seems wrong with the code, so you need to debug. Is it able to connect at all, or do you have a packet filter that leaves the connection attempt hanging for minutes? And so on. Look for that sort of mishap. tcpdump or wireshark might be handy.Bronson
Could you add the code from index.js that uses it?Rog
arnt, Styx, I moved all the imap code into index.js and went through them many times in debug. I could see the value of the imap was passed into the imap.connect(). But openInbox was never called and executed. There is no error throw out. I don't quite understand how imap module works. But it seems to me that the email retrieving (openInbox) was never happenedTjon
In debug, after imap.once('ready', function () {.....}, the execution jumps to imap.once('error') & imap.once('end'), and then imap.connect(). In imap.connect(), it called first Connection.prototype.connect = function() {` and other methods in connection.js, and other methods before exit. The whole lot of code within openInbox(function (err,box )... was not executed at all. This gave me the impression that the connection to inbox and email retrieving were never happened.Tjon
C
2

Have a look at this, this is the Gmail API reference from Google. On that page there is an example of how to connect to it using Node.js.

https://developers.google.com/gmail/api/quickstart/nodejs

And here is an example from the same docs that show you how to search and retrieve message list using the q parameter:

https://developers.google.com/gmail/api/v1/reference/users/messages/list

P.S. In my comment i was just asking you if you were sure that you did all the other configuration stuff needed to access your Gmail account by code, meaning creating the app, authorizing OAuth or in what seemed to be your case authorizing less secure application access, just have a look at the links you might find that you are missing something.

And do you really need to use IMAP package ???

Cobber answered 2/1, 2019 at 14:32 Comment(1)
Yes, I need to use a solution which is not tied up with a specific webmail provider. That's why I have chose the node imap module. When there is a new webmail provider, what I need to do is to provide new information in the imap definition and I can retrieve emails from another webmail provider. Thank you anyway!Tjon
T
1

The problem found was with Avast mail shield as middle man intercepting the IMAP traffic and causes the HTTPS fails. Also the IDE debugger stops at somewhere to keep the connecting active but not ready. Here is the detail of the solution.

Tjon answered 9/1, 2019 at 2:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.