Respond to SMS and Voice webhooks using F# and Minimal APIs
Time to read: 4 minutes
Twilio's SMS and voice webhooks let you respond to messages and voice calls using TwiML (the Twilio Markup Language). You can implement these webhooks using any F# web framework, but in this tutorial, you'll use the built-in ASP.NET Core Minimal API template.
Prerequisites
Here’s what you will need to follow along:
- .NET 7 SDK (earlier and newer versions may work too)
- A code editor or IDE (I recommend JetBrains Rider, Visual Studio, or VS Code with the Ionide for F# plugin)
- A free Twilio account (sign up with Twilio for free and get trial credit to try out Twilio products)
- A Twilio phone number
- The ngrok CLI and, optionally, a free ngrok account
You can find the source code for this tutorial on GitHub. Use it if you run into any issues, or submit an issue if you run into problems.
Set up your F# Minimal API project
Open your preferred shell and use the .NET CLI to create a new empty ASP.NET Core project with the F# language argument:
Twilio provides some libraries to speed up the development of your Twilio applications, which you'll use for this project. Add the Twilio helper library for .NET and the Twilio helper library for ASP.NET Core using the following commands:
Now you are ready to write some code!
Implement the SMS and Voice webhook
When implementing the SMS or voice webhook, you're expected to respond with TwiML, which instructs Twilio how to respond to a message or call.
Open your project using your preferred IDE and update the Program.fs file with the following code:
Start your application using this command:
Your application will print out the localhost URL(s) the web server is listening to, including the port number. In the upcoming commands, replace [YOUR_LOCALHOST_URL]
with one of those localhost URLs.
To quickly test this without configuring your Twilio phone number, use the following cURL commands or PowerShell:
You should get the following TwiML as the responses:
Configure the webhooks on your Twilio Phone Number
To see how this would behave in your Twilio application, you'll need to configure the message and voice webhook on your Twilio phone number. But before you can do that, you'll need to make your locally running project accessible to the internet. You can quickly do this using ngrok which creates a secure tunnel to the internet for you.
Leave your .NET application running, and run the following command in a separate shell:
ngrok will print the Forwarding URL, which you'll need to publicly access your local application.
Now, go to the Twilio Console in your browser, use the left navigation to navigate to Phone Numbers > Manage > Active Numbers, and then select the Twilio phone number you want to test with. (If Phone Numbers isn't on the left pane, click Explore Products and then on Phone Numbers.)
Then, on the phone number configuration page, locate the "A CALL COMES IN" section. Underneath that:
- set the first dropdown to Webhook,
- set the text box next to it to the ngrok forwarding URL — adding on the /voice path,
- and set the dropdown after the text box to "HTTP POST".
Follow the same steps at the "A MESSAGE COMES IN" section, but use the /message path instead. Then, click Save.
Now, call and text the Twilio phone number. When calling, you should hear "Ahoy". When texting, you should receive a response like "Ahoy!".
Read the incoming message and call details
Responding with a hard-coded message is a great first step, but you'd probably want to respond dynamically instead. Let's add some code to read the incoming message body and repeat it back.
Update the Program.fs file:
Now, the /message endpoint reads the data that is passed in as a form and retrieves the Body
parameter, which holds the body of the text message. That body is then echoed back to the sender.
Let's also make the /voice webhook more interesting by asking a question and then responding differently based on the answer. Update the code as shown below:
Stop the application by pressing ctrl + c and start it again using dotnet run
.
Text and call your Twilio number to try out the new functionality.
Secure your webhooks
Now that your web application is publicly accessible, it's also accessible to malicious actors. Luckily, the Twilio helper library for ASP.NET Core has a ValidateTwilioRequestFilter
that validates that the HTTP request originates from Twilio.
Update Program.fs as below to use it:
The code creates an endpoint group for all the Twilio related endpoints, and adds ValidateTwilioRequestFilter
as an EndpointFilter
for the group. As a result, any requests that did not originate from Twilio will get a 403 Forbidden
response. Otherwise, the endpoint will handle the request as before.
The request validator will use the auth token configured at Twilio:RequestValidation:AuthToken
. Since the Auth Token is a secret that you should not share, you should avoid hard-coding it, such as putting it in your appsettings.json file, or any other way it could end up in your source control history. Instead, use the Secrets Manager aka user-secrets, environment variables, or a vault service.
Run the following commands to initialize user-secrets:
Then grab the Auth Token from your Twilio Account and set it using this command:
When you restart your application, everything should continue to work, but any HTTP request not coming from Twilio or your localhost will be rejected.
Next steps
You learned how to read incoming SMS and calls, how to respond to them, and how to secure your Twilio webhooks, all using F# and ASP.NET Core Minimal APIs.
In addition to receiving SMS and responding to incoming SMS, you can also send SMS from your application. Learn how to send SMS from F# using Twilio.
Here are a couple more resources to further your learning on ASP.NET Core and Twilio:
- Forward Voicemails with Transcript to your Email using C# and ASP.NET Core
- Find your U.S. Representatives and Congressional Districts with SMS and ASP.NET Core
- Respond to Twilio Webhooks using Azure Functions
We can't wait to see what you build. Let us know!
Niels Swimberghe is a Belgian American software engineer and technical content creator at Twilio. Get in touch with Niels on Twitter @RealSwimburger and follow Niels’ personal blog on .NET, Azure, and web development at swimburger.net.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.