How to Send Daily SMS Reminders Using C#, Azure Functions and Twilio
Time to read: 6 minutes
Are you remembering to keep up with your New Year’s Resolutions? Using C#, Azure Functions and Twilio we’ll build a service that delivers daily SMS reminders to help keep up with those new goals.
Recipe
Here’s a list of the things we’ll use in the creation of our reminder service:
- Free Twilio account – sign up for one here
- SMS enabled phone number – you can find the perfect one for your needs here
- Microsoft Azure account
- Visual Studio 2015 (while it is possible to work on Azure Functions directly in the web portal, the developer experience is better in VS2015)
- Microsoft Azure SDK for VS 2015
- Visual Studio Tools for Azure Functions
- Microsoft Azure Storage Explorer
Set up your accounts and install any of the software you don’t have before moving on.
Structuring the Reminder Service
Azure Functions make it easy to quickly create the type of service we’re building. It’s “serverless” which means we don’t have to worry about web server architecture. Instead, we can just focus on the small bits of code or “functions” that make our service work.
We’ll create one function that handles receiving SMS messages from Twilio. When it receives a request from Twilio it will create a record in an Azure Table if the text message contains “subscribe”. A second function will fire once a day to send an SMS reminder to each number in the Azure table.
Simple enough? Let’s get started.
Handling Subscription Requests
Create a new Project in Visual Studio 2015 and search the installed templates for “Azure Functions”:
Name your project
DailySmsReminders
and click OK
.
Before we add our functions, let’s configure the app settings. Open appsettings.json
and replace its contents with the following:
The UseDevelopmentStorage=true
setting on line 4 makes it so that our project will use the Azure Storage Emulator any time we make a request to use Azure storage. Make sure to replace the Twilio credentials with your actual values.
Next, right-click on the DailySmsReminders
project and select Add->New Azure Function…
:
The dialog that pops up contains a lot of options. These represent the various ways an Azure function can be triggered. For instance, a function can be triggered when something is added to a queue using a
QueueTrigger
. Read more about what types of triggers are available here. Our first function will need to run when an HTTP request is made to it. The HTTPTrigger - C#
option is perfect for this. Select this option, name the function InboundSmsTrigger
and click Create
:Edit InboundSmsTriggerproject.json
to add a dependency on Twilio.Twiml
which we’ll use to return TwiML to Twilio when a text message comes in:
The InboundSmsTriggerfunction.json
file is used to configure bindings for our function. The two existing bindings specified in the file correspond to the inbound HTTP request and the return from the function. We need to add a binding for the Azure Table we’ll use to store our records. Edit function.json
so that it looks like this:
In the highlighted lines we’ve added a table binding with a tableName
of Reminder
and set the connection for the table to the Azure Storage Emulator.
The function’s code can be found in InboundSmsTriggerrun.csx
. Delete what’s there and replace it with the following code:
On lines 1-2 we pull in references for Microsoft.WindowsAzure.Storage
and System.Runtime
. These are special case external assemblies that can be referenced in this way. There’s a full list in the documentation.
Line 10 adds a CloudTable table
parameter to the function that corresponds to the table binding we added to function.json
. This gives us access to the Reminder
table in Azure Storage.
The Reminder
class at the bottom is a TableEntity
subclass that we will use to store records in Azure Table Storage. The class contains a PartitionKey
which we’ll always set to Reminders
and a RowKey
which we’ll use for storing the user’s phone number to send reminders to later.
The HTTP request from Twilio will contain form data in the body of the request that contains the parameters such as Body
and To
/From
phone numbers. Let’s add some code to parse those into a Dictionary
and store the body of the message and the phone number the text message was sent from:
We also created a TwilioResponse
object that will be used to return TwiML to Twilio.
If the user sends a message that contains anything other than subscribe
we’ll want to send back a message letting them know about the keyword. Let’s set that up by adding the following code:
When we parsed the Body
value using System.Uri.UnescapeDataString
. Any spaces in the string will be left as +
signs. The highlighted line trims any +
signs from the beginning and end of the body
value, makes it lowercase, and compares it against subscribe
.
The bulk of the work for the function occurs when the text message body is subscribe
. Add this code to that block:
Lines 1 and 2 look in the Reminder
table for an entry that corresponds to the PartitionKey of Reminders
and the RowKey of phoneNumber
. If the result exists then we set the response message in line 6 to let the user know they’re already subscribed. If they’re not subscribed already then on line 10 we let the user know they are subscribed and the rest of the code in this block executes an insert operation to add their phone number to the table.
All that’s left to do is return an HttpResponse
from the function. We’ll return the response
TwiML as application/xml
using UTF8
encoding with the following code:
Now it’s time to test this function. First we need to start up the Azure Storage Emulator. Search in the Start menu for Azure Storage Emulator and run it. This will open a command prompt window that runs a command to start it:
Once that’s running you can build and run the Azure Functions solution. On first run, it will ask you to install the Azure CLI tools. Do this and then run the project again:
Just under the cool Azure Functions ASCII art you should see a localhost
URL with a port number. You’ll need to use something like ngrok to forward this localhost port to the Internet so that Twilio can make an HTTP request to it. You can use this guide if you’re unsure how to set this up. A quick and easy way to get ngrok running from Visual Studio is this very handy ngrok extension.
Head over to your Twilio phone number and configure the A Message comes in
webhook to point to https://[your ngrok url]/api/InboundSmsTrigger
and click Save
.
Test the inbound trigger by sending SMS messages. Try sending something that’s not subscribe
then send subscribe
and finally try subscribing again. Now that we have subscriptions, let’s send the reminders.
Don’t Forget, Send Daily SMS Reminders!
Add another Azure Function to the project. This time select TimerTrigger - C#
and name the function SendSmsReminders
. A timer trigger will fire according to a schedule determined by a cron
expression in the function.json
file. The cron expression has six fields: {second} {minute} {hour} {day} {month} {day of the week}
. For example, a cron expression that will trigger at 10:00:00 AM in the Eastern US time zone every day would look like this: 0 0 15 * * *
. Modify SendSmsRemindersfunction.json
to contain this cron expression and also add a table binding like we did in the previous function:
Next, add a Twilio
dependency to SendSmsRemindersproject.json
:
Now we’re ready to send the reminders. Open up SendSmsRemindersrun.csx
and replace the contents with this code which references the Twilio and Azure Storage assemblies and adds the CloudTable binding to the parameter list:
Inside the Run
function we’ll start by setting up a TwilioRestClient
:
Next, construct a query over the Reminder
table that matches the Reminders
PartitionKey
. This will return all of the users that have subscribed:
Now that we have all of the entries, loop through each one and send the SMS reminder using the TwilioRestClient
:
To test this out you’ll want to change the cron expression in function.json
to a time a few minutes in the future and then run the project. You should receive an SMS containing the ReminderMessage
when the cron expression evaluates to the time you set. Now you won’t lose track of those resolutions!
What’s Next?
Now that you know how to use C#, Azure Functions and Twilio to send daily SMS reminders, try some of these things as next steps:
- Try deploying the project to Azure. The process is described in this step-by-step guide.
- Modify the service so that the user can specify a custom reminder.
- Learn how to set up appointment reminders in this tutorial
I’m really excited to see what you come up with using these technologies. Let me know what you build by hitting me up on Twitter @brentschooley.
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.