Email Integration in WordPress
WordPress sends emails using the wp_mail() function, which is a wrapper around PHP’s mail() function. While it works for simple setups, it is unreliable in production environments because many hosting providers block or throttle PHP mail. Professional deployments typically use an SMTP or API-based email service. A commonly recommended solution is Amazon SES (Simple Email Service), which provides scalable and reliable email delivery.
wp_mail() basics
The wp_mail() function sends emails using the WordPress mail system. It supports plain text and HTML emails and allows attachments and custom headers.
Basic usage:
$to = 'user@example.com';
$subject = 'Welcome to Our Website';
$message = 'Thank you for registering.';
$headers = array('Content-Type: text/plain; charset=UTF-8');
wp_mail($to, $subject, $message, $headers);
Sending HTML email:
add_filter('wp_mail_content_type', function () {
return 'text/html';
});
$to = 'user@example.com';
$subject = 'Account Created';
$message = '<h1>Welcome</h1><p>Your account has been created successfully.</p>';
wp_mail($to, $subject, $message);
remove_filter('wp_mail_content_type', '__return_false');
Adding attachments:
$to = 'user@example.com';
$subject = 'Report';
$message = 'Please find the attached report.';
$attachments = array(WP_CONTENT_DIR . '/uploads/report.pdf');
wp_mail($to, $subject, $message, array(), $attachments);
Using hooks to modify outgoing emails:
add_filter('wp_mail', function ($args) {
$args['headers'][] = 'Reply-To: support@example.com';
return $args;
});
Using Amazon SES for WordPress email delivery
Amazon SES is a cloud-based email service designed for reliable transactional email delivery. Instead of relying on PHP mail, SES uses SMTP or API-based sending.
Benefits of SES:
Reliable email delivery
Better reputation management
High scalability
Detailed email analytics
Cost-effective at scale
Typical architecture:
WordPress → SMTP/API → Amazon SES → Recipient Mail Server
SES SMTP configuration example:
add_action('phpmailer_init', function ($phpmailer) {
$phpmailer->isSMTP();
$phpmailer->Host = 'email-smtp.us-east-1.amazonaws.com';
$phpmailer->SMTPAuth = true;
$phpmailer->Port = 587;
$phpmailer->Username = 'SMTP_USERNAME';
$phpmailer->Password = 'SMTP_PASSWORD';
$phpmailer->SMTPSecure = 'tls';
$phpmailer->From = 'noreply@example.com';
$phpmailer->FromName = 'My Website';
});
Best practices for production email
Always use SMTP or API-based email services instead of PHP mail
Verify domains and email addresses in SES
Use dedicated transactional email addresses (e.g., noreply@domain.com)
Log outgoing emails for debugging
Use queue/background processing for bulk emails
Testing email delivery with MailHog
MailHog is a developer email testing tool that captures outgoing emails from applications and displays them in a web interface. Instead of actually sending emails to recipients, MailHog intercepts them and stores them locally.
This allows developers to inspect:
Email content
Headers
Attachments
HTML rendering
MailHog workflow:
WordPress → SMTP → MailHog → Web UI
Typical MailHog SMTP configuration:
SMTP host: localhost
SMTP port: 1025
Web UI: http://localhost:8025
Example configuration in WordPress:
add_action('phpmailer_init', function ($phpmailer) {
$phpmailer->isSMTP();
$phpmailer->Host = 'localhost';
$phpmailer->Port = 1025;
$phpmailer->SMTPAuth = false;
});
Testing email in a plugin during development:
function rt_send_test_email() {
$to = 'test@example.com';
$subject = 'MailHog Test Email';
$message = 'This email should appear in MailHog UI.';
wp_mail($to, $subject, $message);
}
add_action('init', 'rt_send_test_email');
Important development considerations
If a third-party email plugin (SMTP plugin, transactional email plugin, etc.) is active in a development environment, MailHog may not intercept emails properly. Such plugins often override the mail transport and send emails directly to the external provider.
For safe development:
Disable third-party email plugins locally
Use MailHog SMTP configuration
Avoid using real customer email addresses in development environments
Background Processing in WordPress
Background processing allows long-running tasks to execute asynchronously without blocking user requests. Instead of performing heavy operations during a page load, tasks are queued and processed separately.
Problems with synchronous processing
Slow page loads
PHP timeout errors
Poor user experience
Server resource spikes
Example of synchronous processing problem:
foreach ($users as $user) {
send_email_to_user($user);
}
If thousands of users exist, this process can take several seconds or minutes.
Background processing architecture
User action → Queue task → Background worker → Task execution
In WordPress, background processing can be implemented using:
WP_Cron
Custom queues
Action Scheduler
WP_Cron limitations
WP_Cron is a pseudo-cron system triggered by site visits. It has several limitations:
Depends on traffic
Unreliable timing
Limited scalability
Not suitable for large queues
Action Scheduler
Action Scheduler is a scalable background job processing library developed by the WooCommerce team. It is widely used in production WordPress systems for reliable task scheduling.
Features:
Persistent queue storage
Batch processing
Retry handling
Error logging
Scalable background execution
Installing Action Scheduler
It can be bundled with plugins or installed via Composer.
Composer installation:
composer require woocommerce/action-scheduler
Scheduling a background task
as_schedule_single_action(
time() + 60,
'rt_send_background_email',
array('user_id' => 123)
);
Hook to process the scheduled task:
add_action('rt_send_background_email', 'rt_process_email');
function rt_process_email($user_id) {
$user = get_user_by('ID', $user_id);
if (!$user) {
return;
}
wp_mail(
$user->user_email,
'Background Email',
'This email was sent from a background process.'
);
}
Recurring scheduled task:
as_schedule_recurring_action(
time(),
HOUR_IN_SECONDS,
'rt_hourly_cleanup'
);
Task handler:
add_action('rt_hourly_cleanup', function () {
global $wpdb;
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_%'");
});
Checking scheduled actions
$actions = as_get_scheduled_actions(array(
'hook' => 'rt_send_background_email',
'status' => ActionScheduler_Store::STATUS_PENDING
));
Background processing use cases in WordPress plugins
Bulk email sending
Import/export operations
API synchronization
Generating reports
Image processing
Data migrations
Using Supervisor for background workers
Supervisor is a process control system used on servers to monitor and manage background worker processes. It ensures that background workers remain active and automatically restart if they fail.
Typical use cases:
Queue workers
Long-running background processes
Monitoring background scripts
Example worker command:
php wp-content/plugins/my-plugin/worker.php
Supervisor configuration example:
[program:wp-background-worker]
command=php /var/www/html/wp-content/plugins/my-plugin/worker.php
autostart=true
autorestart=true
stderr_logfile=/var/log/worker.err.log
stdout_logfile=/var/log/worker.out.log
Benefits of using background processing in plugins
Improved performance
Better user experience
Reduced request time
Reliable task execution
Scalable job management
Practical plugin pattern combining email and background jobs
Instead of sending emails during a request:
User registers → Queue email job → Background worker sends email
Example:
add_action('user_register', function ($user_id) {
as_schedule_single_action(
time(),
'rt_send_welcome_email',
array('user_id' => $user_id)
);
});
Email processor:
add_action('rt_send_welcome_email', function ($user_id) {
$user = get_user_by('ID', $user_id);
if (!$user) {
return;
}
wp_mail(
$user->user_email,
'Welcome',
'Thanks for joining our website.'
);
});
This pattern ensures fast user registration while the email is handled asynchronously in the background.