This commit is contained in:
2025-05-07 20:20:17 +00:00
parent f6377d1973
commit 630e911589
40 changed files with 8745 additions and 333 deletions

View File

@ -160,6 +160,9 @@ export class EmailSendJob {
this.deliveryInfo.deliveryTime = new Date();
this.log(`Email delivered successfully to ${currentMx}`);
// Record delivery for sender reputation monitoring
this.recordDeliveryEvent('delivered');
// Save successful email record
await this.saveSuccess();
return DeliveryStatus.DELIVERED;
@ -262,7 +265,35 @@ export class EmailSendJob {
this.log(`Connecting to ${mxServer}:25`);
setCommandTimeout();
this.socket = plugins.net.connect(25, mxServer);
// Check if IP warmup is enabled and get an IP to use
let localAddress: string | undefined = undefined;
if (this.mtaRef.config.outbound?.warmup?.enabled) {
const warmupManager = this.mtaRef.getIPWarmupManager();
if (warmupManager) {
const fromDomain = this.email.getFromDomain();
const bestIP = warmupManager.getBestIPForSending({
from: this.email.from,
to: this.email.getAllRecipients(),
domain: fromDomain,
isTransactional: this.email.priority === 'high'
});
if (bestIP) {
this.log(`Using warmed-up IP ${bestIP} for sending`);
localAddress = bestIP;
// Record the send for warm-up tracking
warmupManager.recordSend(bestIP);
}
}
}
// Connect with specified local address if available
this.socket = plugins.net.connect({
port: 25,
host: mxServer,
localAddress
});
this.socket.on('error', (err) => {
this.log(`Socket error: ${err.message}`);
@ -461,6 +492,54 @@ export class EmailSendJob {
return message;
}
/**
* Record an event for sender reputation monitoring
* @param eventType Type of event
* @param isHardBounce Whether the event is a hard bounce (for bounce events)
*/
private recordDeliveryEvent(
eventType: 'sent' | 'delivered' | 'bounce' | 'complaint',
isHardBounce: boolean = false
): void {
try {
// Check if reputation monitoring is enabled
if (!this.mtaRef.config.outbound?.reputation?.enabled) {
return;
}
const reputationMonitor = this.mtaRef.getReputationMonitor();
if (!reputationMonitor) {
return;
}
// Get domain from sender
const domain = this.email.getFromDomain();
if (!domain) {
return;
}
// Determine receiving domain for complaint tracking
let receivingDomain = null;
if (eventType === 'complaint' && this.email.to.length > 0) {
const recipient = this.email.to[0];
const parts = recipient.split('@');
if (parts.length === 2) {
receivingDomain = parts[1];
}
}
// Record the event
reputationMonitor.recordSendEvent(domain, {
type: eventType,
count: 1,
hardBounce: isHardBounce,
receivingDomain
});
} catch (error) {
this.log(`Error recording delivery event: ${error.message}`);
}
}
/**
* Send a command to the SMTP server and wait for the expected response
*/