Send WordPress Email Through the Mailgun API
Delivers all WordPress emails through Mailgun's HTTP API, which avoids blocked SMTP ports and gives you Mailgun's delivery logs and tracking.
Opens WPIDE on
Code
add_filter( 'pre_wp_mail', function ( $return, $atts ) {
if ( null !== $return || ! defined( 'WPIDE_MAILGUN_KEY' ) || ! defined( 'WPIDE_MAILGUN_DOMAIN' ) || ! empty( $atts['attachments'] ) ) {
return $return;
}
$lines = is_array( $atts['headers'] ) ? $atts['headers'] : explode( "\n", str_replace( "\r\n", "\n", (string) $atts['headers'] ) );
$h = array( 'from' => '', 'reply-to' => array(), 'cc' => array(), 'bcc' => array(), 'content-type' => '' );
foreach ( $lines as $line ) {
if ( false === strpos( (string) $line, ':' ) ) {
continue;
}
list( $name, $value ) = array_map( 'trim', explode( ':', $line, 2 ) );
$name = strtolower( $name );
if ( in_array( $name, array( 'reply-to', 'cc', 'bcc' ), true ) ) {
$h[ $name ] = array_merge( $h[ $name ], array_filter( array_map( 'trim', explode( ',', $value ) ) ) );
} elseif ( isset( $h[ $name ] ) ) {
$h[ $name ] = $value;
}
}
$is_html = false !== stripos( $h['content-type'], 'text/html' ) || 'text/html' === apply_filters( 'wp_mail_content_type', 'text/plain' );
$to = is_array( $atts['to'] ) ? $atts['to'] : explode( ',', (string) $atts['to'] );
$body = array(
'from' => $h['from'] ? $h['from'] : sprintf( '%s <%s>', apply_filters( 'wp_mail_from_name', 'WordPress' ), apply_filters( 'wp_mail_from', 'wordpress@' . WPIDE_MAILGUN_DOMAIN ) ),
'to' => implode( ',', array_map( 'trim', $to ) ),
'subject' => (string) $atts['subject'],
);
$body[ $is_html ? 'html' : 'text' ] = (string) $atts['message'];
if ( $h['cc'] ) {
$body['cc'] = implode( ',', $h['cc'] );
}
if ( $h['bcc'] ) {
$body['bcc'] = implode( ',', $h['bcc'] );
}
if ( $h['reply-to'] ) {
$body['h:Reply-To'] = implode( ',', $h['reply-to'] );
}
$host = defined( 'WPIDE_MAILGUN_EU' ) && WPIDE_MAILGUN_EU ? 'api.eu.mailgun.net' : 'api.mailgun.net';
$response = wp_remote_post( 'https://' . $host . '/v3/' . rawurlencode( WPIDE_MAILGUN_DOMAIN ) . '/messages', array(
'timeout' => 15,
'headers' => array( 'Authorization' => 'Basic ' . base64_encode( 'api:' . WPIDE_MAILGUN_KEY ) ),
'body' => $body,
) );
$code = (int) wp_remote_retrieve_response_code( $response );
if ( $code >= 200 && $code < 300 ) {
do_action( 'wp_mail_succeeded', $atts );
return true;
}
$message = is_wp_error( $response ) ? $response->get_error_message() : 'Mailgun returned HTTP ' . $code . ': ' . wp_remote_retrieve_body( $response );
do_action( 'wp_mail_failed', new WP_Error( 'wp_mail_failed', $message, $atts ) );
return false;
}, 10, 2 );
Notes
Define WPIDE_MAILGUN_KEY and WPIDE_MAILGUN_DOMAIN (plus WPIDE_MAILGUN_EU as true for EU accounts) in wp-config.php; emails with attachments fall back to the normal mailer.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.