Invoke an Azure Function with 2 lines of AL code

In the previous blog post I explained how we can leverage one of the Twilio’s products to send a WhatsApp message from Business Central. By invoking an Azure Function, which uses Twilio framework, from Business Central, we were able to send a WhatsApp message.

Today we are going to look at Microsoft’s own CPaaS (Communication Platform as a Service) product, which is part of Azure platform offering and named Azure Communication Services.

In this blog post I am going to cover:

  • how to create a communication service in Azure portal
  • how to create the Azure Function that uses Azure Communication framework to send a SMS
  • lastly, I will share how to invoke the Azure Function from Business Central with 2 lines of AL code.
Invoke Azure Function from Business Central diagram
Invoke Azure Function from Business Central

Create a Communication Service in Azure Portal

  • Open Azure Portal
  • On the top left of the portal, click on the hamburger button(≡), click on Create a resource, search for Communication Service
  • Select the Communication Services in the result and then select Create
  • Fill out the form on the Azure Communication service.
Azure Portal Communication Service
Azure Portal Communication Service
  • Once you fill in the Subscription, Resource Group, unique Resource name, Region, click on Review & create.

Henceforth, the new communication service should look like this:

As the end goal of this blog is to send a Sms from Business Central we will need to get a phone number.

Open the newly created communication service, choose Phone numbers, and + Get.

Azure Communication Service Phone number setup
Azure Communication Service Phone number setup

We are going to only send/receive SMS with this number:

 

 

 

 

 

 

 

 

 

Create an Azure Function for sending a Sms

In Visual Studio use the wizard to create a new Azure Function project:

(If you don’t have Visual Studio you can download the free version Visual Studio Community 2022).

The code of your new Azure Function will look similar to this:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Azure;
using Azure.Communication;
using Azure.Communication.Sms;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
//using System.Net.Mail;


namespace FnAzureACSSms
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            string connectionString = "endpoint=https://acs-sv.communication.azure.com/;accesskey=blah-blah";
            SmsClient smsClient = new SmsClient(connectionString);
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            string _phone = data.to;
            string _from = data.from;
            string _message = data.message;
            SmsSendResult sendResult = smsClient.Send(from: _from,to: _phone,message: _message);
            string responseMessage = string.IsNullOrEmpty(sendResult.MessageId) ? "0" : "1";
            return new OkObjectResult(responseMessage);
        }
    }
}

Create an Azure Function Application in Azure portal and publish the VS project function to your Azure tenant, to your subscription and Azure Function App.

Publish your Azure Function directly from Visual Studio to your Function App in your subscription and inside your Function App:

Invoke Azure Function from BC with 2 lines of code

The goal is to send to a customer “Mobile Phone No.” a Sms.

  1. Create a Setup table and page to keep Azure function key and URL in BC:
  • “Azure Func. Key” is the key of the published function

(Navigate in Azure Portal to the Function App, then the Function and Function Keys)

  • “Azure Func. URL” is the URL of the Azure Function, which you can obtain from “Get Function URL” button on your function page:

2. Create action on Customers List page:

Trigger Azure Function from Business Central
Trigger Azure Function from Business Central
action(SendSms)
{
     ApplicationArea = Basic, Suite;
     Caption = 'Send Sms';
     Image = Email;
     Promoted = true;
     PromotedCategory = Process;
     ToolTip = 'Send a Sms using Azure Communication Services';
     RunObject = Codeunit "ACS-Sms";
}

And below is the source code of the the codeunit that invokes the Azure Function:

codeunit 50110 "ACS-Sms"
{
    TableNo = Customer;

    var
        ACSSendSms: Record "ACS Send Sms Setup";
        SuccessMessageSentLbl: Label 'Message sent.';
        ErrorMessageLbl: Label 'Error: %1', Comment = 'Error message from Azure function.';
        ContentTypeTxt: Label 'application/json';

    trigger OnRun()
    var
        AzResponse: Codeunit "Azure Functions Response";
    begin
        ACSSendSms.FindFirst();
        AzResponse := InvokeAzureFunc(Rec);
        if AzResponse.IsSuccessful() then
            Message(SuccessMessageSentLbl)
        else
            Message(StrsubstNo(ErrorMessageLbl, AzResponse.GetError()));
    end;

    local procedure InvokeAzureFunc(_Customer: Record Customer): Codeunit "Azure Functions Response"
    var
        AzFuncAuthentication: Codeunit "Azure Functions Authentication";
        Authentication: Interface "Azure Functions Authentication";
        AzFunc: codeunit "Azure Functions";
    begin
        Authentication := AzFuncAuthentication.CreateCodeAuth(ACSSendSms.SVIR_AzureFuncURL, ACSSendSms.SVIR_AzureFuncKey);
        Exit(AzFunc.SendPostRequest(Authentication, BuildBody(_Customer), ContentTypeTxt));
    end;

    local procedure BuildBody(Rec: Record Customer) _return: Text
    var
        _jsonObj: JsonObject;
    begin
        _jsonObj.Add('from', ACSSendSms.SVIR_ACS_Number);
        _jsonObj.Add('to', Rec."Mobile Phone No.");
        _jsonObj.Add('message', 'Hello World');
        _jsonObj.WriteTo(_return);
    end;

}

Invoking the Azure function with 2 lines of code is possible from BC version 21.

With version 21 we get a new set of objects from Microsoft, grouped as “Connect to Azure Functions” that delivers what is promising, a simplified framework for using Azure Functions in BC. These objects are in Microsoft System Application extension:

Azure Function Business Central
Azure Function Business Central

If you want to see how Microsoft build it, have a look here.

Github Azure Function module Business Central
Github Azure Function module

To conclude, the 3 variables needed to trigger an Azure Function with 2 lines of code from AL in BC are:

  • The codeunit “Azure Functions Authentication” carries out the implementation of the interface below for OAuth2 and CodeAuth
  • The Interface “Azure Functions Authentication” contains the source code of an interface with one method: Authenticate();
  • The codeunit “Azure Functions” contains implementations for GET and POST http requests

Summary

In effect, the use case I implemented was about sending a SMS from Business Central.

Therefore, I created in Azure Portal an Azure Communication Service entity, to which I attached a phone number. Moreover, I published an Azure Function that receives from Business Central a json with 3 entities: “From Number” (Azure phone number), a “To Number” (this is BC customer mobile number) and the text of SMS message. Lastly, the Azure Function leverages the library Azure.Communication.Sms to send the Sms.

Equally important, Azure Communication Services include many other features like:

  • Chat
  • Telephony and SMS
  • Voice and Video Calling
  • Email

And, as we just saw, some of these features could potentially be integrated with Business Central.

Leave a Reply

%d bloggers like this: