Skip to contentSkip to navigationSkip to topbar
Rate this page:
On this page

Serverless Webhooks with Azure Functions and C#


Serverless architectures allow developers to write code that runs in the cloud without managing servers. "Serverless" applications can be very efficient with compute resources (significantly reducing associated costs) by only running in response to events like API requests. Microsoft Azure's offering for serverless code is called Azure Functions(link takes you to an external page). Let's look at a practical application of Azure Functions by writing C# code to handle Twilio webhooks for incoming SMS messages and voice phone calls.

(information)

Info

Twilio can send your web application an HTTP request when certain events happen, such as an incoming text message to one of your Twilio phone numbers. These requests are called webhooks, or status callbacks. For more, check out our guide to Getting Started with Twilio Webhooks. Find other webhook pages, such as a security guide and an FAQ in the Webhooks section of the docs.


Create a New Azure Function app

create-a-new-azure-function-app page anchor

To get started on the road to serverless bliss, you first need to create a new Function App in the Azure Portal(link takes you to an external page). Do this by clicking New, searching for "Function App" and selecting "Function App" from the list:

Azure - Create function app.

After clicking on "Function App," click the "Create" button. Provide an app name and other parameters to your preferences:

Azure - Function app details.

Write a Function to Respond to SMS Messages

write-a-function-to-respond-to-sms-messages page anchor

Create the Function

create-the-function page anchor

Bring up your new Function App in the Azure Portal. You should see the Quickstart page which will give you options for creating your first function. We want to use the "Webhook + API" scenario and choose C# as our language:

Azure - Create function.

Click "Create this function" and you'll be presented with the function editor, where you can start cutting some code.

Install the Twilio Helper Library

install-the-twilio-helper-library page anchor

When Twilio calls your webhook, it is expecting a response in TwiML. Our C# code will need to generate this TwiML, which is just standard XML. While we could create the XML in a string, the Twilio Helper Library(link takes you to an external page) provides classes to make it easy to build a valid TwiML response. Azure Functions allows installing NuGet packages and making them available to your functions. We need to create a project.json file with the following content:

project.json for C# Azure Functions

projectjson-for-c-azure-functions page anchor

Reference the Twilio Helper Library in Azure Functions C# code.


_10
{
_10
"frameworks": {
_10
"net46":{
_10
"dependencies": {
_10
"Twilio": "5.0.2"
_10
}
_10
}
_10
}
_10
}

To create this file, click the button and then the button. Name the file project.json. Paste the JSON into the code editor and Save the file.

Write the Message Handling Code

write-the-message-handling-code page anchor

Now let's write the code that will handle the incoming text message. Switch back to your function code (click the run.csx file) and paste the following C# code into the editor:

Receive SMS with C# Azure Functions

receive-sms-with-c-azure-functions page anchor

_29
#r "System.Runtime"
_29
_29
using System.Net;
_29
using System.Text;
_29
using Twilio.TwiML;
_29
_29
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req,
_29
TraceWriter log)
_29
{
_29
log.Info("C# HTTP trigger function processed a request.");
_29
_29
var data = await req.Content.ReadAsStringAsync();
_29
var formValues = data.Split('&')
_29
.Select(value => value.Split('='))
_29
.ToDictionary(pair => Uri.UnescapeDataString(pair[0]).Replace("+", " "),
_29
pair => Uri.UnescapeDataString(pair[1]).Replace("+", " "));
_29
_29
// Perform calculations, API lookups, etc. here
_29
_29
var response = new MessagingResponse()
_29
.Message($"You said: {formValues["Body"]}");
_29
var twiml = response.ToString();
_29
twiml = twiml.Replace("utf-16", "utf-8");
_29
_29
return new HttpResponseMessage
_29
{
_29
Content = new StringContent(twiml, Encoding.UTF8, "application/xml")
_29
};
_29
}

Twilio will send data about the incoming SMS as form parameters in the body of the POST request. This function has the code to parse out all of those parameters. You need only reference the name of the parameter you want such as formValues['Body'] for the body of the message or formValues['From'] for the phone number of the person sending the message.

The output of the function is a properly formatted XML response containing the TwiML built by the Twilio.TwiML.MessagingResponse builder. This function simply echoes back whatever message was sent, but you can see where you could put code to do any number of things such as call an external API or make use of other Azure resources(link takes you to an external page).

Configure the Message Webhook

configure-the-message-webhook page anchor

Now we need to configure our Twilio phone number to call our Azure Function whenever a new text message comes in. To find the URL for your function, look for the Function Url label directly above the code editor in the Azure Portal:

Function url.

Copy this URL to the clipboard. Next, open the Twilio Console and find the phone number you want to use (or buy a new number). On the configuration page for the number, scroll down to "Messaging" and next to "A MESSAGE COMES IN," select "Webhook" and paste in the function URL. (Be sure HTTP POST is selected, as well.)

Azure Functions Phone Number Config.

Test the Message Webhook Function

test-the-message-webhook-function page anchor

Now send a text message to your Twilio phone number. If you texted "Hello", then you should get a reply back saying "You said: Hello". If there are any problems, you can use the button in the Azure Function to see what error messages are happening on the server-side. To see errors on Twilio's side, use the Twilio Debugger.

If you'd like to simulate a request from Twilio, you can use the button. Provide [url encoded form parameters](https://en.wikipedia.org/wiki/POST_(HTTP\)#Use_for_submitting_web_forms(link takes you to an external page)) in the "Request body" field and the click the "Run" button at the top of code editor.


Write a Function to Handle Phone Calls

write-a-function-to-handle-phone-calls page anchor

Follow the same steps above to create your function and reference the Twilio Helper Library.

Write the Call Handling Code

write-the-call-handling-code page anchor

Now let's write the code that will handle the incoming phone call. Switch back to your function code (click the run.csx file) and paste the following C# code into the editor:

Receive Voice Calls with C# Azure Functions

receive-voice-calls-with-c-azure-functions page anchor

_35
#r "System.Runtime"
_35
_35
using System.Net;
_35
using System.Text;
_35
using Twilio.TwiML;
_35
_35
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req,
_35
TraceWriter log)
_35
{
_35
log.Info("C# HTTP trigger function processed a request.");
_35
_35
var data = await req.Content.ReadAsStringAsync();
_35
var formValues = data.Split('&')
_35
.Select(value => value.Split('='))
_35
.ToDictionary(pair => Uri.UnescapeDataString(pair[0]).Replace("+", " "),
_35
pair => Uri.UnescapeDataString(pair[1]).Replace("+", " "));
_35
_35
// Perform calculations, API lookups, etc. here
_35
_35
// Insert spaces between the numbers to help the text-to-speech engine
_35
var number = formValues["From"]
_35
.Replace("+", "")
_35
.Aggregate(string.Empty, (c, i) => c + i + ' ')
_35
.Trim();
_35
_35
var response = new VoiceResponse()
_35
.Say($"Your phone number is {number}");
_35
var twiml = response.ToString();
_35
twiml = twiml.Replace("utf-16", "utf-8");
_35
_35
return new HttpResponseMessage
_35
{
_35
Content = new StringContent(twiml, Encoding.UTF8, "application/xml")
_35
};
_35
}

Twilio will send data about the incoming call as form parameters in the body of the POST request. This function has the code to parse out all of those parameters. You need only reference the name of the parameter you want such as formValues['From'] for the phone number of the person calling or formValues['CallSid'] for a unique identifier of the call.

The output of the function is a properly formatted XML response containing the TwiML built by the Twilio.TwiML.VoiceResponse builder. This function simply tells the caller their phone number, but you can see where you could put code to do any number of things such as call an external API or make use of other Azure resources(link takes you to an external page).

Configure the Voice Webhook

configure-the-voice-webhook page anchor

Now we need to configure our Twilio phone number to call our Azure Function whenever a call comes in. To find the URL for your function, look for the Function Url label directly above the code editor in the Azure Portal:

Function url.

Copy this URL to the clipboard. Next, open the Twilio Console and find the phone number you want to use (or buy a new number). On the configuration page for the number, scroll down to "Voice" and next to "A CALL COMES IN," select "Webhook" and paste in the function URL. (Be sure HTTP POST is selected, as well.)

Azure Functions Voice Config.

Test the Voice Webhook Function

test-the-voice-webhook-function page anchor

Now call your Twilio phone number. You should hear a voice saying "Your phone number is <123456>". If there are any problems, you can use the button in the Azure Function to see what error messages are happening on the server-side. To see errors on Twilio's side, use the Twilio Debugger.

If you'd like to simulate a request from Twilio, you can use the button. Provide [url encoded form parameters](https://en.wikipedia.org/wiki/POST_(HTTP\)#Use_for_submitting_web_forms(link takes you to an external page)) in the "Request body" field and the click the "Run" button at the top of code editor.


The Azure Functions documentation(link takes you to an external page) contains all you need to take your functions to the next level. Be sure to also refer to our TwiML Reference for all that you can do with TwiML in your serverless webhooks.

Now, get out there and enjoy your new serverless life.


Rate this page: