I finished coding Webhook Postmark support.
Event webhooks (Bounce, Spam plain, SubscriptionChange) from Postmark to Mautic are supported with this change.
I’m using this code in production with Mautic 4.4.2 and it works like a charm.
I share here the portions of code to modify, I hope it will be useful to someone:
in file: /mautic/app/bundles/EmailBundle/Config/config.php
Replace:
'mautic.transport.postmark' => [
'class' => 'Mautic\EmailBundle\Swiftmailer\Transport\PostmarkTransport',
'serviceAlias' => 'swiftmailer.mailer.transport.%s',
'methodCalls' => [
'setUsername' => ['%mautic.mailer_user%'],
'setPassword' => ['%mautic.mailer_password%'],
],
],
By:
'mautic.transport.postmark' => [
'class' => 'Mautic\EmailBundle\Swiftmailer\Transport\PostmarkTransport',
'serviceAlias' => 'swiftmailer.mailer.transport.%s',
'arguments' => [
'mautic.email.model.transport_callback',
'%mautic.mailer_mailjet_sandbox%',
'%mautic.mailer_mailjet_sandbox_default_mail%',
],
'methodCalls' => [
'setUsername' => ['%mautic.mailer_user%'],
'setPassword' => ['%mautic.mailer_password%'],
],
],
Add:
'mailer_postmark_sandbox' => false,
'mailer_postmark_sandbox_default_mail' => null,
After:
'mailer_mailjet_sandbox' => false,
'mailer_mailjet_sandbox_default_mail' => null,
** Replace all code in file: /mautic/app/bundles/EmailBundle/Swiftmailer/Transport/PostmarkTransport.php
By:
<?php
namespace Mautic\EmailBundle\Swiftmailer\Transport;
use Mautic\EmailBundle\Model\TransportCallback;
use Mautic\LeadBundle\Entity\DoNotContact;
use Symfony\Component\HttpFoundation\Request;
/**
* Class PostmarkTransport.
*/
class PostmarkTransport extends \Swift_SmtpTransport implements CallbackTransportInterface
{
/**
* @var bool
*/
private $sandboxMode;
/**
* @var string
*/
private $sandboxMail;
/**
* @var TransportCallback
*/
private $transportCallback;
/**
* {@inheritdoc}
*/
public function __construct(TransportCallback $transportCallback, $sandboxMode = false, $sandboxMail = '')
{
parent::__construct('smtp.postmarkapp.com', 587, 'tls');
$this->setAuthMode('login');
$this->setSandboxMode($sandboxMode);
$this->setSandboxMail($sandboxMail);
$this->transportCallback = $transportCallback;
}
/**
* @param null $failedRecipients
*
* @return int|void
*
* @throws \Exception
*/
public function send(\Swift_Mime_SimpleMessage $message, &$failedRecipients = null)
{
// add leadIdHash to track this email
if (isset($message->leadIdHash)) {
// contact leadidHeash and email to be sure not applying email stat to bcc
$message->getHeaders()->removeAll('X-MJ-CUSTOMID');
$message->getHeaders()->addTextHeader('X-MJ-CUSTOMID', $message->leadIdHash.'-'.key($message->getTo()));
}
if ($this->isSandboxMode()) {
$message->setSubject(key($message->getTo()).' - '.$message->getSubject());
$message->setTo($this->getSandboxMail());
}
return parent::send($message, $failedRecipients);
}
/**
* Returns a "transport" string to match the URL path /mailer/{transport}/callback.
*
* @return mixed
*/
public function getCallbackPath()
{
return 'postmark';
}
/**
* Handle response.
*
* @return mixed
*/
public function processCallbackRequest(Request $request)
{
$postData = json_decode($request->getContent(), true);
if (is_array($postData)) {
if (!in_array($postData['RecordType'], ['Bounce', 'SpamComplaint', 'SubscriptionChange'])) {
return false;
}
if ('Bounce' === $postData['RecordType']) {
$reason = $postData['Name'].': '.$postData['Description'];
$type = DoNotContact::BOUNCED;
echo "bounce";
} elseif ('SpamComplaint' === $postData['RecordType']) {
$reason = $postData['Name'].': '.$postData['Description'];
$type = DoNotContact::UNSUBSCRIBED;
} elseif ('SubscriptionChange' === $postData['RecordType']) {
$reason = 'User unsubscribed';
$type = DoNotContact::UNSUBSCRIBED;
} else {
return false;
}
$this->transportCallback->addFailureByAddress($postData['Email'], $reason, $type);
} else {
// respone must be an array
return null;
}
}
/**
* @return bool
*/
private function isSandboxMode()
{
return $this->sandboxMode;
}
/**
* @param bool $sandboxMode
*/
private function setSandboxMode($sandboxMode)
{
$this->sandboxMode = $sandboxMode;
}
/**
* @return string
*/
private function getSandboxMail()
{
return $this->sandboxMail;
}
/**
* @param string $sandboxMail
*/
private function setSandboxMail($sandboxMail)
{
$this->sandboxMail = $sandboxMail;
}
}