node-imap icon indicating copy to clipboard operation
node-imap copied to clipboard

node-imap + Mailparser not showing complete email list

Open gcpwebservices opened this issue 5 years ago • 4 comments

I am having problems pushing the parsed email into the array. for example in the email server i have a total of 2 email for this date. after pushing the email inside the mailparser it only shows 1 email instead of 2. I confirmed the total email in result.length. here is my sample code.

var imap = new Imap({
					  	user: retAccount.email_account,
					  	password: atob(retAccount.email_password),
					  	host: retAccount.imap_host,
					  	port: retAccount.imap_port,
					  	tls: ssl
					});

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


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

				          	imap.search(['ALL',['SINCE', '2019-08-05'], ['BEFORE', '2019-08-06']], function (err, results) {
							    var f = imap.fetch(results, {
							      bodies: '',
							      struct: true
							    });

           	 					var messageInbox = [];
								var objMessage = {};

							    f.on('message', function(msg, seqno) {
							      //console.log('Message #%d', seqno);
							      var prefix = '(#' + seqno + ') ';
							      msg.on('body', function(stream, info) {
							 

	                            	async function main(stream,info,results) {

	                        		   	let parsed = await simpleParser(stream);

	                    		   		var attachment = '0';
						    			if(parsed.attachments.length != 0){
						    				attachment = '1';
						    			}
	                            										                         
							          	objMessage = {
							          		seq:info.seqno.toString(),
							          		id:parsed.messageId,
							          		subject: parsed.subject,
				          		    		date:dateFormat(parsed.date,'yyyy-mm-dd HH:MM:ss'),
							          		from_email:parsed.from.value[0].address,
							          		from_name:parsed.from.value[0].name,
							          		attachment:attachment,
							     
							          	};

							          	//console.log(objMessage);

					          			messageInbox.push(objMessage);


									}

									main(stream,info,results);

									


							      });
							      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() {


									jsonRes = {
										success: '1',
											result: {
												account_list:[],
												email_object: messageInbox
											},
										successMessage: 'Email List',
										errorMessage: errorMessage 
							  		};

									res.status(201).json(jsonRes);
									res.end();

	                                imap.end();

							      //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();

gcpwebservices avatar Aug 07 '19 09:08 gcpwebservices

Is your 'message' (or more specifically the 'body') event handler called twice? If so, then perhaps it's a bug/issue with mailparser.

mscdex avatar Aug 07 '19 13:08 mscdex

Hello! thank you for replying. I only call the event once. for example i have 4 emails it will only push 3 emails, but if I console log the parsed data inside the mailparser it will show 4 emails. maybe i am having problems inside the mailparser when im pushing the data into the array. is there anything i can do to fix the problem? :(

gcpwebservices avatar Aug 08 '19 05:08 gcpwebservices

I think i got it fixed buy putting set interval "delay" inside the f.once('end) before i throw the result . =)

gcpwebservices avatar Aug 08 '19 13:08 gcpwebservices

Scenario: This is a wild guess considering the fact that I am also experiencing something similar very to this.

MailParsers function called here is asynchronous and obviously takes a while before it's done parsing. While it's parsing the data, the f.once("end", ()=> {}); would most likely have been emitted meaning we probably have no access to whatever was returned in the mailParser if we end everything on f.once("end", () =>{}).

I assume there might be much better ways to handle this but setTimeout seems to be a fair workaround at this point IMO.

tolumide-ng avatar May 28 '21 22:05 tolumide-ng