The Mission We Chose To Accept
The problem to solve was bringing scanned documents into CRM, preferably via email. The out of the box option is to email the attachment to yourself and track it in or save the attachment and add a Note. As the client already had a coded solution bringing in attachments via Queues in CRM 4, the out of the box options were considered a step backwards.
Workflow could not quite get us there without a custom workflow step so I looked to Flow. In Part Two I tried the direct approach of simply reading the email and creating a Note in CRM. Unfortunately, Flow errors when you try and move the attachment across to CRM so I had to try something else.
The SharePoint Option
My salvation came with the client turning on SharePoint integration for Dynamics 365 (CRM). For those that are unfamiliar with this feature, you go into Dynamics 365’s settings, tell it where the SharePoint server is and which CRM entities you want it on for and SharePoint auto-provisions a document store for each record of that entity available in the Documents child link of the record (accessible from the chevron at the top).
Starting the Flow
Flows allow us to use variables and, for this particular Flow that makes life a lot easier. To this end we start out Flow with the trigger for the Flow and initialising our variables.
Our trigger is the same as in the Part Two Flow; we monitor everything coming into our Inbox. Each variable initiation requires a name, type and, optionally, a default value. The default value can be an expression, rather than a string if you want to get tricky.
For the purposes of this Flow we initialise three variables for the Contact’s GUID, First Name, and Last Name (all for constructing the folder path for SharePoint). In this case, I was not tricky and just set some sensible text for the default value.
The next step is to find the Contact we are going to add the attachments to.
The only complicated bit here is the Filter Query value. The format for an ODATA filter can be found online without too much difficulty and for my purposes can be seen above where I equate the system name of the CRM field on the Contact entity to the Subject of the incoming email.
Loops and Arrays
I hit a small problem at this point. While the contactid was unique to each record, and only one record would be returned, the List Record step returned an array (effectively a list of records). Array manipulation is not obvious in Flow but colleague and Microsoft Azure encyclopedia Doug Daley tells me you can isolate array components with the Compose function. At the time of writing I did not know this trick so I employed a loop to loop through each element in the array (of which there was one, the found Contact, or zero if none were found).
I have also found Flow is a bit twitchy when it comes to creating loops. If you try to create one and then add an array variable to work on, the Flow does not always realise you are in a loop and complains about the array. The best best is to NOT create the loop but add the step as if it was in a loop. Flow then asks if you want to put it inside a loop and you are good.
So what we are doing here is, once we have identified the Contact in question, we set values for our three variables. Flow makes this very easy as it automatically retrieves all the fields for the Contact entity.
Our final step is to loop through our attachments and, using these variables, place them in the right folder so that they can be seen in CRM.
Starting another loop (by adding a Create File step and getting Flow to build the loop around it), we get each attachment from our email and add it to the right folder. The SharePoint Create File step requires:
- Site Address: The SharePoint Site Address. I have had some real trouble getting the value to stick in this field with Flow blanking it out whenever I clicked away. The only advice I can offer is to persist.
- Folder Path: For us this is the formula used by Dynamics 365 (CRM). For Contacts, we use the following Expression. “concat(‘/contact/’,variables(‘FIRSTNAME’),’ ‘,variables(‘LASTNAME’),’_’,replace(variables(‘GUID’),’-‘,”))”. Basically, it uses a subfolder called ‘contact’ and after this each Contact record gets a folder with the name ‘<full name>_<contact GUID>’. If you are doing this for a production environment, consider that the full name is not always ‘<first name> <last name>’ so you may want to pull the <full name> field or construct your Expression differently.
- File Name: The name of the attachment
- File Content: The encoded content of the attachment. This is the part that Flow struggled to pass onto a CRM Note record. Fortunately it works fine for SharePoint.
The End Result
The Flow worked exactly as we would hope and a new file was created against the appropriate SharePoint folder so that the attachment could be seen in CRM.
We replaced non-trivial and, likely, expensive coding with a completely configured Flow. Moreover, I went from knowing essentially nothing about Flow to creating the above in a few hours.
In the end the client actually took the Flow further and, as the attachments were application forms, requested that for each attachment a Case was created and that the attachment was placed on the document store for that Case. It took a little over an hour to get it fully functional from scratch. I will leave it as an exercise for the reader on how to do it.
Looking at the soon-to-be-released update to CRM, erroneously known as the “July Update”, it is possible to start the process for creating Flows directly within CRM.
Therefore I think Flows will become more and more important as time goes on for those of us who work with Dynamics 365.