-
-
Notifications
You must be signed in to change notification settings - Fork 825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow for configuration of activity contacts, type and campaign for email-to-activity #26905
Allow for configuration of activity contacts, type and campaign for email-to-activity #26905
Conversation
Thank you for contributing to CiviCRM! ❤️ We will need to test and review the PR. 👷 Introduction for new contributors
Quick links for reviewers |
@@ -109,11 +127,15 @@ public function getDefaultEntity() { | |||
public function setDefaultValues() { | |||
$defaults = parent::setDefaultValues(); | |||
|
|||
// Set activity status to "Completed" by default. | |||
if ($this->_action != CRM_Core_Action::DELETE && | |||
(!$this->_id || !CRM_Core_DAO::getFieldValue('CRM_Core_BAO_MailSettings', $this->_id, 'activity_status')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only condition in which !CRM_Core_DAO::getFieldValue('CRM_Core_BAO_MailSettings', $this->_id, 'activity_status')
would apply is if you were switching an existing bounce processing mail account to an email-to-activity account, which would happen rarely-to-never, so I don't we need to handle this separately, since the consequence is low (the activity status would be scheduled by default instead of completed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Another consequence besides what you mentioned about status is you end up with the default of only one of the from and recipients being recorded, and in general while not a technical problem, seems undesirable to allow. I.e. none of the people it was sent to get recorded.
- Also note that this situation then ends up being the default choices when creating an account for Oauth. So it's not as rare as thought.
- And personally changing from bounce to activity is something I do somewhat often since not all sites have bounce processing, but activity processing is used a lot in cases.
Otherwise though the PR overall looks pretty good. I haven't looked at the admin ui part. Seems there's a separate discussion there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you mean, but not sure how to handle that. Could change the upgrade and the generated data to also set those defaults for bounce processing, which is fine because they don't do anything for bounce processing.
But that doesn't cover oauth. For that I think we'd need to add defaults in the oauth process or add defaults directly to the DB.
We could check if the activity status is not set and add defaults in that case, but that feels a bit odd and prone to create problems.
Thoughts?
I think the Admin UI part can go ahead as is. Hardly the only issue of that type in Admin UI.
CRM/Admin/Form/MailSettings.php
Outdated
(!$this->_id || !CRM_Core_DAO::getFieldValue('CRM_Core_BAO_MailSettings', $this->_id, 'activity_status')) | ||
) { | ||
if (!$this->_id) { | ||
$defaults['is_ssl'] = TRUE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added sensible defaults for new mail accounts here to check Use SSL and select email-to-activity instead of bounce processing (of which there can only be one anyways).
|
||
// we definitely need a contact id for the from address | ||
// if we dont have one, skip this email | ||
if ($requireContact && empty($params['from']['id'])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check doesn't make sense in the new context as we don't know what the mapping from email fields to activity contacts is here. But it doesn't matter as this is handled in EmailProcessor at 210 anyways, since the condition can also come up in other ways (for instance, if $requireContact is not true, we still can't create an activity without a source contact).
@@ -2,6 +2,7 @@ | |||
|
|||
use CRM_CivicrmAdminUi_ExtensionUtil as E; | |||
|
|||
// This SearchDisplay shows an editable-in-place field for Enabled? for all rows, including the bounce processing mail account, which cannot actually be disabled (you can change it to No, but it won't actually be disabled). So this is FIXME for when we can set rows to edit-in-place conditionally. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@colemanw Any thoughts on how to handle this? I think it has come up in another context as well, but can't find that at the moment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, those edit-in-place links will check edit permissions before they render. So if the system had a rule like "you're not allowed to edit this" then it wouldn't be editable.
But lately we've been using the Enable/Disable action links instead of in-place-edit (or in-addition to, but I don't think both are strictly necessary). Those will have the same problem, so I guess we need to tweak the checkAccess
callback for that entity to make sure it returns false
for the ones that shouldn't be edited.
@@ -242,6 +248,7 @@ public function setUpDoNotCreateContact() { | |||
'domain' => 'example.com', | |||
'is_default' => '0', | |||
'is_contact_creation_disabled_if_no_match' => TRUE, | |||
'is_non_case_email_skipped' => FALSE, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test wasn't actually testing anything before as it was skipping the non-case email.
e831686
to
569995c
Compare
569995c
to
c73c682
Compare
I plan to look at this. |
Thanks @demeritcowboy. It just occurred to me a couple minutes ago that there is a bug in here. I'll fix that today and resolve the merge conflict. |
c73c682
to
528e042
Compare
Jenkins test this please |
528e042
to
4a1b45a
Compare
b26b769
to
a446d6e
Compare
merge conflict from something yesterday, but not necessary for review |
a446d6e
to
d39befe
Compare
@demeritcowboy I've moved the upgrade steps to FiveSixtySix as required. |
Thanks. Yep this is still on my todo list. |
Thanks, appreciate that this one is a project to review. |
c98813a
to
0b0c20d
Compare
CRM/Utils/Mail/EmailProcessor.php
Outdated
throw new CRM_Core_Exception(ts('Could not find a valid Activity Type ID for Inbound Email')); | ||
if ($usedfor == 0) { | ||
// 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_unique(array_merge(explode(",", $dao->activity_targets), explode(",", $dao->activity_assignees), explode(",", $dao->activity_source))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I tell it I don't want any assignees, then $dao->activity_assignees is the empty string, which exploded gives array(0 => ''), which then later tries to look for $mail->''
which gives a fatal error.
But also array_merge doesn't seem right here, because it's merging based on (semi-random) numeric keys, which doesn't actually "merge" because (a) it's not the values, and (b) php is either weird or awesome depending on your point of view and it won't merge numeric keys. But ok that doesn't matter because of the unique(). (But the first point is still true.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, intentionally doing the weird PHP thing here. Open to better ways though.
Maybe it would be best to use a SEPARATOR_BOOKEND or some other serialization for these fields?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose you'd still have to explode since you'll always have a string to start with. Could add an array_filter()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't look pretty, but it works with empty values now. Thanks for catching that.
0b0c20d
to
aacdb40
Compare
CRM/Admin/Form/MailSettings.php
Outdated
if (!$this->_id) { | ||
$defaults['is_ssl'] = TRUE; | ||
$defaults['is_default'] = 0; | ||
$defaults['activity_type_id'] = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Inbound Email'); | ||
$defaults['activity_status'] = 'Completed'; | ||
$defaults['activity_source'] = 'from'; | ||
$defaults['activity_targets'] = 'to,cc,bcc'; | ||
$defaults['activity_assignees'] = 'from'; | ||
$defaults['is_active'] = TRUE; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at how the parent form works, how about (plus the upgrade change for bounce acct)
if (!$this->_id) { | |
$defaults['is_ssl'] = TRUE; | |
$defaults['is_default'] = 0; | |
$defaults['activity_type_id'] = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Inbound Email'); | |
$defaults['activity_status'] = 'Completed'; | |
$defaults['activity_source'] = 'from'; | |
$defaults['activity_targets'] = 'to,cc,bcc'; | |
$defaults['activity_assignees'] = 'from'; | |
$defaults['is_active'] = TRUE; | |
} | |
$defaults['is_ssl'] = $defaults['is_ssl'] ?? TRUE; | |
$defaults['is_default'] = $defaults['is_default'] ?? 0; | |
$defaults['activity_type_id'] = $defaults['activity_type_id'] ?? CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Inbound Email'); | |
$defaults['activity_status'] = $defaults['activity_status'] ?? 'Completed'; | |
$defaults['activity_source'] = $defaults['activity_source'] ?? 'from'; | |
$defaults['activity_targets'] = $defaults['activity_targets'] ?? 'to,cc,bcc'; | |
$defaults['activity_assignees'] = $defaults['activity_assignees'] ?? 'from'; | |
$defaults['is_active'] = $defaults['is_active'] ?? TRUE; |
Seems to work for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is perfect, have done this and updated the upgrade so that it sets the default values for bounce processing as well.
Oops this has upgrade merge conflicts again. |
aacdb40
to
6b9eb83
Compare
418b04c
to
df97bb6
Compare
Thanks @demeritcowboy, merge conflict resolved. |
Test fail is testGetOptionsBasic, unrelated. |
yeah it's failing on every PR. |
Yay! |
Thanks! |
Overview
Email-to-activity processing is a powerful tool, but somewhat hampered by hardwired choices about which email addresses correspond to source, target and assignee contacts, which type of activity should be created, etc. This PR makes it possible to configure the activity source, target and assignee using the from, to, cc and bcc fields of the email according to the user's needs. It also makes it possible to configure the activity type, add a campaign, and to disable and enable a Mail Account.
Now, users can set up email to activity processing to process emails which were sent to the organization (the classic Inbound Email), emails that were sent by the organization to contacts (normally an Email activity), and emails that were sent by contacts to other contacts, copying the organization (probably a custom activity type). Users can use all three of these at the same time by setting up multiple mail accounts.
The popularity of the Inbound Email Activity extension shows there is demand for different configurations for email-to-activity, but this PR gives the user more control and allows for different configurations for different email accounts or different email folders.
Before
After
If the source is set to a field that can contain more than one email address, only the first email will be used as an activity can only have one source contact. Available activity types are Inbound Email, Email and all non-reserved types.
Comments
This works with the Inbound Email Activity extension (ping @JoeMurray), with no change for existing installs. Once this is merged, I can update the docs there to make it clearer how the extension works in the context of these settings.