Mail Drivers

Detailed guides for configuring and using SMTP, Mailgun, Amazon SES, Postmark, Log, and Array mail drivers in Khadem.

Available Mail Drivers

Khadem supports multiple mail drivers for different use cases.
DriverTypeBest ForSpeedCost
SMTPProtocolSelf-hosted serversVariableServer costs
MailgunAPIHigh volumeFastPay-per-email
Amazon SESAPIAWS ecosystemFastVery low
PostmarkAPITransactionalVery fastPer-email
LogDevelopmentDevelopmentInstantFree
ArrayTestingUnit testingInstantFree

SMTP Driver

SMTP is the standard protocol for sending emails. Use it with Gmail, Outlook, Mailtrap, or your own mail server.
dart

// config/app.dart
'mail': {
  'default': 'smtp',
  
  'smtp': {
    'host': env('SMTP_HOST', 'smtp.gmail.com'),
    'port': env.getInt('SMTP_PORT', defaultValue: 587),
    'username': env('SMTP_USERNAME'),
    'password': env('SMTP_PASSWORD'),
    'encryption': env('SMTP_ENCRYPTION', 'tls'), // 'tls', 'ssl', or 'none'
    'timeout': env.getInt('SMTP_TIMEOUT', defaultValue: 30),
  },
  
  'from': {
    'address': env('MAIL_FROM_ADDRESS'),
    'name': env('MAIL_FROM_NAME'),
  },
}
bash

# Gmail
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_ENCRYPTION=tls

# Mailtrap (Testing)
SMTP_HOST=smtp.mailtrap.io
SMTP_PORT=2525
SMTP_USERNAME=your-mailtrap-username
SMTP_PASSWORD=your-mailtrap-password
SMTP_ENCRYPTION=tls

# Outlook/Office 365
SMTP_HOST=smtp.office365.com
SMTP_PORT=587
SMTP_USERNAME=your-email@outlook.com
SMTP_PASSWORD=your-password
SMTP_ENCRYPTION=tls

# SendGrid
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USERNAME=apikey
SMTP_PASSWORD=your-sendgrid-api-key
SMTP_ENCRYPTION=tls

⚠️ Gmail SMTP Requirements:

  • Enable 2-factor authentication on your Google account
  • Generate an App Password (don't use your regular password!)
  • Use smtp.gmail.com:587 with TLS encryption
  • Gmail has sending limits (500 emails/day for free accounts)

Mailgun Driver

Mailgun is a powerful email API service for sending, receiving, and tracking emails.
dart

// config/app.dart
'mail': {
  'default': 'mailgun',
  
  'mailgun': {
    'domain': env('MAILGUN_DOMAIN'),      // e.g., mg.yourdomain.com
    'api_key': env('MAILGUN_API_KEY'),    // Your Mailgun API key
    'endpoint': env('MAILGUN_ENDPOINT', 'https://api.mailgun.net'),
  },
  
  'from': {
    'address': env('MAIL_FROM_ADDRESS'),
    'name': env('MAIL_FROM_NAME'),
  },
}

// .env
MAILGUN_DOMAIN=mg.example.com
MAILGUN_API_KEY=key-1234567890abcdef1234567890abcdef
MAILGUN_ENDPOINT=https://api.mailgun.net  # or https://api.eu.mailgun.net for EU
dart

import 'package:khadem/khadem.dart';

final mailManager = container.resolve<MailManager>();

// Send via Mailgun (using default driver)
await mailManager
    .to('user@example.com')
    .subject('Welcome')
    .html('<h1>Welcome!</h1>')
    .send();

// Or explicitly use Mailgun driver
await mailManager.mailer('mailgun')
    .to('user@example.com')
    .subject('Newsletter')
    .html('<h1>Latest Updates</h1>')
    .send();

💡 Mailgun Features:

  • Email validation API
  • Detailed analytics and tracking
  • Automatic bounce and complaint handling
  • Webhook events for opens, clicks, bounces
  • Free tier: 5,000 emails/month for 3 months

Amazon SES Driver

Amazon Simple Email Service is a cost-effective email service for AWS users.
dart

// config/app.dart
'mail': {
  'default': 'ses',
  
  'ses': {
    'access_key_id': env('AWS_ACCESS_KEY_ID'),
    'secret_access_key': env('AWS_SECRET_ACCESS_KEY'),
    'region': env('AWS_DEFAULT_REGION', 'us-east-1'),
    'configuration_set': env('AWS_SES_CONFIGURATION_SET'), // Optional
  },
  
  'from': {
    'address': env('MAIL_FROM_ADDRESS'),
    'name': env('MAIL_FROM_NAME'),
  },
}

// .env
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
AWS_DEFAULT_REGION=us-east-1
AWS_SES_CONFIGURATION_SET=my-config-set  # Optional
dart

import 'package:khadem/khadem.dart';

final mailManager = container.resolve<MailManager>();

// Send via Amazon SES
await mailManager
    .to('user@example.com')
    .subject('Order Confirmation')
    .html('<h1>Your order has been confirmed</h1>')
    .send();

// Important: Verify email addresses in SES first!
// Use SES console or AWS CLI to verify sender addresses

💰 Amazon SES Pricing:

  • $0.10 per 1,000 emails
  • 62,000 free emails/month when sent from EC2
  • No setup fees or minimum charges
  • Pay only for what you use

Postmark Driver

Postmark specializes in fast, reliable transactional email delivery.
dart

// config/app.dart
'mail': {
  'default': 'postmark',
  
  'postmark': {
    'server_token': env('POSTMARK_SERVER_TOKEN'),
    'message_stream': env('POSTMARK_MESSAGE_STREAM', 'outbound'),
  },
  
  'from': {
    'address': env('MAIL_FROM_ADDRESS'),
    'name': env('MAIL_FROM_NAME'),
  },
}

// .env
POSTMARK_SERVER_TOKEN=your-server-token-here
POSTMARK_MESSAGE_STREAM=outbound  # or 'broadcasts' for marketing emails
dart

import 'package:khadem/khadem.dart';

final mailManager = container.resolve<MailManager>();

// Send via Postmark
await mailManager
    .to('user@example.com')
    .subject('Password Reset')
    .html('<h1>Reset Your Password</h1>')
    .send();

// Use different message streams
await mailManager.mailer('postmark')
    .to('subscriber@example.com')
    .subject('Newsletter')
    .html('<h1>Monthly Newsletter</h1>')
    .send();

🚀 Postmark Advantages:

  • Industry-leading delivery speed
  • 45-day searchable message history
  • Real-time webhooks for all events
  • Spam score analysis
  • Free tier: 100 emails/month

Log Driver (Development)

The Log driver writes emails to log files instead of sending them. Perfect for development.
dart

// config/development/app.dart
'mail': {
  'default': 'log',
  
  'log': {
    'channel': 'mail', // Optional: specific log channel
  },
  
  'from': {
    'address': 'dev@localhost',
    'name': 'Dev Environment',
  },
}

// Emails will be written to logs instead of being sent
// Check storage/logs/khadem.log to see email content

import 'package:khadem/khadem.dart';

await mailManager
    .to('test@example.com')
    .subject('Test Email')
    .html('<h1>This will be logged</h1>')
    .send();

// Log output:
// [2024-01-15 10:30:00] Mail sent to test@example.com
// Subject: Test Email
// Body: <h1>This will be logged</h1>

Array Driver (Testing)

The Array driver stores emails in memory for testing with assertions.
dart

// In your tests
import 'package:khadem/khadem.dart';
import 'package:test/test.dart';

void main() {
  test('welcome email is sent', () async {
    // Create ArrayTransport
    final transport = ArrayTransport();
    final mailer = Mailer(transport);
    
    // Send email
    await mailer
        .to('user@example.com')
        .subject('Welcome')
        .text('Welcome to our app')
        .send();
    
    // Assert email was sent
    expect(transport.hasSent, isTrue);
    expect(transport.wasSentTo('user@example.com'), isTrue);
    expect(transport.wasSentWithSubject('Welcome'), isTrue);
    
    // Check email details
    final sent = transport.lastSent!;
    expect(sent.subject, equals('Welcome'));
    expect(sent.textBody, contains('Welcome to our app'));
  });

  test('multiple emails', () async {
    final transport = ArrayTransport();
    final mailer = Mailer(transport);
    
    // Send multiple emails
    await mailer.to('user1@example.com').subject('Email 1').send();
    await mailer.to('user2@example.com').subject('Email 2').send();
    
    // Assert count
    expect(transport.sentCount, equals(2));
    
    // Find specific emails
    final user1Email = transport.findSent(
      (msg) => msg.to.any((addr) => addr.email == 'user1@example.com'),
    );
    expect(user1Email, isNotEmpty);
    
    // Clear for next test
    transport.clear();
    expect(transport.hasSent, isFalse);
  });
}

Choosing the Right Driver

Select a mail driver based on your specific needs and constraints.

Choose SMTP when:

  • You have an existing mail server
  • You need complete control
  • You're using Gmail/Outlook for small volumes
  • You want to test with Mailtrap

Choose Mailgun when:

  • You need high email volume
  • You want detailed analytics
  • You need email validation
  • You want webhook events

Choose Amazon SES when:

  • You're already using AWS
  • Cost is a primary concern
  • You need massive scalability
  • You want AWS integration

Choose Postmark when:

  • Delivery speed is critical
  • You send transactional emails
  • You need excellent deliverability
  • You want simple, predictable pricing

On this page