workaround Mailgun not returning all headers in webhook

This commit is contained in:
Rich Lott 2018-12-13 17:04:38 +00:00
parent 7d66a7e439
commit 740624b858
2 changed files with 51 additions and 36 deletions

View File

@ -58,8 +58,7 @@ class CRM_Mailgunny_Page_Webhook extends CRM_Core_Page {
* @return string
*/
public function getApiKey() {
// @todo fetch from somewhere.
$v = Civi::settings()->get('mailgun_api_key');
return Civi::settings()->get('mailgun_api_key');
}
/**
@ -74,6 +73,7 @@ class CRM_Mailgunny_Page_Webhook extends CRM_Core_Page {
elseif ($event->severity === 'temporary') {
$this->processTemporaryBounce($event);
}
echo '{"success": 1}';
break;
case 'accepted':
@ -90,8 +90,6 @@ class CRM_Mailgunny_Page_Webhook extends CRM_Core_Page {
default:
throw new CRM_Mailgunny_WebhookRejectedException("Unrecognised webhook event type is not handled by this webhook.");
}
}
public function processPermanentBounce($event) {
@ -103,7 +101,10 @@ class CRM_Mailgunny_Page_Webhook extends CRM_Core_Page {
public function processCommonBounce($event, $type) {
Civi::log()->info("Mailgun Webhook processing bounce: $type");
// Ideally we would have access to 'X-CiviMail-Bounce' but I don't think we do.
$bounce_params = $this->extractVerpData($event->envelope->sender ?? '');
$bounce_params = $this->extractVerpData($event);
if (!$bounce_params) {
throw new CRM_Mailgunny_WebhookRejectedException("Cannot find VERP data necessary to process bounce.");
}
$bounce_params['bounce_type_id'] = $this->getCiviBounceTypeId($type);
$bounce_params['bounce_reason'] = ($event->{'delivery-status'}->description ?? '')
. " "
@ -112,18 +113,31 @@ class CRM_Mailgunny_Page_Webhook extends CRM_Core_Page {
$bounced = CRM_Mailing_Event_BAO_Bounce::create($bounce_params);
}
/**
* Extract data from verp email address string.
*
* Credit goes to https://github.com/mecachisenros
* Extract data from verp data if we can.
*
* @param string $data e.g. 'b.22.23.1bc42342342@example.com'
* @return array with keys: job_id, event_queue_id, hash
*/
public function extractVerpData($data) {
public function extractVerpData($event) {
if (!empty($event->{'user-variables'}->{'civimail-bounce'})) {
// Great, we found the header we added in our hook_civicrm_alterMailParams.
$data = $event->{'user-variables'}->{'civimail-bounce'};
}
elseif (!empty($event->envelope->sender)) {
// Hmmm. See if the envelope sender has anything useful in it.
$data = $event->envelope->sender;
}
// Credit goes to https://github.com/mecachisenros for the verp parsing:
$verp_separator = Civi::settings()->get('verpSeparator');
$localpart = CRM_Core_BAO_MailSettings::defaultLocalpart();
$verp_items = array_combine(['job_id', 'event_queue_id', 'hash'],
explode($verp_separator, substr(substr($data, 0, strpos($data, '@')), strlen($localpart) + 2)));
$parts = explode($verp_separator, substr(substr($data, 0, strpos($data, '@')), strlen($localpart) + 2));
$verp_items = (count($parts) === 3)
? array_combine(['job_id', 'event_queue_id', 'hash'], $parts)
: [];
return $verp_items;
}

View File

@ -134,30 +134,31 @@ function mailgunny_civicrm_entityTypes(&$entityTypes) {
_mailgunny_civix_civicrm_entityTypes($entityTypes);
}
// --- Functions below this ship commented out. Uncomment as required. ---
/**
* Implements hook_civicrm_preProcess().
* Try to embed VERP data in a way that Mailgun will provide to webhooks.
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_preProcess
*
function mailgunny_civicrm_preProcess($formName, &$form) {
} // */
/**
* Implements hook_civicrm_navigationMenu().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_navigationMenu
*
function mailgunny_civicrm_navigationMenu(&$menu) {
_mailgunny_civix_insert_navigation_menu($menu, 'Mailings', array(
'label' => E::ts('New subliminal message'),
'name' => 'mailing_subliminal_message',
'url' => 'civicrm/mailing/subliminal',
'permission' => 'access CiviMail',
'operator' => 'OR',
'separator' => 0,
));
_mailgunny_civix_navigationMenu($menu);
} // */
* Implements hook_civicrm_alterMailParams(&$params, $context)
*/
function mailgunny_civicrm_alterMailParams(&$params, $context) {
if (isset($params['X-CiviMail-Bounce'])) {
// Copy this header to one that will be returned by Mailgun's webhook.
$params['X-Mailgun-Variables'] = json_encode(['civimail-bounce' => $params['X-CiviMail-Bounce']]);
}
elseif (isset($params['Return-Path'])) {
// Copy this header to one that will be returned by Mailgun's webhook.
$params['X-Mailgun-Variables'] = json_encode(['civimail-bounce' => $params['Return-Path']]);
}
/*
$context = (string [10]) `flexmailer`
$params['X-CiviMail-Mosaico'] = (string [3]) `Yes`
$params['List-Unsubscribe'] = (string [52]) `<mailto:u.72.32.fa5f74c72c53c77f@crm.artfulrobot.uk>`
$params['Precedence'] = (string [4]) `bulk`
$params['job_id'] = (string [2]) `72`
$params['From'] = (string [37]) `"Artful Robot" <hello@artfulrobot.uk>`
$params['toEmail'] = (string [20]) `hello@artfulrobot.uk`
$params['toName'] = (string [12]) `Artful Robot`
$params['Return-Path'] = (string [43]) `b.72.32.fa5f74c72c53c77f@crm.artfulrobot.uk`
$params['X-CiviMail-Bounce'] = (string [43]) `b.72.32.fa5f74c72c53c77f@crm.artfulrobot.uk`
$params['attachments'] = (array)
*/
}