update
This commit is contained in:
@ -12,6 +12,17 @@ import { UnifiedDeliveryQueue, type IQueueItem } from './classes.delivery.queue.
|
||||
import type { Email } from '../core/classes.email.js';
|
||||
import type { IDomainRule } from '../routing/classes.email.config.js';
|
||||
|
||||
/**
|
||||
* Delivery status enumeration
|
||||
*/
|
||||
export enum DeliveryStatus {
|
||||
PENDING = 'pending',
|
||||
DELIVERING = 'delivering',
|
||||
DELIVERED = 'delivered',
|
||||
DEFERRED = 'deferred',
|
||||
FAILED = 'failed'
|
||||
}
|
||||
|
||||
/**
|
||||
* Delivery handler interface
|
||||
*/
|
||||
@ -44,6 +55,12 @@ export interface IMultiModeDeliveryOptions {
|
||||
globalRateLimit?: number;
|
||||
perPatternRateLimit?: Record<string, number>;
|
||||
|
||||
// Bounce handling
|
||||
processBounces?: boolean;
|
||||
bounceHandler?: {
|
||||
processSmtpFailure: (recipient: string, smtpResponse: string, options: any) => Promise<any>;
|
||||
};
|
||||
|
||||
// Event hooks
|
||||
onDeliveryStart?: (item: IQueueItem) => Promise<void>;
|
||||
onDeliverySuccess?: (item: IQueueItem, result: any) => Promise<void>;
|
||||
@ -122,6 +139,8 @@ export class MultiModeDeliverySystem extends EventEmitter {
|
||||
},
|
||||
globalRateLimit: options.globalRateLimit || 100, // 100 emails per minute
|
||||
perPatternRateLimit: options.perPatternRateLimit || {},
|
||||
processBounces: options.processBounces !== false, // Default to true
|
||||
bounceHandler: options.bounceHandler || null,
|
||||
onDeliveryStart: options.onDeliveryStart || (async () => {}),
|
||||
onDeliverySuccess: options.onDeliverySuccess || (async () => {}),
|
||||
onDeliveryFailed: options.onDeliveryFailed || (async () => {})
|
||||
@ -345,6 +364,36 @@ export class MultiModeDeliverySystem extends EventEmitter {
|
||||
// Call delivery failed hook
|
||||
await this.options.onDeliveryFailed(item, error.message);
|
||||
|
||||
// Process as bounce if enabled and we have a bounce handler
|
||||
if (this.options.processBounces && this.options.bounceHandler) {
|
||||
try {
|
||||
const email = item.processingResult as Email;
|
||||
|
||||
// Extract recipient and error message
|
||||
// For multiple recipients, we'd need more sophisticated parsing
|
||||
const recipient = email.to.length > 0 ? email.to[0] : '';
|
||||
|
||||
if (recipient) {
|
||||
logger.log('info', `Processing delivery failure as bounce for recipient ${recipient}`);
|
||||
|
||||
// Process SMTP failure through bounce handler
|
||||
await this.options.bounceHandler.processSmtpFailure(
|
||||
recipient,
|
||||
error.message,
|
||||
{
|
||||
sender: email.from,
|
||||
originalEmailId: item.id,
|
||||
headers: email.headers
|
||||
}
|
||||
);
|
||||
|
||||
logger.log('info', `Bounce record created for failed delivery to ${recipient}`);
|
||||
}
|
||||
} catch (bounceError) {
|
||||
logger.log('error', `Failed to process bounce: ${bounceError.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Emit delivery failed event
|
||||
this.emit('deliveryFailed', item, error);
|
||||
logger.log('error', `Item ${item.id} delivery failed: ${error.message}`);
|
||||
|
Reference in New Issue
Block a user