mail bounce

This commit is contained in:
babayaga 2026-01-28 12:17:18 +01:00
parent b73843bdc5
commit 877241608f
8 changed files with 1239 additions and 109 deletions

View File

@ -1 +1,9 @@
export interface IImapConfig {
user: string;
password: string;
host: string;
port: number;
tls: boolean;
}
export declare function getMessagesFromInboxWithFilter(imapConfig: IImapConfig, fromAddress?: string, toAddress?: string, subject?: string): Promise<any[]>;
export declare const draft: (subject: string, html: string, options: any) => Promise<void>;

View File

@ -1,5 +1,5 @@
import { ImapFlow } from 'imapflow';
async function getMessagesFromInboxWithFilter(imapConfig, fromAddress, toAddress) {
export async function getMessagesFromInboxWithFilter(imapConfig, fromAddress, toAddress, subject) {
const client = new ImapFlow({
host: imapConfig.host,
port: imapConfig.port,
@ -9,36 +9,34 @@ async function getMessagesFromInboxWithFilter(imapConfig, fromAddress, toAddress
pass: imapConfig.password
}
});
const results = [];
try {
// Connect to the IMAP server
await client.connect();
// Select and lock the INBOX
let lock = await client.getMailboxLock('INBOX');
try {
// Search for messages where the 'from' address and 'to' address match the specified filters
const searchCriteria = {
from: fromAddress,
to: toAddress
};
// Search for messages matching the criteria
const messages = client.fetch({ from: fromAddress, to: toAddress }, { envelope: true, source: true });
// Iterate through each filtered message and print details
const searchCriteria = {};
if (fromAddress)
searchCriteria.from = fromAddress;
if (toAddress)
searchCriteria.to = toAddress;
if (subject)
searchCriteria.subject = subject;
// if no criteria, search all? or return empty? Let's assume search all if empty, or enforce at least one?
// For now, if empty object, fetch might return everything.
const messages = client.fetch(searchCriteria, { envelope: true, source: true });
for await (let message of messages) {
console.log('Message ID:', message.uid);
console.log('From:', message.envelope?.from?.map(f => `${f.name} <${f.address}>`).join(', '));
console.log('To:', message.envelope?.to?.map(f => `${f.name} <${f.address}>`).join(', '));
console.log('Subject:', message.envelope?.subject);
console.log('Date:', message.envelope?.date);
// If you need the message body, you can access it from message.source
console.log('Raw message source:', message.source.toString());
results.push({
uid: message.uid,
envelope: message.envelope,
source: message.source.toString()
});
}
}
finally {
// Always release the lock
lock.release();
}
// Log out and close the connection
await client.logout();
return results;
}
catch (err) {
console.error('Error fetching messages:', err);
@ -75,6 +73,7 @@ export const draft = async (subject, html, options) => {
}
catch (err) {
console.error('Error:', err);
throw err;
}
finally {
// Close the connection
@ -82,25 +81,4 @@ export const draft = async (subject, html, options) => {
console.log('Connection ended.');
}
};
/*
// Example usage
const config: ImapConfig = {
user: 'your-email@example.com',
password: 'your-password',
host: 'imap.your-email-provider.com',
port: 993,
tls: true
};
const fromAddress = 'sender@example.com';
const toAddress = 'recipient@example.com';
getMessagesFromInboxWithFilter(config, fromAddress, toAddress)
.then(() => {
console.log('Finished fetching filtered messages.');
})
.catch(err => {
console.error('Error:', err);
});
*/
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2ltYXAvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQVVuQyxLQUFLLFVBQVUsOEJBQThCLENBQUMsVUFBc0IsRUFBRSxXQUFtQixFQUFFLFNBQWlCO0lBQzFHLE1BQU0sTUFBTSxHQUFHLElBQUksUUFBUSxDQUFDO1FBQzFCLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtRQUNyQixJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUk7UUFDckIsTUFBTSxFQUFFLFVBQVUsQ0FBQyxHQUFHO1FBQ3RCLElBQUksRUFBRTtZQUNKLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtZQUNyQixJQUFJLEVBQUUsVUFBVSxDQUFDLFFBQVE7U0FDMUI7S0FDRixDQUFDLENBQUM7SUFFSCxJQUFJLENBQUM7UUFDSCw2QkFBNkI7UUFDN0IsTUFBTSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFdkIsNEJBQTRCO1FBQzVCLElBQUksSUFBSSxHQUFHLE1BQU0sTUFBTSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVoRCxJQUFJLENBQUM7WUFDSCw0RkFBNEY7WUFDNUYsTUFBTSxjQUFjLEdBQUc7Z0JBQ3JCLElBQUksRUFBRSxXQUFXO2dCQUNqQixFQUFFLEVBQUUsU0FBUzthQUNkLENBQUM7WUFFRiw0Q0FBNEM7WUFDNUMsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUV0RywwREFBMEQ7WUFDMUQsSUFBSSxLQUFLLEVBQUUsSUFBSSxPQUFPLElBQUksUUFBUSxFQUFFLENBQUM7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
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2ltYXAvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQVVuQyxNQUFNLENBQUMsS0FBSyxVQUFVLDhCQUE4QixDQUFDLFVBQXVCLEVBQUUsV0FBb0IsRUFBRSxTQUFrQixFQUFFLE9BQWdCO0lBQ3RJLE1BQU0sTUFBTSxHQUFHLElBQUksUUFBUSxDQUFDO1FBQzFCLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtRQUNyQixJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUk7UUFDckIsTUFBTSxFQUFFLFVBQVUsQ0FBQyxHQUFHO1FBQ3RCLElBQUksRUFBRTtZQUNKLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtZQUNyQixJQUFJLEVBQUUsVUFBVSxDQUFDLFFBQVE7U0FDMUI7S0FDRixDQUFDLENBQUM7SUFFSCxNQUFNLE9BQU8sR0FBVSxFQUFFLENBQUM7SUFFMUIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFdkIsSUFBSSxJQUFJLEdBQUcsTUFBTSxNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWhELElBQUksQ0FBQztZQUNILE1BQU0sY0FBYyxHQUFRLEVBQUUsQ0FBQztZQUMvQixJQUFJLFdBQVc7Z0JBQUUsY0FBYyxDQUFDLElBQUksR0FBRyxXQUFXLENBQUM7WUFDbkQsSUFBSSxTQUFTO2dCQUFFLGNBQWMsQ0FBQyxFQUFFLEdBQUcsU0FBUyxDQUFDO1lBQzdDLElBQUksT0FBTztnQkFBRSxjQUFjLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztZQUU5QywwR0FBMEc7WUFDMUcsMkRBQTJEO1lBRTNELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUVoRixJQUFJLEtBQUssRUFBRSxJQUFJLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztnQkFDbkMsT0FBTyxDQUFDLElBQUksQ0FBQztvQkFDWCxHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUc7b0JBQ2hCLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUTtvQkFDMUIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO2lCQUNsQyxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUM7UUFFRCxNQUFNLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN0QixPQUFPLE9BQU8sQ0FBQztJQUVqQixDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNiLE9BQU8sQ0FBQyxLQUFLLENBQUMsMEJBQTBCLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDL0MsTUFBTSxHQUFHLENBQUM7SUFDWixDQUFDO0FBQ0gsQ0FBQztBQUVELHlCQUF5QjtBQUN6QixNQUFNLFVBQVUsR0FBRztJQUNqQixJQUFJLEVBQUUsa0JBQWtCO0lBQ3hCLElBQUksRUFBRSxHQUFHO0lBQ1QsSUFBSSxFQUFFO1FBQ0osSUFBSSxFQUFFLHdCQUF3QjtRQUM5QixJQUFJLEVBQUUsZUFBZTtLQUN0QjtJQUNELE1BQU0sRUFBRSxJQUFJO0NBQ2IsQ0FBQztBQUVGLHVCQUF1QjtBQUN2QixNQUFNLENBQUMsTUFBTSxLQUFLLEdBQUcsS0FBSyxFQUFFLE9BQWUsRUFBRSxJQUFZLEVBQUUsT0FBTyxFQUFFLEVBQUU7SUFDcEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUE7SUFFcEMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUE7UUFFdEIsTUFBTSxNQUFNLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRWxDLE1BQU0sWUFBWSxHQUFHO1lBQ25CLFFBQVEsRUFBRTtnQkFDUixJQUFJLEVBQUUsb0NBQW9DO2dCQUMxQyxPQUFPLEVBQUUsT0FBTzthQUNqQjtZQUNELE9BQU8sRUFBRSxJQUFJO1lBQ2IsR0FBRyxPQUFPO1NBQ1gsQ0FBQTtRQUVELDBDQUEwQztRQUMxQyxNQUFNLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDekQsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDN0IsTUFBTSxHQUFHLENBQUE7SUFDWCxDQUFDO1lBQVMsQ0FBQztRQUNULHVCQUF1QjtRQUN2QixNQUFNLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDbkMsQ0FBQztBQUNILENBQUMsQ0FBQSJ9

View File

@ -1,2 +1,2 @@
import { IOptions } from '../../types.js';
export declare const test: (options: IOptions) => Promise<false | import("nodemailer/lib/smtp-transport/index.js").SentMessageInfo>;
export declare const test: (options: IOptions) => Promise<import("nodemailer/lib/smtp-transport/index.js").SentMessageInfo>;

View File

@ -20,6 +20,7 @@ const sendHtmlEmail = async ({ from, to, subject, html, attachments }, transport
catch (error) {
logger.error(`Error occurred: ${error.message}`);
logger.trace(error);
throw error;
}
};
export const test = async (options) => {
@ -27,8 +28,7 @@ export const test = async (options) => {
logger.settings.minLevel = (options.logLevel || 'info');
const transport = config?.email[options.transport];
if (!transport) {
logger.error(`No email transport configuration found : ${options.transport}`);
return false;
throw new Error(`No email transport configuration found : ${options.transport}`);
}
if (!options.html && options.src && options.srcInfo) {
options.html = read(options.src, 'string') || '<h1>Test Email</h1>';
@ -42,4 +42,4 @@ export const test = async (options) => {
attachments: options.attachments
}, transport);
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL25vZGVtYWlsZXIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBQ3ZDLE9BQU8sRUFBbUIsZUFBZSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQzdELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUNsRCxPQUFPLEVBQUUsSUFBSSxJQUFJLElBQUksRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBRWhELE1BQU0sYUFBYSxHQUFHLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQW1CLEVBQUUsU0FBNEIsRUFBRSxFQUFFO0lBQ3BILElBQUksQ0FBQztRQUNELE1BQU0sV0FBVyxHQUFHLGVBQWUsQ0FBQztZQUNoQyxHQUFHLFNBQVM7U0FDZixDQUFDLENBQUE7UUFDRixNQUFNLElBQUksR0FBRyxNQUFNLFdBQVcsQ0FBQyxRQUFRLENBQUM7WUFDcEMsSUFBSTtZQUNKLEVBQUUsRUFBRSxvQkFBb0I7WUFDeEIsT0FBTyxFQUFFLGVBQWU7WUFDeEIsSUFBSTtZQUNKLFdBQVc7U0FDZCxDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQTtRQUM5QyxPQUFPLElBQUksQ0FBQTtJQUNmLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7UUFDaEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUN2QixDQUFDO0FBQ0wsQ0FBQyxDQUFBO0FBRUQsTUFBTSxDQUFDLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFBRSxPQUFpQixFQUFFLEVBQUU7SUFDNUMsTUFBTSxNQUFNLEdBQVEsY0FBYyxFQUFFLENBQUE7SUFDcEMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxPQUFPLENBQUMsUUFBZSxJQUFJLE1BQU0sQ0FBQyxDQUFBO0lBQzlELE1BQU0sU0FBUyxHQUFHLE1BQU0sRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBc0IsQ0FBQTtJQUN2RSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDYixNQUFNLENBQUMsS0FBSyxDQUFDLDRDQUE0QyxPQUFPLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQTtRQUM3RSxPQUFPLEtBQUssQ0FBQTtJQUNoQixDQUFDO0lBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksT0FBTyxDQUFDLEdBQUcsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbEQsT0FBTyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQVcsSUFBSSxxQkFBcUIsQ0FBQTtJQUNqRixDQUFDO0lBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsT0FBTyxDQUFDLElBQUksT0FBTyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUNsRSxPQUFPLGFBQWEsQ0FBQztRQUNqQixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7UUFDbEIsRUFBRSxFQUFFLE9BQU8sQ0FBQyxFQUFFO1FBQ2QsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPLElBQUksWUFBWTtRQUN4QyxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxxQkFBcUI7UUFDM0MsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXO0tBQ25DLEVBQUUsU0FBUyxDQUFDLENBQUE7QUFDakIsQ0FBQyxDQUFBIn0=
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL25vZGVtYWlsZXIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBQ3ZDLE9BQU8sRUFBbUIsZUFBZSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQzdELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUNsRCxPQUFPLEVBQUUsSUFBSSxJQUFJLElBQUksRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBRWhELE1BQU0sYUFBYSxHQUFHLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQW1CLEVBQUUsU0FBNEIsRUFBRSxFQUFFO0lBQ3BILElBQUksQ0FBQztRQUNELE1BQU0sV0FBVyxHQUFHLGVBQWUsQ0FBQztZQUNoQyxHQUFHLFNBQVM7U0FDZixDQUFDLENBQUE7UUFDRixNQUFNLElBQUksR0FBRyxNQUFNLFdBQVcsQ0FBQyxRQUFRLENBQUM7WUFDcEMsSUFBSTtZQUNKLEVBQUUsRUFBRSxvQkFBb0I7WUFDeEIsT0FBTyxFQUFFLGVBQWU7WUFDeEIsSUFBSTtZQUNKLFdBQVc7U0FDZCxDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQTtRQUM5QyxPQUFPLElBQUksQ0FBQTtJQUNmLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7UUFDaEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNuQixNQUFNLEtBQUssQ0FBQTtJQUNmLENBQUM7QUFDTCxDQUFDLENBQUE7QUFFRCxNQUFNLENBQUMsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLE9BQWlCLEVBQUUsRUFBRTtJQUM1QyxNQUFNLE1BQU0sR0FBUSxjQUFjLEVBQUUsQ0FBQTtJQUNwQyxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsR0FBRyxDQUFDLE9BQU8sQ0FBQyxRQUFlLElBQUksTUFBTSxDQUFDLENBQUE7SUFDOUQsTUFBTSxTQUFTLEdBQUcsTUFBTSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFzQixDQUFBO0lBQ3ZFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNiLE1BQU0sSUFBSSxLQUFLLENBQUMsNENBQTRDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFBO0lBQ3BGLENBQUM7SUFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxPQUFPLENBQUMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNsRCxPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBVyxJQUFJLHFCQUFxQixDQUFBO0lBQ2pGLENBQUM7SUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLHNCQUFzQixPQUFPLENBQUMsSUFBSSxPQUFPLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFBO0lBQ2xFLE9BQU8sYUFBYSxDQUFDO1FBQ2pCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtRQUNsQixFQUFFLEVBQUUsT0FBTyxDQUFDLEVBQUU7UUFDZCxPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU8sSUFBSSxZQUFZO1FBQ3hDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxJQUFJLHFCQUFxQjtRQUMzQyxXQUFXLEVBQUUsT0FBTyxDQUFDLFdBQVc7S0FDbkMsRUFBRSxTQUFTLENBQUMsQ0FBQTtBQUNqQixDQUFDLENBQUEifQ==

View File

@ -58,10 +58,6 @@ describe('Mail E2E Tests', () => {
const info = await sendTestEmail(options)
if (!info) {
throw new Error('Email sending failed, info is undefined')
}
expect(info).toBeDefined()
expect(info.messageId).toBeDefined()
expect(info.accepted).toContain('recipient@example.com')

View File

@ -1,6 +1,6 @@
import { ImapFlow } from 'imapflow'
interface ImapConfig {
export interface IImapConfig {
user: string;
password: string;
host: string;
@ -8,7 +8,7 @@ interface ImapConfig {
tls: boolean;
}
async function getMessagesFromInboxWithFilter(imapConfig: ImapConfig, fromAddress: string, toAddress: string): Promise<void> {
export async function getMessagesFromInboxWithFilter(imapConfig: IImapConfig, fromAddress?: string, toAddress?: string, subject?: string): Promise<any[]> {
const client = new ImapFlow({
host: imapConfig.host,
port: imapConfig.port,
@ -19,41 +19,37 @@ async function getMessagesFromInboxWithFilter(imapConfig: ImapConfig, fromAddres
}
});
const results: any[] = [];
try {
// Connect to the IMAP server
await client.connect();
// Select and lock the INBOX
let lock = await client.getMailboxLock('INBOX');
try {
// Search for messages where the 'from' address and 'to' address match the specified filters
const searchCriteria = {
from: fromAddress,
to: toAddress
};
const searchCriteria: any = {};
if (fromAddress) searchCriteria.from = fromAddress;
if (toAddress) searchCriteria.to = toAddress;
if (subject) searchCriteria.subject = subject;
// Search for messages matching the criteria
const messages = client.fetch({ from: fromAddress, to: toAddress }, { envelope: true, source: true });
// if no criteria, search all? or return empty? Let's assume search all if empty, or enforce at least one?
// For now, if empty object, fetch might return everything.
const messages = client.fetch(searchCriteria, { envelope: true, source: true });
// Iterate through each filtered message and print details
for await (let message of messages) {
console.log('Message ID:', message.uid);
console.log('From:', message.envelope?.from?.map(f => `${f.name} <${f.address}>`).join(', '));
console.log('To:', message.envelope?.to?.map(f => `${f.name} <${f.address}>`).join(', '));
console.log('Subject:', message.envelope?.subject);
console.log('Date:', message.envelope?.date);
// If you need the message body, you can access it from message.source
console.log('Raw message source:', message.source.toString());
results.push({
uid: message.uid,
envelope: message.envelope,
source: message.source.toString()
});
}
} finally {
// Always release the lock
lock.release();
}
// Log out and close the connection
await client.logout();
return results;
} catch (err) {
console.error('Error fetching messages:', err);
@ -61,17 +57,6 @@ async function getMessagesFromInboxWithFilter(imapConfig: ImapConfig, fromAddres
}
}
// Configuration for IMAP
const imapConfig = {
host: 'imap.example.com',
port: 993,
auth: {
user: 'your_email@example.com',
pass: 'your_password'
},
secure: true
};
// Create a draft email
export const draft = async (subject: string, html: string, options) => {
const client = new ImapFlow(options)
@ -95,31 +80,10 @@ export const draft = async (subject: string, html: string, options) => {
console.log('Draft created successfully.');
} catch (err) {
console.error('Error:', err);
throw err
} finally {
// Close the connection
await client.logout();
console.log('Connection ended.');
}
}
/*
// Example usage
const config: ImapConfig = {
user: 'your-email@example.com',
password: 'your-password',
host: 'imap.your-email-provider.com',
port: 993,
tls: true
};
const fromAddress = 'sender@example.com';
const toAddress = 'recipient@example.com';
getMessagesFromInboxWithFilter(config, fromAddress, toAddress)
.then(() => {
console.log('Finished fetching filtered messages.');
})
.catch(err => {
console.error('Error:', err);
});
*/

View File

@ -21,6 +21,7 @@ const sendHtmlEmail = async ({ from, to, subject, html, attachments }: SendMailO
} catch (error) {
logger.error(`Error occurred: ${error.message}`)
logger.trace(error)
throw error
}
}
@ -29,8 +30,7 @@ export const test = async (options: IOptions) => {
logger.settings.minLevel = (options.logLevel as any || 'info')
const transport = config?.email[options.transport] as ITransportOptions
if (!transport) {
logger.error(`No email transport configuration found : ${options.transport}`)
return false
throw new Error(`No email transport configuration found : ${options.transport}`)
}
if (!options.html && options.src && options.srcInfo) {
options.html = read(options.src, 'string') as string || '<h1>Test Email</h1>'

File diff suppressed because one or more lines are too long