Hello I'm trying write async function to be called for 100 seconds to see if new email arrive.
Logic works fine, console return new message after resolve, but after this comes errors, like try open connection after everything resolved.
I spent 8h on solve this issue, and really don't know where I did mistake.
Short version what I want achive:
- Connect to imap
- Listen for new mails
- If new email comes return values, and stop everything in this function
- If no new message in 100sekonds, stop everything in this function and return null/false
Here error from console:
Listening for new messages...
New message has been delivered! Number of new messages: 1
{
"sender": "[email protected]",
"subject": "Mailbox Verification Code",
"body": "The PIN for [email protected] is: sWmO-604273 (expired on 26/03 17:43)"
}
CHUJ
IMAP error after connection closed: AggregateError
at internalConnectMultiple (node:net:1114:18)
at afterConnectMultiple (node:net:1667:5) {
code: 'ECONNREFUSED',
source: 'socket',
[errors]: [
Error: connect ECONNREFUSED ::1:143
at createConnectionError (node:net:1634:14)
at afterConnectMultiple (node:net:1664:40) {
errno: -4078,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '::1',
port: 143
},
Error: connect ECONNREFUSED 127.0.0.1:143
at createConnectionError (node:net:1634:14)
at afterConnectMultiple (node:net:1664:40) {
errno: -4078,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 143
}
]
}
IMAP connection ended
Here is full code:
const Imap = require('imap');
const { simpleParser } = require('mailparser');
// Definicja funkcji nasłuchującej na nowe wiadomości
function waitForEmail(imapConfig, timeout = 100000) {
return new Promise((resolve, reject) => {
new Promise((resolve, reject) => {
resolve('Success!');
// Po tym punkcie, żaden kod nie powinien być wykonywany
return; // Dobrze jest zwrócić, aby zapobiec wykonaniu dalszego kodu
});
const imap = new Imap(imapConfig);
let isResolvedOrRejected = false; // Flag to prevent multiple resolve/reject calls
function openInbox(cb) {
imap.openBox('INBOX', false, cb);
}
imap.once('error', function (err) {
if (!isResolvedOrRejected) {
console.log('IMAP error after connection closed:', err);
}
});
imap.once('end', function () {
console.log('IMAP connection ended');
if (!isResolvedOrRejected) {
isResolvedOrRejected = true;
reject(new Error('IMAP connection unexpectedly closed'));
}
});
imap.connect();
imap.once('ready', function () {
openInbox(function (err, box) {
if (err) {
console.error('Error opening inbox:', err);
if (!isResolvedOrRejected) {
isResolvedOrRejected = true;
reject(err);
}
return;
}
console.log('Listening for new messages...');
imap.on('mail', function (numNewMsgs) {
console.log(`New message has been delivered! Number of new messages: ${numNewMsgs}`);
var fetch = imap.seq.fetch(box.messages.total + ':*', {
bodies: '',
struct: true
});
fetch.on('message', function (msg) {
let emailBuffer = [];
msg.on('body', function (stream) {
stream.on('data', function (chunk) {
emailBuffer.push(chunk);
});
});
msg.once('end', function () {
simpleParser(Buffer.concat(emailBuffer), (err, mail) => {
if (err) {
console.error('Error parsing:', err);
return;
}
// Create a JSON object with the data you're interested in
let emailInfo = {
sender: mail.from.value.map(a => a.address).join(', '),
subject: mail.subject,
body: mail.text || mail.html || 'No text content.'
};
// Print out the JSON object
console.log(JSON.stringify(emailInfo, null, 2));
imap.end();
sleep(5, 6)
if (!isResolvedOrRejected) {
isResolvedOrRejected = true;
console.log('CHUJ')
resolve(emailInfo);
}
});
});
});
});
});
});
// Odrzucenie Promise po upływie limitu czasu
setTimeout(() => {
if (!isResolvedOrRejected) {
isResolvedOrRejected = true;
reject(new Error('Timeout: No new email was received.'));
}
}, timeout);
}); }
function sleep(minSeconds, maxSeconds) { // Oblicz losowy czas trwania w milisekundach na podstawie sekund const sleepDuration = Math.floor(Math.random() * (maxSeconds - minSeconds + 1) + minSeconds) * 1000;
// Zwróć Promise, który rozwiązuje się po upływie obliczonego czasu return new Promise(resolve => setTimeout(resolve, sleepDuration)); }
// Eksport funkcji do użycia w innych plikach module.exports = { waitForEmail };