diff --git a/changelog.md b/changelog.md index 8db1247..0fe6384 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2026-02-11 - 5.1.3 - fix(docs) +clarify sendEmail default behavior and document automatic MX discovery and delivery modes + +- Updated README to describe automatic MX record discovery and grouping behavior when using sendEmail() (MTA mode) +- Added a Delivery Modes section and API signature for sendEmail(mode) describing mta, forward, and process options +- Expanded examples to show multi-recipient delivery, explicit mode usage, and retained low-level sendOutboundEmail example + ## 2026-02-11 - 5.1.2 - fix(readme) adjust ASCII architecture diagram alignment in README diff --git a/readme.md b/readme.md index 4059031..7a5f5a2 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # @push.rocks/smartmta -A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with a Rust-powered SMTP engine — no nodemailer, no shortcuts. 🚀 +A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with a Rust-powered SMTP engine — no nodemailer, no shortcuts. Automatic MX record discovery means you just call `sendEmail()` and smartmta figures out where to deliver. 🚀 ## Issue Reporting and Security @@ -78,9 +78,10 @@ After installation, run `pnpm build` to compile the Rust binary (`mailer-bin`). **Data flow for outbound mail:** -1. 📝 TypeScript constructs the email and resolves DKIM keys for the sender domain -2. 🦀 Sends to Rust via IPC — Rust builds the RFC 2822 message, signs with DKIM, and delivers via its SMTP client with connection pooling -3. 📬 Result (accepted/rejected recipients, server response) returned to TypeScript +1. 📝 TypeScript constructs the email and calls `sendEmail()` (defaults to MTA mode) +2. 🔍 MTA mode automatically resolves MX records for each recipient domain, sorts by priority, and groups recipients for efficient delivery +3. 🦀 Sends to Rust via IPC — Rust builds the RFC 2822 message, signs with DKIM, and delivers via its SMTP client with connection pooling +4. 📬 Result (accepted/rejected recipients, server response) returned to TypeScript ## Usage @@ -169,9 +170,9 @@ await emailServer.start(); > 🔒 **Note:** `start()` will throw if the Rust binary is not compiled. Run `pnpm build` first. -### 📧 Sending Outbound Emails +### 📧 Sending Emails (Automatic MX Discovery) -All outbound email delivery goes through the Rust SMTP client, accessed via `UnifiedEmailServer.sendOutboundEmail()`. The Rust client handles connection pooling, TLS negotiation, and DKIM signing automatically: +The recommended way to send email is `sendEmail()`. It defaults to **MTA mode**, which automatically resolves MX records for each recipient domain via DNS — you don't need to know the destination mail server: ```typescript import { Email, UnifiedEmailServer } from '@push.rocks/smartmta'; @@ -179,8 +180,7 @@ import { Email, UnifiedEmailServer } from '@push.rocks/smartmta'; // Build an email const email = new Email({ from: 'sender@example.com', - to: ['recipient@example.com'], - cc: ['cc@example.com'], + to: ['alice@gmail.com', 'bob@company.org'], subject: 'Hello from smartmta! 🚀', text: 'Plain text body', html: '

Hello!

HTML body with formatting

', @@ -194,7 +194,50 @@ const email = new Email({ ], }); -// Send via the Rust SMTP client (connection pooling, TLS, DKIM signing) +// Send — MTA mode auto-discovers MX servers for gmail.com and company.org +const emailId = await emailServer.sendEmail(email); + +// Optionally specify a delivery mode explicitly +const emailId2 = await emailServer.sendEmail(email, 'mta'); +``` + +In MTA mode, smartmta: +- 🔍 Resolves MX records for each recipient domain (e.g. `gmail.com`, `company.org`) +- 📊 Sorts MX hosts by priority (lowest = highest priority per RFC 5321) +- 🔄 Tries each MX host in order until delivery succeeds +- 🌐 Falls back to the domain's A record if no MX records exist +- 📦 Groups recipients by domain for efficient batch delivery +- 🔑 Signs outbound mail with DKIM automatically + +### 📮 Delivery Modes + +`sendEmail()` accepts a mode parameter that controls how the email is delivered: + +```typescript +public async sendEmail( + email: Email, + mode: EmailProcessingMode = 'mta', // 'mta' | 'forward' | 'process' + route?: IEmailRoute, + options?: { + skipSuppressionCheck?: boolean; + ipAddress?: string; + isTransactional?: boolean; + } +): Promise +``` + +| Mode | Description | +|---|---| +| `mta` (default) | **Auto MX discovery** — resolves MX records via DNS, delivers directly to the recipient's mail server. No relay configuration needed. | +| `forward` | **Relay delivery** — forwards the email to a configured SMTP host (e.g. an internal mail gateway or third-party relay). | +| `process` | **Scan + deliver** — runs the content scanning / security pipeline first, then delivers via auto MX resolution. | + +### 📬 Direct SMTP Delivery (Low-Level) + +For cases where you know the exact target SMTP server (e.g. relaying to a specific host), use the lower-level `sendOutboundEmail()`: + +```typescript +// Send directly to a known SMTP server (bypasses MX resolution) const result = await emailServer.sendOutboundEmail('smtp.example.com', 587, email, { auth: { user: 'sender@example.com', pass: 'your-password' }, dkimDomain: 'example.com', diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 38df9c9..b5fb2f3 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartmta', - version: '5.1.2', + version: '5.1.3', description: 'A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with Rust acceleration.' }