Add List-Unsubscribe header to emails [MAILPOET-793]

Amazon SES supports custom headers only via 'SendRawEmail' action
MailPoet Sending Service doesn't support custom headers yet
This commit is contained in:
Alexey Stoletniy
2017-01-26 15:38:23 +03:00
parent e77717c4c2
commit dd2df429ef
11 changed files with 146 additions and 43 deletions

View File

@ -2,6 +2,7 @@
namespace MailPoet\Mailer;
use MailPoet\Models\Setting;
use MailPoet\Subscription\Url as SubscriptionUrl;
if(!defined('ABSPATH')) exit;
require_once(ABSPATH . 'wp-includes/pluggable.php');
@ -29,8 +30,9 @@ class Mailer {
}
function send($newsletter, $subscriber) {
$extra_params = $this->getExtraParams($newsletter, $subscriber);
$subscriber = $this->formatSubscriberNameAndEmailAddress($subscriber);
return $this->mailer_instance->send($newsletter, $subscriber);
return $this->mailer_instance->send($newsletter, $subscriber, $extra_params);
}
function buildMailer() {
@ -166,6 +168,12 @@ class Mailer {
return sprintf('=?utf-8?B?%s?=', base64_encode($name));
}
function getExtraParams($newsletter, $subscriber) {
$extra_params = array();
$extra_params['unsubscribe_url'] = SubscriptionUrl::getUnsubscribeUrl($subscriber);
return $extra_params;
}
static function formatMailerConnectionErrorResult($error_message) {
return array(
'response' => false,

View File

@ -18,6 +18,7 @@ class AmazonSES {
public $sender;
public $reply_to;
public $return_path;
public $message;
public $date;
public $date_without_time;
private $available_regions = array(
@ -48,10 +49,10 @@ class AmazonSES {
$this->date_without_time = gmdate('Ymd');
}
function send($newsletter, $subscriber) {
function send($newsletter, $subscriber, $extra_params = array()) {
$result = wp_remote_post(
$this->url,
$this->request($newsletter, $subscriber)
$this->request($newsletter, $subscriber, $extra_params)
);
if(is_wp_error($result)) {
return Mailer::formatMailerConnectionErrorResult($result->get_error_message());
@ -66,27 +67,61 @@ class AmazonSES {
return Mailer::formatMailerSendSuccessResult();
}
function getBody($newsletter, $subscriber) {
function getBody($newsletter, $subscriber, $extra_params = array()) {
$this->message = $this->createMessage($newsletter, $subscriber, $extra_params);
$body = array(
'Action' => 'SendEmail',
'Action' => 'SendRawEmail',
'Version' => '2010-12-01',
'Destination.ToAddresses.member.1' => $subscriber,
'Source' => $this->sender['from_name_email'],
'ReplyToAddresses.member.1' => $this->reply_to['reply_to_name_email'],
'Message.Subject.Data' => $newsletter['subject'],
'ReturnPath' => $this->return_path
'RawMessage.Data' => $this->encodeMessage($this->message)
);
if(!empty($newsletter['body']['html'])) {
$body['Message.Body.Html.Data'] = $newsletter['body']['html'];
}
if(!empty($newsletter['body']['text'])) {
$body['Message.Body.Text.Data'] = $newsletter['body']['text'];
}
return $body;
}
function request($newsletter, $subscriber) {
$body = array_map('urlencode', $this->getBody($newsletter, $subscriber));
function createMessage($newsletter, $subscriber, $extra_params = array()) {
$message = \Swift_Message::newInstance()
->setTo($this->processSubscriber($subscriber))
->setFrom(array(
$this->sender['from_email'] => $this->sender['from_name']
))
->setSender($this->sender['from_email'])
->setReplyTo(array(
$this->reply_to['reply_to_email'] => $this->reply_to['reply_to_name']
))
->setReturnPath($this->return_path)
->setSubject($newsletter['subject']);
if(!empty($extra_params['unsubscribe_url'])) {
$headers = $message->getHeaders();
$headers->addTextHeader('List-Unsubscribe', '<' . $extra_params['unsubscribe_url'] . '>');
}
if(!empty($newsletter['body']['html'])) {
$message = $message->setBody($newsletter['body']['html'], 'text/html');
}
if(!empty($newsletter['body']['text'])) {
$message = $message->addPart($newsletter['body']['text'], 'text/plain');
}
return $message;
}
function encodeMessage(\Swift_Message $message) {
return base64_encode($message->toString());
}
function processSubscriber($subscriber) {
preg_match('!(?P<name>.*?)\s<(?P<email>.*?)>!', $subscriber, $subscriber_data);
if(!isset($subscriber_data['email'])) {
$subscriber_data = array(
'email' => $subscriber,
);
}
return array(
$subscriber_data['email'] =>
(isset($subscriber_data['name'])) ? $subscriber_data['name'] : ''
);
}
function request($newsletter, $subscriber, $extra_params = array()) {
$body = array_map('urlencode', $this->getBody($newsletter, $subscriber, $extra_params));
return array(
'timeout' => 10,
'httpversion' => '1.1',

View File

@ -17,7 +17,7 @@ class MailPoet {
$this->reply_to = $reply_to;
}
function send($newsletter, $subscriber) {
function send($newsletter, $subscriber, $extra_params = array()) {
$message_body = $this->getBody($newsletter, $subscriber);
$result = wp_remote_post(
$this->url,

View File

@ -20,9 +20,9 @@ class PHPMail {
$this->mailer = $this->buildMailer();
}
function send($newsletter, $subscriber) {
function send($newsletter, $subscriber, $extra_params = array()) {
try {
$message = $this->createMessage($newsletter, $subscriber);
$message = $this->createMessage($newsletter, $subscriber, $extra_params);
$result = $this->mailer->send($message);
} catch(\Exception $e) {
return Mailer::formatMailerSendErrorResult($e->getMessage());
@ -39,7 +39,7 @@ class PHPMail {
return \Swift_Mailer::newInstance($transport);
}
function createMessage($newsletter, $subscriber) {
function createMessage($newsletter, $subscriber, $extra_params = array()) {
$message = \Swift_Message::newInstance()
->setTo($this->processSubscriber($subscriber))
->setFrom(array(
@ -51,6 +51,10 @@ class PHPMail {
))
->setReturnPath($this->return_path)
->setSubject($newsletter['subject']);
if(!empty($extra_params['unsubscribe_url'])) {
$headers = $message->getHeaders();
$headers->addTextHeader('List-Unsubscribe', '<' . $extra_params['unsubscribe_url'] . '>');
}
if(!empty($newsletter['body']['html'])) {
$message = $message->setBody($newsletter['body']['html'], 'text/html');
}

View File

@ -34,9 +34,9 @@ class SMTP {
$this->mailer = $this->buildMailer();
}
function send($newsletter, $subscriber) {
function send($newsletter, $subscriber, $extra_params = array()) {
try {
$message = $this->createMessage($newsletter, $subscriber);
$message = $this->createMessage($newsletter, $subscriber, $extra_params);
$result = $this->mailer->send($message);
} catch(\Exception $e) {
return Mailer::formatMailerSendErrorResult($e->getMessage());
@ -60,7 +60,7 @@ class SMTP {
return \Swift_Mailer::newInstance($transport);
}
function createMessage($newsletter, $subscriber) {
function createMessage($newsletter, $subscriber, $extra_params = array()) {
$message = \Swift_Message::newInstance()
->setTo($this->processSubscriber($subscriber))
->setFrom(array(
@ -72,6 +72,10 @@ class SMTP {
))
->setReturnPath($this->return_path)
->setSubject($newsletter['subject']);
if(!empty($extra_params['unsubscribe_url'])) {
$headers = $message->getHeaders();
$headers->addTextHeader('List-Unsubscribe', '<' . $extra_params['unsubscribe_url'] . '>');
}
if(!empty($newsletter['body']['html'])) {
$message = $message->setBody($newsletter['body']['html'], 'text/html');
}

View File

@ -17,10 +17,10 @@ class SendGrid {
$this->reply_to = $reply_to;
}
function send($newsletter, $subscriber) {
function send($newsletter, $subscriber, $extra_params = array()) {
$result = wp_remote_post(
$this->url,
$this->request($newsletter, $subscriber)
$this->request($newsletter, $subscriber, $extra_params)
);
if(is_wp_error($result)) {
return Mailer::formatMailerConnectionErrorResult($result->get_error_message());
@ -35,7 +35,7 @@ class SendGrid {
return Mailer::formatMailerSendSuccessResult();
}
function getBody($newsletter, $subscriber) {
function getBody($newsletter, $subscriber, $extra_params = array()) {
$body = array(
'to' => $subscriber,
'from' => $this->sender['from_email'],
@ -43,6 +43,13 @@ class SendGrid {
'replyto' => $this->reply_to['reply_to_email'],
'subject' => $newsletter['subject']
);
$headers = array();
if(!empty($extra_params['unsubscribe_url'])) {
$headers['List-Unsubscribe'] = '<' . $extra_params['unsubscribe_url'] . '>';
}
if($headers) {
$body['headers'] = json_encode($headers);
}
if(!empty($newsletter['body']['html'])) {
$body['html'] = $newsletter['body']['html'];
}
@ -56,8 +63,8 @@ class SendGrid {
return 'Bearer ' . $this->api_key;
}
function request($newsletter, $subscriber) {
$body = $this->getBody($newsletter, $subscriber);
function request($newsletter, $subscriber, $extra_params = array()) {
$body = $this->getBody($newsletter, $subscriber, $extra_params);
return array(
'timeout' => 10,
'httpversion' => '1.1',