const MJ_LOAD_INDEX = 1; // index of the avg [1m,5m,15m] const MJ_MAX_LOAD = 2; const MJ_LOAD_CHECK_FREQ = 100; const MJ_COOLING_PERIOD = 20; $msg_since_check = 0; $arguments = getopt('q:'); $queue_name = $arguments['q']; function connect() { return new AMQPStreamConnection(CIVICRM_AMQP_HOST, CIVICRM_AMQP_PORT, CIVICRM_AMQP_USER, CIVICRM_AMQP_PASSWORD, CIVICRM_AMQP_VHOST); } $callback = function ($msg) { global $msg_since_check; try { $msg_handler = new CRM_Mailjet_Page_EndPoint(); $msg_handler->processMessage($msg->body); $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']); } catch (Exception $ex) { $msg->delivery_info['channel']->basic_nack($msg->delivery_info['delivery_tag']); CRM_Core_Error::debug_var("MAILJET AMQP", $ex, true, true); } finally { $msg_since_check++; } }; $connection = connect(); $channel = $connection->channel(); debug('Waiting for messages. To exit press CTRL+C...'); while (true) { while (count($channel->callbacks)) { if ($msg_since_check >= MJ_LOAD_CHECK_FREQ) {
function processMessage($msg) { //Decode Trigger Informations $trigger = json_decode($msg, true); //No Informations sent with the Event if (!is_array($trigger) || !isset($trigger['event'])) { CRM_Core_Error::debug_var("ENDPOINT EVENT", "Invalid JSON or no event", true, true); return 'HTTP/1.1 422 Not ok'; } $event = trim($trigger['event']); $email = trim($trigger['email']); $time = date('YmdHis', $trigger['time']); $mailingId = CRM_Utils_Array::value('customcampaign', $trigger); //CiviCRM mailling ID //PERFORANCE IMPACT, xav CRM_Core_Error::debug_var("MAILJET TRIGGER", $trigger, true, true); if (substr($mailingId, 0, 5) === "TRANS" || substr($mailingId, 0, 15) === "=?utf-8?Q?TRANS") { //PERFORANCE IMPACT, xav CRM_Core_Error::debug_var("TRANS EMAIL", array($mailingId, $event, $email), true, true); $allowedEvents = array('bounce', 'blocked', 'spam', 'unsub'); if (!in_array($event, $allowedEvents)) { return 'HTTP/1.1 200 Ok'; } $emailResult = civicrm_api3('Email', 'get', array('email' => $email, 'sequential' => 1)); if (isset($emailResult['values']) && !empty($emailResult['values'])) { //we always get the first result $emailId = $emailResult['values'][0]['id']; $contactId = $emailResult['values'][0]['contact_id']; if ($event == 'bounce' && $trigger['hard_bounce']) { $params = array('sequential' => 1, 'id' => $emailId, 'email' => $email, 'on_hold' => 2, 'hold_date' => date('YmdHis')); civicrm_api3('Email', 'create', $params); } $params = array('sequential' => 1, 'activity_type_id' => 58, 'activity_date_time' => $time, 'status_id' => 'Completed', 'subject' => $event, 'details' => 'Added by mailjet extension, error: ' . CRM_Utils_Array::value('error_related_to', $trigger) . ', ' . CRM_Utils_Array::value('error', $trigger) . '. blocked=' . (int) CRM_Utils_Array::value('blocked', $trigger) . '. hard_bounce=' . (int) CRM_Utils_Array::value('hard_bounce', $trigger), 'source_contact_id' => $contactId); civicrm_api3('Activity', 'create', $params); } if ($event == 'unsub') { $params = array('sequential' => 1, 'id' => $emailId, 'email' => $email, 'on_hold' => 2, 'hold_date' => date('YmdHis')); civicrm_api3('Email', 'create', $params); $params = array('sequential' => 1, 'id' => $contactId, 'is_opt_out' => 1); civicrm_api3('Contact', 'create', $params); } return 'HTTP/1.1 200 Ok'; } if ($mailingId && $mailingId[0] != '0') { //we only process if mailing_id exist - marketing email /* https://www.mailjet.com/docs/event_tracking for more informations. */ switch ($event) { //For unsupported events, we just store them raw case 'open': case 'click': case 'unsub': case 'typofix': CRM_Mailjet_BAO_Event::createFromPostData($trigger); return 'HTTP/1.1 200 Ok'; //We replace the civi delivery time with the mailjet one //but keep the civi one for comparison //We replace the civi delivery time with the mailjet one //but keep the civi one for comparison case 'sent': $emailResult = civicrm_api3('Email', 'get', array('email' => $email, 'sequential' => 1)); if (isset($emailResult['values']) && !empty($emailResult['values'])) { CRM_Mailjet_Page_EndPoint::updateDelivery($trigger, $emailResult); return 'HTTP/1.1 200 Ok'; } else { //This shouldn't happen, let's log the event CRM_Mailjet_BAO_Event::createFromPostData($trigger); CRM_Core_Error::debug_var("MAILJET TRIGGER", "Unknown address {$email}", true, true); return 'HTTP/1.1 422 unknown email address'; } //we treat bounce, span and blocked as bounce mailing in CiviCRM //we treat bounce, span and blocked as bounce mailing in CiviCRM case 'bounce': case 'spam': case 'blocked': $emailResult = civicrm_api3('Email', 'get', array('email' => $email, 'sequential' => 1)); if (isset($emailResult['values']) && !empty($emailResult['values'])) { $params = CRM_Mailjet_Page_EndPoint::prepareBounceParams($trigger, $emailResult); CRM_Mailjet_BAO_Event::recordBounce($params); return 'HTTP/1.1 200 Ok'; } else { //This shouldn't happen, let's log the event CRM_Mailjet_BAO_Event::createFromPostData($trigger); CRM_Core_Error::debug_var("MAILJET TRIGGER", "Unknown address {$email}", true, true); return 'HTTP/1.1 422 unknown email address'; } # No handler # No handler default: CRM_Core_Error::debug_var("MAILJET TRIGGER", "No handler for {$event}", true, true); return 'HTTP/1.1 422 unknown event'; } } else { //assumed if there is not mailing_id, this should be a transaction email //TODO::process a transaction email } return 'HTTP/1.1 200 Ok'; }