COPY: Dynamic Values for Custom Entities in Email Templates

I ran across this article a few weeks ago and want to make a copy of it here just in case it gets removed from it’s source.

Original Article


Configure a Queue for Simple E-mail handling

Much has been written about how Dynamics 365 can handle complex email processing, convert emails to cases, automatic rules for converting them, etc.  One thing I noticed was missing was how to configure a Queue and a Mailbox for simple email processing.

Use Case:

You are a small to medium sized business and you have a customer support email box where your customers can email you an issue for a response.

Note:  These instructions are designed for a Dynamics 365 online environment only.  It is assumed that the CRM instance is online, and your Exchange is also online.  If you are on-premise, this tutorial may not apply to you.  [ and I can’t test it since I don’t have direct access to one, sorry… 🙂 ]

Requirements

  1. You must already be a Dynamics 365 system admin
  2. You must either be an Office 365 global admin, or know one that can assist you.
  3. You should have access to the shared mailbox, or know someone who does that can verify that it’s working.

Steps

Navigate in Dynamics to Settings, Business Management, Queues

Select New to create a new queue.

  • Name :: This should reflect something about the queue/mailbox being setup. In our scenario, we are going to call this queue Customer Support.
  • Type :: This should be set to Public.
  • Incoming Email :: This should be the email address for the mailbox that is being monitored.  In this scenario it’s a support@xxxxx.onmicrosoft.com mailbox.
  • Owner :: Typically a Dynamics Admin, but could also be another Dynamics user (e.g. Support manager?)
  • Description :: (Optional)
  • Convert Incoming Email to Activities :: This is typically set to All email messages.

Once the queue is created, it will also create a related Mailbox.  In these next steps we will configure that mailbox.  Click on the Mailbox name underneath the Convert Incoming Email to activities field to access the mailbox.

Note: For this first step, you will need to either be an Office 365 Global Administrator, or be able to get one to help you.  If it’s not you, you will need to get them to login to Dynamics and follow this step.

Access the mailbox record and press the Approve Email button.

Ensure that the Incoming Email field is set to Server-Side Synchronization or Email Router.

(Optional) If you are also going to reply to email using the same email address, also set the Outgoing Email to Server-Side Synchronization or Email Router.  This will allow your Dynamics users to reply anonymously and have replies go back to the original mailbox.

Save the Record.

Next you will have to test and enable the mailbox.  Click the Test and Enable Mailbox button in the ribbon bar.

Note: Depending on your Office 365 tenant, the test may take up to 15 minutes.   You can refresh the browser page showing the mailbox and check the status of the test.

Once the mailbox is tested successfully, you are ready to start accepting E-mails.  Anything sent to the mailbox will now show up in the new Queue that was created.

To Test!

  • Navigate to Service, Queues
  • Select the All Items View
  • Select the new queue that was just created

Recap

So we did a number of things here, but the basics are that we now have a simple way to have all emails sent to a common mailbox become activities in Dynamics 365.  We can convert them to cases, attach them to existing records by setting the Regarding on the emails, etc.

Enjoy!

Updating Records in a Plugin without blowing up your Audit Log

If you’ve ever worked on a Dynamics 365 (CRM) plugin where you were updating data on an existing record, you may have run across a strange phenomenon.  The Plugin engine will send you a copy of the postImageEntity, which is an object of type Entity and is a copy of the current record you are working with.

Example:

IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
 
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
 
Entity postImageEntity = (context.PostEntityImages != null && context.PostEntityImages.Contains("Target")) ? context.PostEntityImages["Target"] : null;

 

From this new variable, you can set the value of one of the fields and write the record back to Dynamics.  Let’s say we want to update the Account Number field on the Account Entity to the first 3 characters of the Account Name.

postImageEntity["accountnumber"] = postImageEntity["name"].ToString().Substring(0, 3);
 
service.Update(postImageEntity);

So all looks correct, right?  Well, sort of.

While technically this code works, there is a catch.  If you run this code and have auditing turned on for your Account entity you will see something odd.  You will see that the ENTIRE record is loaded into the Audit record with all the before and after field values being exactly the same with the exception of the Account Number.

If you have unlimited storage space available and keep your audit records forever, then you don’t have a problem.  If you are like the other 99% of us that need to be frugal with storage space, especially with Dynamics online, then you need a better solution.  Besides, who can read an audit where every single field is written back and you try to find the 1 field that was actually updated.

If you look at the code, it actually makes sense why it did it that way… postImageEntity contains every field on the record.  All we did was to update one field and write the whole thing back.  It doesn’t care that you only updated one field…like a good C# function it’s doing what you told it to do.

So here’s a solution.  You need to declare another variable of type Entity, update that one with the new value, and write that back to the system.

I have a helper function that does this that I use in all my plugin projects.

public static Entity getEntityForUpdate(IOrganizationService service, string EntityName, Guid EntityRecordId)
{
/*
====================================================================
Chris H:
Here we are declaring a separate entity object to use strictly 
for updating values on the Record
If we just update the postImageEntity, it updates 
EVERY field on the record, not just the ones that are 
being updated which makes the audit logging look bizarre.
=====================================================================
*/
Entity _Entity = new Entity(EntityName);
ColumnSet _EntityAttributes = new ColumnSet(new string[] { EntityName + "id" });
_Entity = service.Retrieve(_Entity.LogicalName, EntityRecordId, _EntityAttributes);
return _Entity;
}

Now what you do at the beginning of you plugin code is declare this Entity variable, update it, and write it back.

Entity record2Update = getEntityForUpdate(service, postImageEntity.LogicalName, postImageEntity.Id);
 
record2Update["accountnumber"] = postImageEntity["name"].ToString().Substring(0, 3);
 
service.Update(record2Update);

Hopefully this makes sense, if not just send me a comment I can clarify.

Disclaimer:  I am NOT a classically trained developer.  I have basically learned how to write .NET code by copying the work of others and modifying it for my own needs.  I’ve learned a few tips over the years and hope that you find them useful.  Enjoy!