Using GOV.UK Notify in a Dynamics CRM Plugin Without ILMerge

Zoe Dawson
Capgemini Microsoft Blog
4 min readOct 16, 2019

With GOV.UK Notify’s SMS sending service becoming the next hip and trendy thing for government departments to use, it was only a matter of time before it had to be integrated with Dynamics CRM.

This blog post shows you how to create a Dynamics CRM plugin that can send text messages using this service, without using ILMerge, adding DLLs to the GAC or any other funny business.

It is important to try and avoid using ILMerge, as Microsoft has said it is unsupported. Adding DLLs to the GAC is not unsupported, but isn’t an option in online instances of Dynamics and can be difficult to maintain in on premise instances, requiring installation of every DLL you want to use into the GAC of every Dynamics server, and updating the DLLs on each of these servers when a new version of a DLL is released.

Dependencies

The first thing to tackle is the Gov.UK Notify DLL’s dependencies, as if we aren’t using ILMerge we won’t be able to add these DLLs into Dynamics for our plugin to use either. Gov.UK Notify has two dependencies: Newtonsoft.Json for JSON parsing and JWT for generating JWT authentication tokens.

Newtonsoft.Json

The Newtonsoft.Json library is used to create the JSON request to be sent to the Notify API. This can be replaced using the System.Web.Extensions JavaScript serializer. To use this, we have to create a class for every JSON object we want to parse; the ones you’ll need for the whole plugin are below:

class Header

{

public string typ { get; set; }

public string alg { get; set; }

}

class Request

{

public string phone_number { get; set; }

public string template_id { get; set; }

public Dictionary<string, string> personalisation { get; set; }

}

class Payload

{

public string iss { get; set; }

public double iat { get; set; }

}

The final step in replicating the Newtonsoft.Json DLL is writing a method to create our new Request object from the values we’re pulling out of CRM:

public static Request CreateRequestParams(string templateId, Dictionary<string, string> personalisation, string mobileNumber)

{

var req = new Request

{

template_id = templateId,

personalisation = personalisation,

phone_number = mobileNumber,

};

return req;

}

JWT

The second DLL we need to replace is JWT, which provides the JWT token generation functionality that the Notify API uses to authenticate. This is considerably more complicated than the Newtonsoft.Json replication; the first step was to Google what a JWT token is made from. Conveniently, the JWT website itself tells you exactly how a token is made (https://jwt.io/), so the next step is to recreate this in C#, using some of the JSON objects we created earlier to help us.

JWTs are comprised of three main parts; a header containing information on the type of token and algorithm used, a payload, which is a combination of the service ID (first half of your API key) and the current time in seconds, and finally the signature, which is the base64 encoded header and payload hashed using a secret, which in this case is the second half of your API key. The generate token function is shown below. I also added a little GetCurrentTimeInSeconds function to make it neater.

public string GenerateToken(string secret, string serviceId)

{

var header = new Header

{ typ = “JWT”, alg = “HS256” };

var headerJson = new JavaScriptSerializer().Serialize(header);

var payload = new Payload { iss = serviceId, iat = GetCurrentTimeInSeconds() };

var payloadJson = new JavaScriptSerializer().Serialize(payload);

var headerEncoded = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(headerJson));

var payloadEncoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(payloadJson));

var data = headerEncoded + “.” + payloadEncoded;

var hasher = new HMACSHA256(Encoding.UTF8.GetBytes(secret));

var hashedData = hasher.ComputeHash(Encoding.UTF8.GetBytes(data));

var signature = System.Convert.ToBase64String(hashedData);

var token = headerEncoded.ToString() + “.” + payloadEncoded.ToString() + “.” + signature;

return token;

}

public static double GetCurrentTimeInSeconds()

{

var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

return Math.Round((DateTime.UtcNow — epoch).TotalSeconds);

}

Now we have the JWT token and the JSON serialiser, it’s time to send a text. I used two functions for this, one to set up the client and one to send the request. These functions can be used to send one text, or in a for loop to send multiple, just put all of this logic in a class, create a new instance of the class in your plugin Execute method and call SendText().

Note that the “content” property in the dictionary should correspond to the name of the personalisation set in the template being used. For example, for the default templates, this would be “fullname” or “lastname”.

public HttpResponseMessage SendText(string mobileNumber, string msgContent)

{

var client = new HttpClient();

client.BaseAddress = new Uri(smsEndPoint);

client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(“application/json”));

HttpResponseMessage response;

var content = new Dictionary<string, string>()

{

{“content”, msgContent }

};

return SendSmsAsync(client, mobileNumber, templateid, content);

}

HttpResponseMessage SendSmsAsync(HttpClient client, string mobileNumber, string templateId, Dictionary<string, string> personalisation)

{

var params = CreateRequestParams(templateId, personalisation, mobileNumber);

var url = “”;

var jsonParams = new JavaScriptSerializer().Serialize(params);

var request = new HttpRequestMessage(HttpMethod.Post, smsEndPoint);

var content = new StringContent(jsonParams, Encoding.UTF8, “application/json”);

var token = GenerateToken(smsApiKey.Substring(37,36), smsApiKey.Substring(0, 36));

request.Headers.TryAddWithoutValidation(“Authorization”, “Bearer “ + token);

request.Content = content;

HttpResponseMessage response;

return client.SendAsync(request).Result;

}

Conclusion

This blog post covered the reasons for using the GOV.UK Notify API over the DLL when sending SMS messages from Dynamics CRM plugins, how to replace the GOV.UK Notify DLL dependencies with your own code, and finally how to access and send a text using the API.

If it doesn’t work first time, don’t give up! It’s worth investing the time to make the code supported by Microsoft rather than using ILMerge to avoid the problem.

Join the Capgemini Microsoft team, open roles here.

--

--