Microsoft Dynamics 365 – Send SMS using Flow

Looking at the list of traditional CRM activities I always miss the SMS, being a common and effective type of communication between organizations and customers.

Sending SMS triggered by Microsoft Dynamics 365 events (e.g. Case created) used to be a developer’s task. You had to write Plugin or Custom Workflow Activity code to access the SMS provider web service and maintain it as endpoints sometime change.

With Flow you can integrate applications in a declarative manner so an event in one application will trigger an action in another application along with custom conditional logic and even wait capabilities (similar to Dynamics 365 internal Workflow Wait step). 

In this post, I’ll walkthrough the process of setting up SMS sending without coding using Flow and Twilio (SMS provider).

  1. Prerequisites

    Before advancing make sure you have the following:

    a. Microsoft Dynamics 365 instance (trial will do)
    b. Twilio account (trial will do – click +sign up in Twilio home page)

  2. Setting up Twilio account

    a. In your Twilio Account console, click ‘Get a number’ button under the build menu

    Setting up Twilio account

    b. In the dialog, choose the suggested number or select a different one.
    c. Go to the Home tab and note the Account SID and Auth Token keys, you will need these later

    Setting up Twilio account

  3. Setting up Flow

    a. Login to your Office 365 environment and click the Flow tile

    Setting up Flow 

    b. In My Flows tab click the ‘+ Create from blank’

    image

    c. In the search box, type in Dynamics and from the results list select the ‘Dynamics 365 – When a record is created’ trigger 

    Setting up Flow

    d. In the Organization Name select the name of your Dynamics 365 instance. In the entity name dropdown select the entity for which the Flow will listen

    Setting up Flow

    e. Click the ‘New Step’ button and then ‘Add an action’

    Setting up Flow

    f. Search and Select the Twilio – Send Text Message (SMS) action

    Setting up Flow

    g. Feed in a name for your Twilio account (for future Flows) and keys from your Twilio Home tab: Account SID goes into the Account ID box, Auth token goes to the Access Token box

    Setting up Flow

    h. Feed in the your Twilio assigned Phone number in the From Phone Number box. Feed the target phone number in the To phone number. Feed in the SMS text. Note you can map dynamic data from the Case record into the text or target phone number

    Setting up Flow

    i. Click ‘Create Flow’ and then ‘Done’ 
     

  4. Testing & Monitoring
    a. In your Dynamics 365 create a new Case.
    b. After a few seconds, you should get a SMS message

    After a few seconds, you should get a SMS message

    c. In Flow management console Click ‘Manage’
    Testing & Monitoring 

    d. You can view your Flow, edit and deactivate it here. Clicking the i will show you the Flow instances details and running results 
     
    Testing & Monitoring

 

Implementation Notes

  1. It may take Flow some time to kick in. If you didn’t get an SMS message after creating the first Case, create another
  2. Twilio trial account will grant you a limited amount of SMS messages and each message will starts with ‘Sent from a Twilio Trial account’
  3. Twilio supports sending messages in these countries

@microsoft.com

I am back.

It has been a while since my last post. About a month ago I started a new job as a Dynamics TSP (Technology Solution Professional) at Microsoft. It is a technical role aimed to support Dynamics related sales processes.
Sadly, It means giving up my MVP title, as Microsoft employees are not eligible for this award. 

This is a major change for me. In the last 8 years I was self employed of a sort, without a regular schedule, office or boss. Switching to work in one of the largest corporations on the planet is overwhelming. But in a good way. Although I am still drinking from the firehose, I can now access deep and broad layers of knowledge I was missing before.

I have been writing this blog since 2009 and plan to continue. Although I am a Microsoft employee now, the opinions and views stated in this blog are my own.

So now, armed with new knowledge and super powers, this blog is getting even better. Stay tuned. 

Accessing Form Header Web Resource

Although this Help article states that with Microsoft Dynamics CRM 2016/Online “You can’t include a web resource in a form header or footer”, you certainly can.

Sadly, form Footer Web Resource no longer display any content (as it did in version 2015). Form header displays content correctly, but adding it will spread the header fields all over the form width.

adding web resource will spread the header fields all over the form width

If you are ok with the UI, you might want to access the header Web Resource programmatically via JavaScript. Maybe when a form attribute value changes, the Web Resource content should change dynamically.
Unlike header attributes, which can be accessed using
  Xrm.Page.getControl(“header_name”), the header Web Resource can not be accessed this way as it seem to be invisible to the getControl function.

So how can the header Web Resource ‘Listen’ to form and field events?

Since Web Resource can access the Xrm.Page object via the parent object, it has full access to the form elements and events. The addOnChange function allows the the Web Resource code to register an internal function as an event handler for a form or field event.

The following sample demonstrates HTML Web Resource located in the Account form header area, ‘listening’ to the Account Name attribute change event. 
The code is located in the HTML Web Resource:

//register event handler to the account name attribute onChange event

function registerRefreshEvent()
{
    if(parent.Xrm.Page != null)
    {
         parent.Xrm.Page.data.entity.attributes.get(“name”).addOnChange(refreshContent);
    }
}

//do something with the Web Resource content…

function refreshContent()
{
    alert(“Refreshing Web Resource content…”);
}

registerRefreshEvent();

HTML Web Resource located in the Account form header area, ‘listening’ to the Account Name attribute change event

Update Records with the Import Wizard

I recently noticed that in version 2016, the option to export records for update (available in version 2015 as seen below) has vanished from the Export To Excel dialog.
When checked, this option allows you to update the exported data and later on use the Import Wizard tool to update existing records.

option to export records for update available in version 2015

import existing records with the Import Wizard

Consulting Faridun Kadir, a fellow MVP, I learned that exporting MSCRM records to a static worksheet exports records GUID (record unique identifier) by default as a hidden column. This GUID is later used by the Import Wizard mechanism to determine if the imported record is to be created or updated.
For this reason, the ‘Make this data available for re-importing’ checkbox was removed from the Export to Excel dialog.

image
 
As you can see above, the hidden columns title includes a warning (‘DO Not Modify’). Indeed, changing these columns data will end with an import failure. So although exposing these columns by itself will not cause any harm, you better leave it hidden to prevent an accidental change.

All you have to do in order to update existing records is to update required value in the Excel file and import via the Import Wizard. You can also add new records which will be created in the same import job.

Entity Scope Business Rules demystified

Entity scoped Business Rules run on both client and server side. On the server side, Business Rules are executed synchronously when a record is saved (created or updated) and this means that in some cases, Business Rules can replace synchronous Plug-ins. Business Rules UX is better and maintenance wise, implementing business logic using the declarative Business Rule is preferred over Plug-in custom code.  

Sounds great, but for some Business Rule actions the meaning of running on the server side is a bit obscure:

  1. Show error message: on client side, the save operation is prevented by the error message. Is the save operation also blocked on the server side? Does the caller receive the designated error message?
  2. Set business required: does the save operation fail if a value is not supplied for the required field on server side?
  3. Lock or unlock field: does this action actually prevent setting field value on server side?

As for the other actions, I assume the Set visibility action is meaningless on server side and also that Set field/default value actions work on both client and server side in the same manner.

To test these three actions on the server side, I created and updated an Account record via the OrganizationService API in a synchronous manner while activating only the relevant Business Rule. Following are the various tests and results:

  1. Show error message

    Business Rule definition:

    Show error message action test 

    Client side test:

    Show error message action client test

    Server side test result: Account record is not created, the caller receives the designated error message

    Show error message action server test

  2. Set business required:

    Business Rule definition:

    Set business required action test

    Client side test:

    Set business required action client test

    Server side test result: Account record can not be created without specifying a value for required field

    Set business required action server test

  3. Lock or unlock field

    Business Rule definition:

    Lock or unlock field action test

    Client side test:

    Lock or unlock field action client test

    Server side test result: Account record is created successfully although the Account Number field is set to be locked by the Business Rule

    Lock or unlock field action server test

Conclusion: Show error message and Set business required actions perform on server side similar to a Plug-in. The Lock or unlock field action is meaningless on server side.

Rollup Field vs. Security Role

One of the professional benefits I gain from training Microsoft Dynamics CRM courses appears from time to time in the form of an innocent question from a student. A question which makes me stop for a moment and think… What would Mr. Spock answer to this?

Here is one: Does a Rollup field calculation take the user’s privileges into account?

Let me demonstrate: a user has access to a Project record which contains the Total hours consumed. This is a Rollup field which sums up the related Activity Report records Total Hours field value. The user Security Roles prevent him for reading any Activity Report records.
Having this, when the user activates the Total hours consumed field on demand calculation functionality,  would the result be zero?

Humm… on one hand, It seems logical to expect that if the user has no access to the data used for calculation, he will get partial or no calculation result. On the other hand, displaying partial or no result can lead the user to the wrong business decision.

What would Mr. Spock answer to this?
After testing this scenario I can answer that Rollup field calculation ignores the user’s privileges. Even without access, the Activity Reports entity, a user can activate a Rollup field on demand calculation and get a result as if he had full privileges.

The reason for this is that Rollup fields calculation is performed under the privileges of the System user account rather than the actual operating user. If you want to prevent read access to calculation result, use Field Level Security as Microsoft suggests in this article.

Rollup field Supporting sample

Field Level Security – Update, Don’t Read

I always assumed Field Level Security privileges are somehow inclusive, meaning you can’t have Update privilege without Read. I was wrong.

Defining the Field Security privileges like this

image

will prevent the profile users from reading the secured field value but will allow them to create with and update it.

FLSDemo

I can’t think of a business process which requires such behavior, but since Field Level Security apply to APIs as well as UI, it may be useful when external applications are required to update a secured value but are not allowed to retrieve it.