Scenario
- On Business Central, when a sales order is being updated the subscribed WebHook is invoked (WebHooks are a new feature in BC, they are really powerful and they deserve to be used);
- The Web hook gets order details and send a SMS to the sales agent (eg: “The XYZ order has been released, do you want to send a confirmation email to your customer”?) and wait his/her reply;
- The sales agent reply with a YES/NO and in case the Azure Function sends an SMS with order detail to the final customer;

THE RECIPE
The recipe is pretty easy and consists in three ingredients:
- Buy a Twilio phone number and then configure twilio account.
- Create a simple Azure function and deploy it.
- Set-Up a BC WebHook on SalesOrder table (for newbies, later on I briefly describe the powerful technology of web hooks)

In this sample I am not using Azure Vault to store passwords and I just use settings.json, you should when in production environment 🙂
DOWNLOAD AND DEPLOYS AZURE FUNCTION
A simple Azure Function works as subscriber for Business Central WebHook.
Here are sources in GitHub: https://github.com/avalonit/AzSalesOrderWebHook
The azure function consists basically in five .cs files.
SalesOrderWebHook.cs contains the azure function subscribed as Business Central WebHook. In my sample the WebHook is trigger every time a SalesOrder modification occurs. The function is in charge to manage the high level logic.

Pay attention to these couple of lines of code, they are very important and this is the response the azure function must reply when you will subscribe your web hook in Business Central. Basically they response back the validation token to BC.
BusinessCentralConnector.cs contains class that manages calls to API. It connects to API and get the requested order and sales agent by applying filtering to API request.

MessageComposer.cs is the class that create the response string used to reply to the request.
SalesOrders.cs and Employees.cs are the class representing Business Central SalesOrders and Empolyees tables. They are used for deserialising API data. I find useful https://app.quicktype.io/ to automatically convert Json returned from BC API to C# class. Just pay attention to DateTimeOffset field type that are not supported by JSON.

To have your solution working just download sources, configure your Business Central endpoint and deploy it to your azure subscription.
SUBSCRIBE A WEB HOOK IN BUSINESS CENTRAL
There is brief but well written article about web hooks here:
https://docs.microsoft.com/en-us/dynamics-nav/api-reference/v1.0/dynamics_subscriptions
I use Insomia to register a new web hook to subscribe to OrderSales table modifications. Basically you POST to your Business Central URL
https://api.businesscentral.dynamics.com/v1.0/{your_business_central_instance}/sandbox/api/v1.0/subscriptions
a JSON content like this:
{
“notificationUrl”: “https:/{your_azurefunction_address}.azurewebsites.net/api/SalesOrderWebHook”,
“resource”: “/api/v1.0/companies({your_company_id})/salesOrders”,
“clientState”: “optionalValueOf250”
}
If the azure function is working you get a confirmation reply:
{
“@odata.context”: “https://api.businesscentral.dynamics.com/v1.0/{your_bc_instance}/sandbox/api/v1.0/$metadata#subscriptions/$entity”,
“@odata.etag”: “W/\”JzQ0O1djTE9JamVYVk0yMDYxc0dwRElCT1lPQlAwOHVISSsyeG9Tem81RlJhUXc9MTswMDsn\””,
“subscriptionId”: “39db02dc8ccf4fd59755d92a9080197c”,
“notificationUrl”: “https://{your_azurefunction_url.azurewebsites.net}/api/SalesOrderWebHook”,
“resource”: “api/v1.0/companies({your_company})/salesOrders”,
“userId”: “dc77101d-e4d4-4e42-84ae-68c54851c232”,
“lastModifiedDateTime”: “2020-04-12T08:04:53Z”,
“clientState”: “optionalValueOf250”,
“expirationDateTime“: “2020-04-15T08:04:53Z”
}
You can check anytime your active web hooks subscribed with a simple API query:
https://api.businesscentral.dynamics.com/v1.0/your_bc_instance/Sandbox/api/v1.0/subscriptions
CONFIGURE TWILIO
First of all you need to buy a Twilio phone number. Unfortunately some countries are not available when you buy a number, for example Italy is not. In my case I decided to buy a number from Belgium the subscription is 1€ per month and thanks to European Union roaming rules messages among EU countries are charged same price as national message.
In Twilio site you have a wide choice of numbers:
https://www.twilio.com/console/phone-numbers/search
Then you have to register all destination numbers in Twilio.
ABOUT SMS
An SMS nowadays might sound some kind of old-fashion manner to send a message. First thought you may have is: why don’t you use whatsapp, SMS is just such an old technology. It’s true but if you have have to deal with an international customer it’s not so obvious to use WhatsApp. In every region of the world you have different messaging platforms: WeChat in Asia, Line in Japan, KaKaoTalk in South Korea, Telegram is Middle East countries, Viber is former Russian countries. It’s a mess and I takes time to implement all of them. Instead SMS are working everywhere and they are just so easy to handle!
LAST UPDATE
12th of April 2020