Respond to SMS and Voice webhooks using F# and Giraffe
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 one of the most popular F# web frameworks, Giraffe.
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# web 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:
Next, add the Giraffe package:
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:
The code adds Giraffe to ASP.NET Core's services and adds Giraffe to the request pipeline.
The Giraffe webapp
routes the HTTP requests with path /message to the messageHandler
after binding the form body to an SmsRequest
object, and routes HTTP requests with path /voice directly to the voiceHandler
.
Both handlers generate TwiML instructions that are written to the HTTP response body using writeTwimlAsync
.
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 application 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 within the Message Configuration menu, 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 [YOUR_PHONE_NUMBER]!".
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 method RequestValidationHelper.IsValidRequest
that validates that the HTTP request originates from Twilio.
Update Program.fs as below to use it:
The validateTwilioRequest
HTTP handler will validate that the HTTP request originates from Twilio. If the HTTP request originates from Twilio, the next HTTP handler is invoked, otherwise a 403 Forbidden
response is sent back.
The new validateTwilioRequest
HTTP handler is included in the Giraffe webApp
so it is invoked before the /message and /voice routing occurs.
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 Giraffe.
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.