Introduction
In this tutorial, we will learn how to read incoming messages in Twilio and respond to webhooks using Azure Functions.
We will learn webhooks, how to set up an Azure Function, and then use the Azure Function app to respond to a Twilio SMS webhook and create a record in Dynamic 365 in case an entity receives a new message.
Prerequisites
- A Twilio account.
- An Azure account with an active subscription.
- Dynamic365 subscription.
What is a webhook?
Webhook is an HTTP request triggered by an event in a source system and sent to a destination system. To enable this, you provide the source system with a URL where it can send the HTTP request.
A typical webhook setup involves the following.
- A destination system that needs to be notified about a specific event.
- A source system that sends a notification to the destination system when the event occurs. This system uses the provided webhook URL to make the HTTP request.
In your article, we will focus on responding to webhooks triggered by incoming SMS.
For Twilio SMS, two types of webhooks can be triggered.
- Incoming Message: This webhook is triggered when your Twilio Phone Number receives a message. Twilio will send the details of this message to the webhook URL that you specify.
- Status Callback: This webhook is triggered when the status changes of a message sent via Twilio. This webhook sends a message with the status of the message along with other details about the message.
Building the Azure Function
Open Visual Studio and create Azure function.
Select the Azure function and click on Next.
Once the function creates rename Function1.cs to TwilioReceiveMessage.cs.
.NET APIs, but the Twilio SDK for .NET has dedicated APIs to generate TwiML. Add the Twilio NuGet package using the .NET CLI.
Navigate to Tools in Visual Studio à NuGet Package Manager à Manage Nuget Packages for a solution and install below two packages below.
- Package Twilio
- Twilio.AspNet.Core
- Microsoft.PowerPlatform.Dataverse.Client ( To connect CRM service)
Now, update the TwilioReceiveMessage class with the following code.
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using Twilio.AspNet.Core;
using Twilio.TwiML;
using Microsoft.PowerPlatform.Dataverse.Client;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk;
using System.Security.Cryptography;
namespace TwilioMessage
{
public class TwilioReceiveMessage
{
private readonly ILogger<TwilioReceiveMessage> _logger;
public TwilioReceiveMessage(ILogger<TwilioReceiveMessage> logger)
{
_logger = logger;
}
private static ServiceClient service { get; set; }
public static ServiceClient Service
{
get
{
if (service == null)
{
service = new ServiceClient(
new Uri(Environment.GetEnvironmentVariable("CRMIntegrationTargetEnvironment")),
Environment.GetEnvironmentVariable("CRMIntegrationClientId"),
Environment.GetEnvironmentVariable("CRMIntegrationClientSecret"),
true
);
}
return service;
}
set => service = value;
}
[Function("TwilioReceiveMessage")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req,
ILogger logger)
{
logger.LogInformation("C# HTTP trigger function processed a request.");
var form = await req.ReadFormAsync();
var body = form["Body"];
logger.LogInformation("Message: " + body);
var fromNumber = form["From"].ToString();
logger.LogInformation("From Number: " + fromNumber);
if (Service.IsReady)
{
CreateCase(fromNumber, body);
}
var response = new MessagingResponse();
response.Message(
$"You sent: {body}",
action: new Uri("/api/MessageStatus", UriKind.Relative),
method: Twilio.Http.HttpMethod.Post
);
return new TwiMLResult(response);
//return new OkObjectResult("Welcome to Azure Functions!");
}
private static void CreateCase(string fromNumber, string body)
{
Entity caseEntity = new Entity("cases");
caseEntity.Attributes.Add("title", body);
caseEntity.Attributes.Add("mobilephone", fromNumber);
Service.Create(caseEntity);
}
}
}
Now let's Implement the Status Callback Webhook, right click on project àAdd àNew Azure Function.
Give function name as MessageStatus.cs Select the Http trigger and click on Add as shown in the below screens.
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using Twilio.AspNet.Core;
using Twilio.TwiML;
using Microsoft.PowerPlatform.Dataverse.Client;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk;
namespace TwilioMessage
{
public class MessageStatus
{
private readonly ILogger<MessageStatus> _logger;
public MessageStatus(ILogger<MessageStatus> logger)
{
_logger = logger;
}
[Function("MessageStatus")]
public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
var form = await req.ReadFormAsync();
string messageSid = form["MessageSid"];
string messageStatus = form["MessageStatus"];
_logger.LogInformation(
"Status changed to {MessageStatus} for Message {MessageSid}",
messageStatus,
messageSid
);
return new OkResult();
}
}
}
Deploy the Azure Function to Azure.
Navigate to https://portal.azure.com/ and search for the function app.
Select the resource group in which you want to create the function app, give the function name, and click on Review + Create.
Note. Make sure you create your Environment Variables in the Azure function, whatever you are using in the app.cofig file.
The Azure function will be created.
Now, let’s publish the function app on Azure. Right-click on project and click on publish.
Once the Azure function is published, get the URL.
Configure the webhook URL in Twilio
Now that we have the Azure function app URL, let’s configure the webhook URL in twilo.
- Log in to the Twilio console and select your Account.
- Click on the Explore Products and select Phone Numbers. Then, in the left side navigation, click on Phone Numbers àManage àActive Numbers.
- Click the active number you'd like to use which will take you to the configuration page.
- On the configuration page, scroll down to the Messaging Section. Under ‘A MESSAGE COMES IN’, set the first dropdown to Webhook, then into the text box, enter the azure function app URL as the path, and lastly, set the second dropdown to HTTP POST.
- Click Save and then send an SMS to your Twilio Phone Number.
Thank you!