Write an Azure Function that processes Microsoft Dataverse events
The previous exercise reviewed how to register webhooks that expose Microsoft Dataverse data to an external Web API. In this exercise, you will build an example Web API by using Azure Functions to illustrate how to consume a published webhook event.
Azure Functions vs. plug-ins
Microsoft Azure Functions provides a great mechanism for doing small units of work, similar to what you would use plug-ins for in Dataverse. In many scenarios it might make sense to offload this logic into a separate component, such as an Azure Function, to reduce load on the Dataverse's application host. You have the availability to run functions in a synchronous capacity because Dataverse webhooks provide the Remote Execution Context of the given request.
However, Azure Functions does not explicitly run within the Dataverse's implementation pipeline, so if you need to update data in the most high-performing manner, such as autoformatting a string value before it posts to Dataverse, we still recommend that you use a plug-in to perform this type of operation.
Write an Azure Function that processes Dataverse events
To start writing an Azure Function that processes Dataverse events, you will use Visual Studio 2019's Azure development template to create and publish your Function. Visual Studio provides a number of tools that are available to help make Azure development simple. Therefore, you are required to have Azure Development Tools installed in your Visual Studio 2019 instance. If you don't have the feature installed, you can add it through the Visual Studio Installer.
Create your Azure Function project
Create a new Azure Function project by using the Azure Functions template. You can find this template by creating a new project and then entering "function" in the search bar.
Give your Function project a descriptive name and then select Create.
Specify the Azure Functions v2 (.NET Core) type and ensure that Http trigger template is selected. You can set Storage Account to None because you won't be using storage for this exercise; however, you might need it in other scenarios. Set the Authorization level to Function and then select Create.
Your sample project should be created now, with the following template code found in the Function's .cs file:
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}
}
You will be replacing this code later, but first, you will publish your Function to ensure that everything works correctly.
Publish your Azure Function to Azure
Right-click your project and select Publish... from the context menu to test the publishing of your Function to Azure App Service.
Create a new publish target if you haven't already. If you'd like to select an existing App Service plan, you can skip this step and select the Select Existing option instead.
If you are creating a new publish target, name your new App Service, verify that its Subscription, Resource group, Location, and Azure Storage fields are correct, and then select Create.
After your Publish profile is created, select Publish to deploy your Function to Azure. The Function is published by default in release mode. If you'd like to debug this function (more on this later), you'll want to publish the Function in Debug mode.
Another method to create Azure Functions
If you want to manually create your Azure Function without the help of Visual Studio 2019, you can do so from the Azure portal:
Sign in to your Azure environment and create a Function App by selecting Create a resource.
To create an Azure Function App, specify its name and runtime stack, and then verify that the Subscription, Resource group, and Region fields are correct.
Note
This lesson doesn't cover the details of building a new Azure Function assembly.
Update your Function's logic to interact with Dataverse data
If needed, change your Function's FunctionName and corresponding class name to something more meaningful (that is, MSLearnFunction).
Add the following using statements to your Function:
using Newtonsoft.Json.Linq;
Replace the code inside the Run function with the code below:
log.LogInformation("C# HTTP trigger function processed a request."); string queryParams = ""; foreach (var q in req.Query) { queryParams += $"Key: {q.Key} Value: {q.Value}\n"; } string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); dynamic data = JsonConvert.DeserializeObject(requestBody); string requestHeader = ""; foreach (var h in req.Headers) { requestHeader += $"Key: {h.Key} Value: {h.Value}\n"; } log.LogInformation("Query Parameters:\n" + queryParams); log.LogInformation("Request Header: \n" + requestHeader); log.LogInformation("Request Body:\n" + requestBody); string requestBodyFormatted = JValue.Parse(requestBody).ToString(Formatting.Indented); log.LogInformation("Request Body Formatted:\n" + requestBodyFormatted); try { dynamic target = data.InputParameters["Target"]; foreach (dynamic field in target.Attributes) { log.LogInformation($"Name: {field.Key} Value: { field.Value}"); } } catch (Exception ex) { log.LogInformation(ex.ToString()); } return (ActionResult)new OkObjectResult(data.InitiatingUserId);
Build your Function and publish it to Azure by right-clicking the project and then selecting Publish....
Verify that your Function has been published by going to the Azure portal. You can either manually select it from within the resource group that you specified when you created the Function, or you can search for it by name in the Azure portal, as shown in the following image.
Register a Dataverse webhook that calls your Azure Function
In this exercise, you'll use the Plug-in Registration Tool to register a webhook that calls your new Azure Function.
Open the Plug-in Registration Tool and sign in to your Dataverse environment.
Register a new webhook by selecting Register New Web Hook under the Register menu option.
Get your Function's URL from the Azure portal by selecting Get function URL.
Paste the copied value into a text editor, which should look like the following image.
https://[AppServiceUrl].azurewebsites.net/api/MsLearnFunction?code=[WebhookKey]
Cut and paste the code query string value from the copied URL and place into the Value section of the WebHook Registration string (make sure to remove the code= portion).
Register a new step that will post a message on creation of a new account. Register a new step by right-clicking your new webhook assembly and then selecting Register New Step.
Configure the step as illustrated in the following figure. Because you will be building this webhook to run synchronously, ensure that the flag is set when you are registering the new step.
Test your webhook integration
To test your webhook integration, go to your Dataverse environment and create an account.
Go to your Function in the Azure portal and view the logs.
Need help? See our troubleshooting guide or provide specific feedback by reporting an issue.