Microsoft Dynamics 365 for Sales CRM: How to Write Plug-ins in Azure Functions

Microsoft Dynamics 365: How to Write Dynamics 365 CRM Plug-ins Using Azure Functions

While a lot has changed over the years with Microsoft Dynamics 365 for Sales (formerly Dynamics 365 CRM), there’s one thing that’s been a consistent feature of the software. We’re talking, of course, about plug-ins.

 

What is a plug-in? Simply put, a Dynamics plug-in is a custom business logic that’s triggered by an event in Dynamics 365 CRM. For example, creating a new account triggers a customer plug-in which then executes further processes within Dynamics 365.

 

Thanks to the introduction of configurable webhooks in Dynamics 365 CRM 9.0, it’s now possible to create a webhook -- similar to the process of configuring a plug-in -- which is subsequently executed within an Azure Function. This can be helpful when you encounter plug-in limitations, or if you want to use a plug-in for further integration.

 

In this blog, we’ll show you exactly how to write a Dynamics 365 CRM plugin in Azure Functions. If you’re not familiar with Dynamics plug-ins, you can read more about Dynamics 365 CRM plug-ins here. If you want to learn more about webhooks, click here.

 

The Advantages of Webhooks Over Dynamics Plug-ins

 

Of course, you might be wondering why you’d want to use a webhook over a plug-in in the first place. There are essentially two reasons:

 

1. Integrations: If you want to separate integration logic from the Dynamics 365 CRM code base, you’ll need to use a webhook in order to implement this logic outside of CRM. You can also run into various complexities when attempting to work with existing .NET assemblies to facilitate integration with an outside system. This can result in complicated plug-in code.

 

2. Sandbox plug-in limitations: If you’re familiar with Dynamics 365 CRM, you know that there are various limitations when it comes to running plug-ins in the sandbox:

●      Issues with shared assemblies

●      Timeouts

●      HTTP/HTTPS protocol limitations

●      Execution with partial trust

●      Inability to access the network via UP

●      Resource load (plug-ins eat up the CRM resource pool)

 

Webhooks allow you to avoid these various pitfalls. So, how do you set them up?

 

How to Set Up Webhooks in Dynamics 365 CRM

 

First off, you’ll need to create a service that uses the incoming webhook request from Dynamics 365 CRM. Then, you’ll need a second webhook step within Dynamics 365. This is configurable using the Plug-in Registration Tool.

 

Create and Deploy a Dynamics Webhook Via an Azure Function

 

Let’s look at an example. Here, we’re working with Visual Studio 2017 with the Azure Development workload installed. This allows us to code Azure FUnctions directly into Visual Studio.

 

First, create a new function in Azure with the type “Generic Webhook.”

 

 

Next, swap the template code inside “Run” with something like this:

 

log.Info($"Webhook was triggered!");

 

// get the context from D365

string jsonContent = await req.Content.ReadAsStringAsync();

 

// log what we got from D365 as an example

log.Info(jsonContent);

 

// return a success message to D365

return req.CreateResponse(HttpStatusCode.OK);

 

Now, deploy the function to your Azure Function app. Take note of the function’s URL and key. Browse to the Function App within Azure Portal, choose your function, and use the “Get Function URL” feature next to the Run button. Use the key in order to get the URL.

 

 

Configure Dynamics 365 CRM to Call Your Webhook in Azure Functions

 

Next up, you’ll want to open the Plug-in Registration Tool and connect to your organization. Click here to download the tool.

 

 

Register a new webhook, and then tie that webhook to an event in Dynamics 365 CRM. Select your newly registered webhook, right-click it, and then choose “Register New Step.”

 

 

Note that the webhook here is set to execute whenever a change to an account record is detected within Dynamics 365 CRM.

 

 

Next, you’ll need to click “Register New Step.” Then, be sure to confirm that your webhook and steps have been successfully registered.

 

 

The best way to verify that Dynamics 365 CRM is properly triggering the associated Azure function is to do the following:

1)    First, modify an existing account record within Dynamics 365 CRM.

2)    Then, check the Azure Function’s log within Azure Portal. Here, you should be able to see a log message which contains the JSON that was sent to Azure from Dynamics 365. If you can’t see this log message, then Dynamics CRM isn’t properly triggering the associated Azure function.

 

 

How to Use the Information Obtained from Dynamics 365 CRM

At this point, you have a significant amount of JSON information coming from Dynamics 365. The question arises, then: how should you make use of this data?

 

In fact, you have the ability to turn that JSON data into a RemoteExecutionContext object straight from the CRM software development kit. You can then work with the RemoteExecutionContext much the same way that you would with plug-in code:

 

RemoteExecutionContext cdsContext =  ContextHelper.GetContext(jsonContent);

 

Here, you’ll want to use the DataContractJsonSerializer to turn the JSON into a RemoteExecutionContext.

 

 

/// <summary>

/// Returns an execution context object familiar to CRM developers

/// </summary>

/// <param name="contextJSON">JSON String</param>

/// <returns>Xrm sdk RemoteExecutionContext</returns>

public static RemoteExecutionContext GetContext(string contextJSON)

{

RemoteExecutionContext rv = null;

 

using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(contextJSON)))

{

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(RemoteExecutionContext));

rv = (RemoteExecutionContext)ser.ReadObject(ms);

}

 

return rv;

}

 

If you’re a plug-in developer, this context object will look quite familiar to you. This object can be used inside your new Azure function.

 

 

log.Info("Received: " + cdsContext.MessageName);

Entity updatedAccount = (Entity)cdsContext.InputParameters["Target"];

log.Info(updatedAccount.LogicalName + ": " + updatedAccount.Id);

return req.CreateResponse(HttpStatusCode.OK);

 

Now, it’s time to deploy your new code, update another Dynamics 365 CRM account, and check your logs again. At this point, the log should show both an updated account ID as well as a confirmation that the webhook itself was triggered.

 

 

Done! You now have the ability to take the context of a Dynamics 365 CRM event and pass it directly to an external webhook service without using any code within Dynamics 365 itself. This is huge. And, as we’ve seen, all you had to do within Dynamics 365 was register the webhook and link it to an event in the 365 event pipeline using the Plug-in Registration Tool.

 

In addition, it’s possible to interact with the context you’ve created the same way that you would if you were using a native Dynamics 365 plug-in -- that is, by deserializing the context to a RemoteExecutionObject.

 

Sample Azure Function Code

 

To wrap up, here’s the code for a sample function from Azure. It’s important to note that this code comes from a Visual Studio Function App project. This means that if you want to use the code in a typical .csx file, you’ll need to alter it slightly (as such code would be edited within the Azure Portal UI rather than from within Visual Studio):

 

using System.IO;

using System.Net;

using System.Net.Http;

using System.Runtime.Serialization.Json;

using System.Text;

using System.Threading.Tasks;

using Microsoft.Azure.WebJobs;

using Microsoft.Azure.WebJobs.Host;

using Microsoft.Xrm.Sdk;

 

namespace AKA.D365.CRM.AzureFunctions.Samples

{

public static class WebhookSample

{

[FunctionName("WebhookSample")]

public static async Task<object> Run([HttpTrigger(WebHookType = "genericJson")]HttpRequestMessage req, TraceWriter log)

{

log.Info($"Webhook was triggered!");

// get the context from D365

string jsonContent = await req.Content.ReadAsStringAsync();

RemoteExecutionContext cdsContext = GetContext(jsonContent);

log.Info("Received: " + cdsContext.MessageName);

Entity updatedAccount = (Entity)cdsContext.InputParameters["Target"];

log.Info(updatedAccount.LogicalName + ": " + updatedAccount.Id);

// return a success message to D365

return req.CreateResponse(HttpStatusCode.OK);

}

 

/// <summary>

/// Returns an execution context object familiar to CRM developers

/// </summary>

/// <param name="contextJSON">JSON String</param>

/// <returns>Xrm sdk RemoteExecutionContext</returns>

private static RemoteExecutionContext GetContext(string contextJSON)

{

RemoteExecutionContext rv = null;

 

using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(contextJSON)))

{

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(RemoteExecutionContext));

rv = (RemoteExecutionContext)ser.ReadObject(ms);

}

 

return rv;

}

}

}

As you can see, implementing Dynamics 365 solutions isn’t always easy. Are you struggling to make Dynamics 365 CRM work for your organization? If so, AKA Enterprise Solutions can help. Contact us today to speak with one of our Dynamics 365 experts.


ABOUT AKA ENTERPRISE SOLUTIONS
AKA specializes in making it easier to do business, simplifying processes and reducing risks. With agility, expertise, and original industry solutions, we embrace projects other technology firms avoid—regardless of their complexity. As a true strategic partner, we help organizations slay the dragons that are keeping them from innovating their way to greatness. Call us at 212-502-3900!

5 thoughts on “Microsoft Dynamics 365 for Sales CRM: How to Write Plug-ins in Azure Functions”

  1. Such a great Post about Microsoft Dynamics 365 for Sales CRM happy to see your story if you want a subscription management Software For your industry please visit our site.

  2. Nice of you to share. It would be great if you still recorded a small video or made more examples of how to use the software. I finally found a good article that explains how to write dynamic 365 CRM modules with Azure.

  3. That all works, good explanation but can you give a example if I want to update a field value after changing it back to CRM? For example after getting the phone no from account entity I formated the phone no and update the field with new value??

    Thanks

    Aakash

  4. Hi!:)
    Thank you so much for sharing. I finally found a good article that explains how to write dynamic 365 CRM modules with Azure. Very useful!:)
    Have a nice day!

Comments are closed.

Show Buttons
Hide Buttons