Use Visual Studio dev tunnels to handle Twilio Webhooks

Niels Swimberghe

Niels Swimberghe - - .NET

Follow me on Twitter, buy me a coffee

Use Visual Studio dev tunnels to handle Twilio Webhooks

This blog post was written for Twilio and originally published at the Twilio blog.

Visual Studio recently introduced a new feature called dev tunnels. By using dev tunnels, Visual Studio will create a new public URL (tunnel URL) for you, and HTTP requests sent to the tunnel URL will be forwarded to your ASP.NET Core project running on localhost.

Dev tunnels has a lot of use cases. You could use this to easily test your web application on other devices like mobiles phone and tablets. You could also use this to make your application temporarily, publicly available for doing interactive demos and inviting your audience to participate.

How to use dev tunnels with Twilio #

The most exciting use case for Twilio is that you can use dev tunnels to test webhooks. What are webhooks again?

"Webhooks are user-defined HTTP callbacks. They are triggered by some event in a web application and can facilitate integrating different applications or third-party APIs, like Twilio."

At Twilio, we heavily use webhooks throughout all of our products. You can use webhooks to respond to text messages or to manage voice calls. Here's a diagram of what it looks like when there's an incoming text message to your Twilio Phone Number and your application is handling the messaging webhook:

Phone texts "Ahoy!" to a Twilio Phone Number, Twilio sends the SMS details (from and to phone number and the body of the message) via HTTP to your web application, then your application responds with TwiML instructions instructing to respond with "Hi!". Twilio receives the instructions and sends "Hi!" back to the original sender.

When your Twilio Phone Number receives a text message, Twilio will send an HTTP request with the message details to your application. Your application then has to respond with TwiML (Twilio Markup Language) to instruct Twilio how to respond. TwiML is XML with special tags defined by Twilio to provide instructions on how to respond to messages and voice calls. In the diagram depicted above, Twilio will respond with "Hi!" because the app responded with TwiML that looks like this:

<?xml version="1.0" encoding="utf-8"?>

You can learn more about TwiML for Programmable Messaging here.

Some other types of webhooks will inform you of an event and not expect instructions as a response. However, webhook requests can only be made to publicly available URLs, and when you're developing and testing applications, you are usually doing so locally. But with Visual Studio dev tunnels, you can quickly make your web application public, so you can develop your webhooks!

So when a text message comes in, instead of Twilio sending an HTTP request directly to your application, Twilio can send it to your Visual Studio tunnel which will forward it to your application running on localhost.

Diagram of the SMS webhook flow to an ASP.NET Core project tunneled via Visual Studio dev tunnels. Phone sending an SMS has arrows pointing back and forth to the Twilio logo, with arrows back and forth pointing to tunnels.api.visualstudio.com, with arrows pointing back and forth to a laptop with the Visual Studio logo on it.

In this tutorial, you'll learn how to use Visual Studio to create an ASP.NET Core project that will handle the Twilio SMS webhook, use dev tunnels to make the locally running application public, and then configure a Twilio Phone Number to send webhook requests to the public tunnel URL whenever a text message comes in so you can respond to it.

Prerequisites #

You'll need the following things in this tutorial:

  • A Windows machine (there is no information about support for Visual Studio for Mac yet.)
  • Visual Studio 2022 Preview, with the ASP.NET and web development workload installed
  • In Visual Studio, you need to enable the dev tunnels preview feature

You can find details on how to do these steps in the dev tunnels announcement post by Microsoft.

Lastly, you'll also need a Twilio account (trial or upgraded). Try Twilio for free with promotional trial credit.

You can find the source code for this tutorial on GitHub. Use it as a reference if you run into any issues, or submit an issue if you need assistance

Create an empty ASP.NET Core web application with dev tunnels #

Open Visual Studio 2022 preview and click "Create a new project", then search for the "ASP.NET Core Empty" project template and click Next.

Visual Studio "Create a new project" dialog. This dial lists different project templates and the user is searching "Empty" and selected "ASP.NET Core Empty" project.

On the next screen, give your project a meaningful name and click Next. Then on the last screen, leave everything as is and click Create.

Visual Studio will now generate an empty ASP.NET Core application that returns "Hello World!" using Minimal APIs. Go ahead and run your project to see it in action by pressing the green play arrow with your project name.

Visual Studio top toolbar with green play arrow next to the project name "SmsBot".

Visual Studio will run your application, open your browser, and then browse to the web application URL, which will look similar to https://localhost:5000. However, port number 5000 will be a random port number instead. The "Hello World!" application works as expected, but is only reachable on your machine. No other devices can reach it.

Back in Visual Studio, click on the debug dropdown menu, and then select the Dev Tunnels menu item. Now, the Dev Tunnels fly out menu shows you different options, to either select a dev tunnel (but there are none yet), to create a new tunnel, or to open the dev tunnels window.

Visual Studio Debug dropdown menu containing a Dev Tunnels subitem with a fly out menu showing three menu items: None (active the tunnel), Create A Tunnel..., and Show Dev Tunnels Window.

Click on Create A Tunnel... which opens a dialog to create your tunnel.

Dialog with form to create dev tunnel. The form asks for the account to create the tunnel for, in this case a GitHub account, a name for the tunnel, the type which is set to Persistent, and the access level which is set to Public.

Just like the form above, select an Account, enter a Name for the tunnel, set the Tunnel Type to Persistent, and the Access to Public. Then click OK.

When you set the Tunnel Type to Persistent, the URL of your dev tunnel is preserved until you delete the tunnel. When set to Temporary, the URL of the tunnel changes whenever you restart Visual Studio. The Tunnel Access has three options:

  • Private: Only you can access the web application by logging in with your Visual Studio account. This is great for personally testing your application on other devices.
  • Organizational: Anyone within your organization can access the web application. You can use this to demo the application to your teammates.
  • Public: Anyone can access the web application, and you don't need to log in. Make sure it is safe for you to share your application publicly! This is what you need to receive HTTP requests from Twilio webhooks.

Just like before, Visual Studio will open your web browser and browse to your web application. However, this time it will browse to the public tunnel URL, which looks something like https://0pbvlk3m-7032.use.devtunnels.ms/.

Browser with public tunnel URL in the URL bar. The URL ends with "rel.tunnels.api.visualstudio.com". The web page says "Hello World!".

Now you can open the same URL on any other device and send it to your friends and colleagues. As long as your project is running, they will be able to use the web application that is running locally on your machine.

Now that your application is publicly available, let's add some Twilio magic to it ☎️

Respond to SMS with ASP.NET Core #

Buy a Twilio Phone Number #

If you haven't done so already, you'll need to buy a Twilio phone number. To do that, log in to the Twilio Console, select Phone Numbers, and then click on the “Buy a number” button. Note that if you have a free account, you will be using your trial credit for this purchase.

On the “Buy a Number” page, select your country and check SMS in the “Capabilities” field. If you’d like to request a number that is local to your region, you can enter your area code in the “Number” field.

Buy a Twilio phone number

Click the “Search” button to see what numbers are available, and then click “Buy” for the number you like from the results. After you confirm your purchase, click the “Close” button.

Handle Twilio SMS webhook in ASP.NET Core #

Since TwiML is XML, you can use any technique to produce the XML as a response to the Twilio webhook request. However, you can use the Twilio .NET SDK and the Twilio helper library for ASP.NET Core to make it easier.

First, make sure your application isn't running anymore. You can stop your app by pressing the red square icon in the Visual Studio top toolbar, or close the browser window.

Arrow pointing to the stop button which is a red square in the top toolbar.

In Visual Studio, right-click on the Dependencies node of your project, and click "Manage NuGet Packages". This will open the NuGet Package Manager window in Visual Studio. Click on the Browse tab and search for "Twilio.AspNet.Core". Click on the Twilio.AspNet.Core package by Twilio Labs, and click the Install button to install the latest version.

NuGet Package Manager window in Visual Studio searching for "Twilio.AspNet.Core". The "Twilio.AspNet.Core" package is selected and an install button is shown.

By installing the Twilio.AspNet.Core package, you also implicitly install the Twilio NuGet package which has the Twilio SDK. You can also explicitly install the Twilio NuGet package to choose the package version yourself.

Now, replace the code from Program.cs with the following code:

using Twilio.AspNet.Core.MinimalApi;
using Twilio.TwiML;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapPost("/message", () =>
    var messagingResponse = new MessagingResponse();
    return Results.Extensions.TwiML(messagingResponse);


The "Hello World!" GET / endpoint has been replaced with the /message endpoint. The /message endpoint creates a MessagingResponse. messagingResponse.Message("Ahoy!") will create a Message TwiML verb to respond with "Ahoy!".
Lastly, the Results.Extensions.TwiML method will create a TwiMLResult object which takes care of serializing the object to XML and setting the correct content-type headers.

Start your project again. Visual Studio will open the browser again, but you'll see a HTTP 404 error which is fine, this is expected. Copy the URL somewhere as you'll need it in the next section.

Configure your SMS webhook #

Now that your web application is running and publicly available through the tunnel, you can now configure the messaging webhook on your Twilio Phone Number.

Back in the Twilio Console, navigate to Phone Numbers > Manage > Active Numbers, or click this link to the Active Numbers page, then click on your Twilio Phone Number to navigate to the configuration page. Scroll down to the Messaging section and where it says "A MESSAGE COMES IN", pick the "Webhook" option in the first dropdown, paste your Visual Studio tunnel URL and add the /message path, and then pick the "HTTP POST" option from the next dropdown.

Twilio Phone Number Messaging form. There"s a label "A MESSAGE COMES IN" with a dropdown underneath set to "Webhook". Next to the dropdown is a text field set to the Visual Studio tunnel URL, suffixed with /message. Next to the text field is another dropdown, which is set to "HTTP POST".

Click the Save button.

Test your SMS application #

Now that everything has been set up, it's time to test out your SMS application. Pull out your personal phone, and send an SMS to your Twilio Phone Number. You should receive a response saying "Ahoy!".

One thing I always do to gain a better understanding is to put a breakpoint in the application and see when the breakpoint is hit. Feel free to put a breakpoint inside the /message endpoint, and play around with the application to see what you can do with Twilio Messaging.

Alternatively, you can test your messaging and voice applications using the Twilio Dev Phone.

Next steps #

Congratulations on building this SMS application! Since your application is now public, that also means anyone on the internet can reach it which comes with its own risks. To mitigate these risks, you can validate that the incoming requests originated from Twilio and not some bad actor. In this tutorial, you manually updated the webhook URL in the Twilio console, but you can also do this programmatically. Check out this follow-up tutorial on how to automatically configure your Twilio webhooks using Visual Studio dev tunnels.

Want to learn what else you can do with Twilio? Here are some more tutorials for inspiration:

Shout-out to Sayed I. Hashimi for answering my questions and taking my feedback.