From f85a56a799128a9e4fbfafc350d4dff0f87bd19f Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Tue, 12 Sep 2023 08:33:33 +1200 Subject: [PATCH] Use bounce activity type, if exists We can look at adding in upgrade script in later version after bedding in --- CRM/Utils/Mail/EmailProcessor.php | 17 ++++++++++++++++- CRM/Utils/Mail/IncomingMail.php | 11 +++++++++++ .../CRM/Utils/Mail/EmailProcessorTest.php | 6 +++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/CRM/Utils/Mail/EmailProcessor.php b/CRM/Utils/Mail/EmailProcessor.php index 8904a440b0..c1e511df87 100644 --- a/CRM/Utils/Mail/EmailProcessor.php +++ b/CRM/Utils/Mail/EmailProcessor.php @@ -16,6 +16,8 @@ */ // we should consider moving this to the settings table +use Civi\Api4\Activity; + define('MAIL_BATCH_SIZE', 50); /** @@ -84,6 +86,16 @@ class CRM_Utils_Mail_EmailProcessor { // create an array of all of to, from, cc, bcc that are in use for this Mail Account, so we don't create contacts for emails we aren't adding to the activity. $emailFields = array_merge($targetFields, $assigneeFields, $sourceFields); $createContact = !($dao->is_contact_creation_disabled_if_no_match); + $bounceActivityTypeID = $activityTypeID = (int) $dao->activity_type_id; + $activityTypes = Activity::getFields(TRUE) + ->setLoadOptions(['id', 'name']) + ->addWhere('name', '=', 'activity_type_id') + ->execute()->first()['options']; + foreach ($activityTypes as $activityType) { + if ($activityType['name'] === 'Bounce') { + $bounceActivityTypeID = (int) $activityType['id']; + } + } // retrieve the emails try { @@ -118,9 +130,12 @@ class CRM_Utils_Mail_EmailProcessor { // if its the activities that needs to be processed .. try { + if ($incomingMail->isBounce()) { + $activityTypeID = $bounceActivityTypeID; + } $mailParams = CRM_Utils_Mail_Incoming::parseMailingObject($mail, $incomingMail->getAttachments(), $createContact, $emailFields, [$incomingMail->getFrom()]); $activityParams = [ - 'activity_type_id' => (int) $dao->activity_type_id, + 'activity_type_id' => $activityTypeID, 'campaign_id' => $dao->campaign_id ? (int) $dao->campaign_id : NULL, 'status_id' => $dao->activity_status, 'subject' => $incomingMail->getSubject(), diff --git a/CRM/Utils/Mail/IncomingMail.php b/CRM/Utils/Mail/IncomingMail.php index c11273a5fa..04eeb841b9 100644 --- a/CRM/Utils/Mail/IncomingMail.php +++ b/CRM/Utils/Mail/IncomingMail.php @@ -124,6 +124,17 @@ class CRM_Utils_Mail_IncomingMail { return (bool) $this->action; } + /** + * Is this a bounce email. + * + * At the moment we are only able to detect verp bounces but maybe in the future... + * + * @return bool + */ + public function isBounce() : bool { + return $this->getAction() === 'b'; + } + /** * @param \ezcMail $mail * @param string $emailDomain diff --git a/tests/phpunit/CRM/Utils/Mail/EmailProcessorTest.php b/tests/phpunit/CRM/Utils/Mail/EmailProcessorTest.php index e893939998..1d1d0e5b60 100644 --- a/tests/phpunit/CRM/Utils/Mail/EmailProcessorTest.php +++ b/tests/phpunit/CRM/Utils/Mail/EmailProcessorTest.php @@ -1,5 +1,7 @@ 'from', ], ]); + $this->createTestEntity('OptionValue', ['option_group_id:name' => 'activity_type', 'name' => 'Bounce', 'label' => "Bounce"]); } /** @@ -48,6 +51,7 @@ class CRM_Utils_Mail_EmailProcessorTest extends CiviUnitTestCase { public function tearDown(): void { CRM_Utils_File::cleanDir(__DIR__ . '/data/mail'); parent::tearDown(); + OptionValue::delete(FALSE)->addWhere('name', '=', 'Bounce')->execute(); $this->quickCleanup([ 'civicrm_group', 'civicrm_group_contact', @@ -116,7 +120,7 @@ class CRM_Utils_Mail_EmailProcessorTest extends CiviUnitTestCase { $this->callAPISuccess('job', 'fetch_bounces', ['is_create_activities' => TRUE]); $this->assertFileDoesNotExist(__DIR__ . '/data/mail/' . $mail); $this->checkMailingBounces(1); - $this->callAPISuccessGetSingle('Activity', ['source_contact_id' => $this->contactID, 'activity_type_id' => 'Inbound Email']); + $this->callAPISuccessGetSingle('Activity', ['source_contact_id' => $this->contactID, 'activity_type_id' => 'Bounce']); } /** -- 2.25.1