In our previous post, we created a simple Azure Function using a free account. (1-hour limitation).
https://nishantrana.me/2017/04/26/starting-with-a-simple-hello-world-azure-functions/
In this post, we’d use our trial Azure account to create a Function App for which we will configure Web Hook trigger and it outputs to Queue and Azure Blog Storage.
We will call this Function from Plugin on Post Create of Lead in CRM Online and pass Lead details to it. This detail will be then passed to Queue and a file inside Azure Blog Storage as Output from the Function.
Open the Azure Portal
Select Function App.
Create the Function App.
Click on + for Functions to create a new Function.
We’d select GenericWebHook-Csharp template here.
This creates a new Function nme MyLeadWebHook and it has mode set to Webhook and type as Generic JSON.
We can define Post as the only allowed method to call this function as shown below.
Update the code for the function by defining the Lead Object and deserialization logic as shown below.
#r is syntax for referencing the library. Here Newtonsoft.Json library is being referenced for deserialization.
Save and Run to check if it has compiled successfully or not. Click on Test tab to test the function by passing the JSON in the request body.
We can see below that our function has run successfully.
This finishes our Web Hook trigger part. Now let us define the Queue Output to it.
Select Integrate and click on New Output.
Select Azure Queue Storage template here.
Name the queue as leadqueue. This will automatically create a queue name leadqueue.
The parameter name here is outputQueueItem. We will update our code to pass the lead details to this parameter.
Before we update the code for our function let us add new output which saves the Lead details to a text file. Click on new output and select Azure Blog Storage.
Here outputBlob is the parameter to which we need to provide the lead details. In the path outcontainer is the name of the container within Blob and rand-guid generates a random guid for the file name. Here we have added the extension .txt.
Now we have our outputs defined, so let us go back to our code for the function and update it to pass values to both the output parameter one for queue and other for the blob.
#r "Newtonsoft.Json" using System; using System.Net; using Newtonsoft.Json; public class Lead { public string Topic { get; set;} public string FullName { get; set;} public string Email { get; set;} } public static async Task<object> Run(<span class="hiddenSpellError" pre="" data-mce-bogus="1">HttpRequestMessage</span> req, TraceWriter log, </object> IAsyncCollector<Lead> outputQueueItem, TextWriter outputBlob) { log.Info($"Lead Information Recieved"); string jsonContent = await req.Content.ReadAsStringAsync(); var lead = JsonConvert.DeserializeObject<Lead>(jsonContent); log.Info($"Lead named {lead.Topic} created for {lead.FullName} with email id {lead.Email}"); // add to queue await outputQueueItem.AddAsync(lead); // write to a text file in azure blog storage outputBlob.WriteLine($"Topic: {lead.Topic}"); outputBlob.WriteLine($"Full Name: {lead.FullName}"); outputBlob.WriteLine($"Email: {lead.Email}"); return req.CreateResponse(HttpStatusCode.OK, new { message = "Lead Information Recieved" }); }
To test the code click on Test and select Run
Click on Monitor tab for the Function and select the log created for our test run. We can see the values for the parameters in the invocation details section.
Now let us write a plugin that runs on Post Create of lead and calls this Function App.
First let us get the URL for our function app. Go to Function and click on Get Function URL.
Our Function URL –
The code parameter is the Key that should be passed while calling the above URL.
Keys tab is where we can configure out Keys.
Below is code for our plugin.
using Microsoft.Xrm.Sdk; using System; using System.IO; using System.Net; using System.Runtime.Serialization.Json; using System.Text; namespace MyTestPlugin { public class Lead { public string Topic { get; set; } public string FullName { get; set; } public string Email { get; set; } } public class MyPluginClass : IPlugin { public void Execute(IServiceProvider serviceProvider) { try { // Obtain the execution context from the service provider. IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); // The InputParameters collection contains all the data passed in the message request. if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) { // Obtain the target entity from the input parameters. Entity entity = (Entity)context.InputParameters["Target"]; using (WebClient client = new WebClient()) { // get the lead details var myLead = new Lead(); myLead.Topic = entity.Attributes["subject"].ToString(); myLead.FullName = entity.Attributes["fullname"].ToString(); myLead.Email = entity.Attributes["emailaddress1"].ToString(); DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Lead)); MemoryStream memoryStream = new MemoryStream(); serializer.WriteObject(memoryStream, myLead); var jsonObject = Encoding.Default.GetString(memoryStream.ToArray()); var webClient = new WebClient(); webClient.Headers[HttpRequestHeader.ContentType] = "application/json"; // our function key var code = "2QYP6xwCswMNmzJDFJdDE65ed1PdNBOj5Wlu4LbSpeSjs/58h1KLbg=="; // the url for our Azure Function var serviceUrl = "https://mycrmfunctionapp.azurewebsites.net/api/MyLeadWebHook?code=" + code; // upload the data using Post mehtod string response = webClient.UploadString(serviceUrl, jsonObject); } } } catch (Exception ex) { throw new InvalidPluginExecutionException(ex.Message); } } } }
Let us create our lead record in CRM and test our Azure Function.
We can check the Monitor tab for our Function and check the logs and can see the Lead Information added to queue and also a text file created from our output parameters.
Our text file in the container.
Hope it helps..
Hi Nishant, I have question regarding authentication enabled for above Azure Function. If AAD is enabled, how plugin code will change for that scenario?
LikeLike
These 3mw6h http://3mw6h.ga/ are excellent!! Really like THEM!!
LikeLike
Hi Nishant,
Why did you call the Function app from within a plugin?
Can’t we just call the Function app directly using Webhook and register a step on create of lead?
LikeLiked by 1 person
That article is of April 2017 Gaurav when that feature was not released. https://nishantrana.me/2017/11/14/register-a-new-webhook-through-plugin-registration-tool-in-dynamics-365/
LikeLike