Reputation: 1021
Problem: We use the CRM for Outlook plugin to automatically log our support emails, but internal emails between employees (some of which contain sensitive information) are also being logged.
Ideal Solution: I am attempting to write a pre-event (the "create email" message) plugin to block the automatic logging of internal emails, but (apparently) the only way to stop a message from being executed is to throw an exception in the pre-event phase, but this always results in an error message being shown in outlook (which we obviously can't have). According to the documentation, only the "InvalidPluginExecutionExeception" is supposed to show messages to the user, but this is not the case as all exceptions result in an error message in the user's Outlook application.
Potential Solution: There is also a "CheckPromoteEmail" message that (according to the documentation) determines whether or not an email should be promoted to the CRM (I assume "promoted to CRM" means "make an email entity to store in CRM"), but I couldn't find anything in the context that would let me tell CRM to not promote the email. Is there some flag buried in the context that I can set, or some way to invlaidate the email so the CRM's own logic decides to not store it?
Workaround Solution: The only other solution that I am aware of (mentioned here) to just clear the subject and contents of the email after it has been created, but I would rather stop the email from being created in the first place than editing or deleting it after time and resources have been wasted creating the email.
Is there a clean way to stop an operation from a plugin? Or from anywhere? If there isn't, does anyone know why Microsoft didn't provide this feature? They already have ironclad rollback functionality under the hood in case an operation fails, why don't they just give me a way to call the rollback?
Here's my code in case it's helpful in answering my question:
public class InternalEmailFilter : IPlugin
{
void IPlugin.Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext _context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
Entity e = (Entity)_context.InputParameters["Target"];
bool shouldStore = ShouldStoreInCRM(e);
if (shouldStore == false)
{
throw new Exception(); //attempting to stop the operation without an InvalidPluginExecutionException, but still results in error message to user
}
}
protected bool ShouldStoreInCRM(Entity e)
{
List<Entity> parties = new List<Entity>();
var atttributes = e.Attributes;
if (atttributes.ContainsKey("to") == true) parties.AddRange((atttributes["to"] as EntityCollection).Entities);
if (atttributes.ContainsKey("from") == true) parties.AddRange((atttributes["from"] as EntityCollection).Entities);
if (atttributes.ContainsKey("cc") == true) parties.AddRange((atttributes["cc"] as EntityCollection).Entities);
if (atttributes.ContainsKey("bcc") == true) parties.AddRange((atttributes["bcc"] as EntityCollection).Entities);
foreach (Entity p in parties)
{
if (p.LogicalName == "activityparty" && p.Attributes.ContainsKey("addressused") == true && p.Attributes["addressused"] != null)
{
if (p.Attributes["addressused"].ToString().ToLower().Contains("@ourdomain.com") == false)
{
return true; //someone connected in the email is not an employee, store the email
}
}
}
return false; //everyone was an employee, do not store
}
}
Upvotes: 5
Views: 4513
Reputation: 408
You have an option in the personal settings where you can choose to track all emails, email responses to CRM emails (emails already tracked), emails from records (accounts etc) and emails from records that have email enabled.
Upvotes: 0
Reputation: 1021
After much blood, sweat, and tears I finally figured out how to do this:
You have to use an async post-event plugin on the "Create email" message to delete the email from the DB with the CRMService after it has been created. It has to be asynchronous because you need to wait for the CRM finish creating and 'let go' of the entity before you can delete it. Otherwise, the process hangs.
Any of these solutions would have been better, but for reference, you cannot:
Maddening.
Upvotes: 8
Reputation: 4111
Sorry, the workaround is your only option. The only way to stop an operation via a plugin is to throw an exception. Why did Microsoft do this? I assume they didn't want plugins silently failing.
As for the workaround, you should clear the subject and body before they go into the database by clearing them in your pre-event plugin, then clean up the record itself in a post-event asynchronous plugin. This way that sensitive info doesn't make it into any auditing logs either.
Finally, look at DeliverPromoteEmail
instead of CreateEmail
. DeliverPromoteEmail
is what is used by Outlook to create the tracked emails. This way you could still create Emails in the CRM UI that don't fire this plugin (if needed).
edit CheckPromoteEmail
only looks at the tracking token in the subject (and/or the MessageID in the email header) to decide whether an email should be tracked, so it won't be useful either.
Upvotes: 2