Database-backed email sender configuration management with provider verification integration
npm install @bernierllc/email-sender-managerDatabase-backed email sender configuration management with provider verification integration. Manage, verify, and intelligently select email sender configurations for your applications.
``bash`
npm install @bernierllc/email-sender-manager
- Database-Backed Storage: Persistent sender configurations with transaction support
- Provider Integration: Verify sender configurations with email providers (SendGrid, Mailgun, etc.)
- Smart Sender Selection: Intelligent sender selection based on domain matching, priority, or round-robin strategies
- Bootstrap System: Automatic database schema creation and default sender seeding
- Full TypeScript Support: Complete type definitions with strict mode compliance
- Comprehensive Validation: Email format validation, domain restrictions, and configuration checks
`typescript
import { EmailSenderManager } from '@bernierllc/email-sender-manager';
import type { DatabaseAdapter } from '@bernierllc/email-sender-manager';
// Implement your database adapter
const databaseAdapter: DatabaseAdapter = {
async execute(query: string, params?: unknown[]): Promise
// Your database execute logic
},
async query
// Your database query logic
},
async queryOne
// Your database queryOne logic
},
async transaction
// Your transaction logic
},
};
// Initialize manager
const manager = new EmailSenderManager({
database: databaseAdapter,
bootstrap: {
enabled: true,
createTables: true,
seedDefaultSenders: true,
defaultSenders: [
{
name: 'Default Sender',
fromEmail: 'noreply@example.com',
fromName: 'My App',
provider: 'sendgrid',
priority: 1,
},
],
environment: 'production',
},
selection: {
strategy: 'domain_match',
fallbackToDefault: true,
domainMatchingRules: [],
},
});
// Bootstrap database
await manager.bootstrapDatabase();
`
A sender configuration represents an email address that can send emails through your application:
`typescript`
interface SenderConfiguration {
id: string;
name: string;
description?: string;
fromEmail: string;
fromName: string;
replyToEmail?: string;
replyToName?: string;
provider: string;
providerSenderId?: string;
providerMetadata?: Record
isVerified: boolean;
verificationStatus: 'pending' | 'verified' | 'failed' | 'expired';
lastVerifiedAt?: Date;
isDefault: boolean;
isActive: boolean;
priority: number; // Lower = higher priority
allowedDomains?: string[];
domain: string;
createdAt: Date;
updatedAt: Date;
createdBy: string;
lastModifiedBy: string;
}
Providers verify sender configurations with email service providers:
`typescript`
interface SenderProviderPlugin {
readonly providerId: string;
readonly name: string;
validateSender(email: string): Promise
getVerifiedSenders(): Promise
syncSender(sender: SenderConfiguration): Promise
getCapabilities(): string[];
}
`typescript
// Create a new sender
const sender = await manager.createSender({
name: 'Marketing Team',
fromEmail: 'marketing@example.com',
fromName: 'Marketing Department',
replyToEmail: 'support@example.com',
provider: 'sendgrid',
priority: 10,
allowedDomains: ['example.com', '*.example.com'],
createdBy: 'admin-user',
});
console.log(Created sender: ${sender.id});`
`typescript`
// Update sender configuration
const updated = await manager.updateSender(sender.id, {
name: 'Updated Name',
priority: 5,
isActive: true,
lastModifiedBy: 'admin-user',
});
`typescript
// List all active senders
const activeSenders = await manager.listSenders({
isActive: true,
orderBy: 'priority',
orderDirection: 'asc',
});
// List verified senders for a specific provider
const verifiedSenders = await manager.listSenders({
provider: 'sendgrid',
isVerified: true,
limit: 10,
offset: 0,
});
// Paginate through results
console.log(Total: ${activeSenders.total}, Showing: ${activeSenders.items.length});Has more: ${activeSenders.hasMore}
console.log();`
`typescript
// Select best sender for an email
const bestSender = await manager.selectBestSender('user@example.com', {
strategy: 'domain_match', // or 'priority' or 'round_robin'
allowUnverified: false,
});
if (bestSender) {
console.log(Using sender: ${bestSender.fromEmail} (priority: ${bestSender.priority}));
}
// Select sender for specific provider
const sendgridSender = await manager.selectBestSender('user@example.com', {
provider: 'sendgrid',
strategy: 'priority',
});
`
`typescript
import type { SenderProviderPlugin } from '@bernierllc/email-sender-manager';
// Implement a provider plugin
class SendGridProvider implements SenderProviderPlugin {
readonly providerId = 'sendgrid';
readonly name = 'SendGrid';
constructor(private apiKey: string) {}
async validateSender(email: string): Promise
// Call SendGrid API to verify sender
const verifiedSenders = await this.getVerifiedSenders();
const match = verifiedSenders.find((s) => s.email === email);
return {
isVerified: Boolean(match?.isVerified),
verificationStatus: match?.verificationStatus || 'not_found',
lastChecked: new Date(),
metadata: { providerId: match?.id },
};
}
async getVerifiedSenders(): Promise
// Fetch from SendGrid API
return [];
}
async syncSender(sender: SenderConfiguration): Promise
// Sync with SendGrid
return { success: true, senderId: sender.id, synced: true };
}
getCapabilities(): string[] {
return ['verification', 'sync'];
}
}
// Register provider
const provider = new SendGridProvider(process.env.SENDGRID_API_KEY!);
await manager.registerProvider(provider);
// Verify a sender
const verification = await manager.verifySender(sender.id);
console.log(Verified: ${verification.isVerified});`
`typescript
const manager = new EmailSenderManager({
database: databaseAdapter,
bootstrap: {
enabled: true,
createTables: true,
seedDefaultSenders: true,
defaultSenders: [
{
name: 'Default Sender',
fromEmail: 'noreply@example.com',
fromName: 'My Application',
provider: 'sendgrid',
priority: 1,
},
{
name: 'Marketing Sender',
fromEmail: 'marketing@example.com',
fromName: 'Marketing Team',
provider: 'sendgrid',
priority: 10,
allowedDomains: ['example.com'],
},
],
environment: 'production',
},
});
// Run bootstrap
const result = await manager.bootstrapDatabase();
console.log(result.message);
// Output: "Bootstrap completed successfully. Tables created: true, Senders seeded: 2"
`
Selects senders based on domain relationships:
1. Exact domain match: example.com sender for user@example.comexample.com
2. Subdomain match: sender for user@app.example.comallowedDomains
3. Allowed domains: Senders with configuration
4. Fallback to priority: If no domain match found
`typescript`
const sender = await manager.selectBestSender('user@app.example.com', {
strategy: 'domain_match',
});
Selects sender with lowest priority number (higher priority):
`typescript`
const sender = await manager.selectBestSender('user@example.com', {
strategy: 'priority',
});
Distributes selections evenly across available senders:
`typescript`
const sender = await manager.selectBestSender('user@example.com', {
strategy: 'round_robin',
});
`typescript
import {
extractDomain,
isDomainMatch,
isValidEmail,
getParentDomain,
isSubdomainOf,
} from '@bernierllc/email-sender-manager';
// Extract domain from email
const domain = extractDomain('user@example.com'); // "example.com"
// Check domain matching with wildcards
const matches = isDomainMatch('app.example.com', '*.example.com'); // true
// Validate email format
const valid = isValidEmail('user@example.com'); // true
// Get parent domain
const parent = getParentDomain('app.example.com'); // "example.com"
// Check subdomain relationship
const isSub = isSubdomainOf('app.example.com', 'example.com'); // true
`
`typescript
import { validateCreateSenderRequest } from '@bernierllc/email-sender-manager';
// Validate sender creation request
const validation = validateCreateSenderRequest({
name: 'Test Sender',
fromEmail: 'test@example.com',
fromName: 'Test',
provider: 'sendgrid',
createdBy: 'admin',
});
if (validation.errors.length > 0) {
console.error('Validation errors:', validation.errors);
}
if (validation.warnings.length > 0) {
console.warn('Validation warnings:', validation.warnings);
}
`
The package automatically creates the following database schema:
`sql`
CREATE TABLE IF NOT EXISTS email_senders (
id VARCHAR(255) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
from_email VARCHAR(255) NOT NULL UNIQUE,
from_name VARCHAR(255) NOT NULL,
reply_to_email VARCHAR(255),
reply_to_name VARCHAR(255),
provider VARCHAR(100) NOT NULL,
provider_sender_id VARCHAR(255),
provider_metadata JSON,
is_verified BOOLEAN DEFAULT FALSE,
verification_status VARCHAR(50) DEFAULT 'pending',
last_verified_at TIMESTAMP NULL,
verification_error TEXT,
is_default BOOLEAN DEFAULT FALSE,
is_active BOOLEAN DEFAULT TRUE,
priority INTEGER DEFAULT 100,
allowed_domains JSON,
domain VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by VARCHAR(255),
last_modified_by VARCHAR(255),
INDEX idx_email_senders_from_email (from_email),
INDEX idx_email_senders_domain (domain),
INDEX idx_email_senders_provider (provider),
INDEX idx_email_senders_active (is_active),
INDEX idx_email_senders_default (is_default),
INDEX idx_email_senders_priority (priority)
);
Main class for managing sender configurations.
#### Constructor
`typescript`
constructor(config: SenderManagerConfig)
#### Methods
- bootstrapDatabase(): Promise - Initialize database and seed default senderscreateSender(request: CreateSenderRequest): Promise
- - Create new senderupdateSender(id: string, updates: UpdateSenderRequest): Promise
- - Update existing senderdeleteSender(id: string): Promise
- - Delete sendergetSender(id: string): Promise
- - Get sender by IDlistSenders(options?: ListSendersOptions): Promise
- - List senders with filtersvalidateSender(id: string): Promise
- - Validate sender configurationverifySender(id: string, provider?: string): Promise
- - Verify sender with providerselectBestSender(fromEmail: string, options?: SelectionOptions): Promise
- - Select optimal sendergetDefaultSender(provider?: string): Promise
- - Get default sendergetSendersByDomain(domain: string): Promise
- - Get senders for domainregisterProvider(provider: SenderProviderPlugin): Promise
- - Register provider pluginsyncWithProviders(): Promise
- - Sync all senders with providerscleanupInactiveSenders(): Promise
- - Remove inactive senders
- Logger: Not applicable - Core utility package with database-backed state (logging handled at service layer)
- Docs-Suite: Ready - Comprehensive API documentation with TypeDoc comments exported
- NeverHub: Not applicable - Core utility package focused on email sender configuration management. NeverHub integration is appropriate at the service layer where sender selection events and metrics would be published to the event bus. This package provides the foundational primitives for sender management without environment-dependent behavior.
The package includes comprehensive tests with 90%+ coverage:
`bashRun tests
npm test
Copyright (c) 2025 Bernier LLC
This file is licensed to the client under a limited-use license.
The client may use and modify this code only within the scope of the project it was delivered for.
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
- @bernierllc/email-sender - Email sending abstraction
- @bernierllc/logger - Logging utilities
- @bernierllc/retry-policy - Retry logic utilities