Send wishes using Twilio Voice and SMS with C# and ASP.NET Core

December 12, 2022
Written by
Similoluwa Adegoke
Contributor
Opinions expressed by Twilio contributors are their own
Reviewed by

Send wishes using Twilio Voice and SMS

In the light of the season of giving, you will build an app where users can send in their wishes to your Twilio Phone Number for a special someone, and when that special person dials the number, they can listen to a random wish out of all the wishes that are saved. For example, family members can send in wishes to your Twilio Phone Number and when the kids dial the number, they get to listen to a different wish every time.

In this tutorial, you will build a Web API that serves two webhooks. The first is an SMS webhook that saves the message that is sent to your Twilio Phone Number while the second webhook is a voice webhook that responds to incoming calls and reads out a wish.

Prerequisites

You will need the following things to follow along:

Here is the link to the complete code on GitHub.

Create the Web API

To begin this tutorial, create the Web API project using the following commands:

mkdir WishesApp
cd WishesApp
dotnet new webapi

Then proceed to open it with your code editor.

In the code editor, add an API Controller named WebhookController in the Controllers folder, then add two actions that will serve the webhooks like the code below:

using Microsoft.AspNetCore.Mvc;

namespace WishesApp.Controllers;

[ApiController]
[Route("api/")]
public class WebhookController : ControllerBase
{
    [HttpPost("IncomingMessage")]
    public async Task<IActionResult> IncomingMessage()
    {
        return Ok();
    }

    [HttpPost("WishPlayer")]
    public async Task<IActionResult> WishPlayer()
    {
        return Ok();
    }
}

The IncomingMessage action will respond to the SMS webhook and save every wish that is sent to your Twilio number while the WishPlayer action will respond to the incoming call by playing a random wish.

Create the Webhooks

Configure the database

Install the EF Core packages to save the messages that are received into a database and to retrieve them later:

dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Design

Next, you will create a data model and database context to store the messages that are received.Create  WishItem.cs and AppDbContext.cs to define the data model and database context respectively. Update WishItem.cs with the following code:

namespace WishesApp;

public class WishItem
{
    public int Id { get; set; }
    public string Message { get; set; }
    public string Sender { get; set; }
}

Update the AppDbContext.cs with the following code:

using Microsoft.EntityFrameworkCore;

namespace WishesApp;

public class AppDbContext : DbContext
{
    public DbSet<WishItem> WishItems { get; set; }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite(connectionString: "Data Source=WishesApp.db");
    }
}

Then run the database migrations command to create the data WishesApp.db database and the WishItems table:

dotnet ef migrations add initialCreation
dotnet ef database update

Finally, register the AppDbContext in the Program.cs file:

using WishesApp;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
builder.Services.AddDbContext<AppDbContext>();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();

Update the SMS webhook

When your Twilio Phone Number receives a message, Twilio will send an HTTP request to a webhook URL that you have configured on the Twilio console. The webhook URL is expected to receive the request from Twilio and respond with instructions written using the Twilio Markup Language (TwiML).

Here is an example of a TwiML that sends an ‘Ahoy!’ message back to a user.

<?xml version="1.0" encoding="utf-8"?>
<Response>
  <Message>Ahoy!</Message>
</Response>

Update the IncomingMessage method with the code below

using Microsoft.AspNetCore.Mvc;
using Twilio.AspNet.Core;
using Twilio.TwiML;

namespace WishesApp.Controllers;

[ApiController]
[Route("api/")]
public class WebhookController : ControllerBase
{
    private readonly AppDbContext _dbContext;
    public WebhookController(AppDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    [HttpPost("IncomingMessage")]
    public async Task<IActionResult> IncomingMessage()
    {
        var form = await Request.ReadFormAsync();
        var body = form["Body"];
        var sender = form["From"];

        _dbContext.WishItems.Add(new WishItem { Message = body, Sender = sender });
        _dbContext.SaveChanges();

        var response = new MessagingResponse();
        response.Message("Thank you for the wish. Happy Holidays!");

        return new TwiMLResult(response);
    }

    [HttpPost("WishPlayer")]
    public IActionResult WishPlayer()
    {
        return Ok();
    }
}

The IncomingMessage action retrieves the Body and From component from the request that is sent by Twilio and saves it to the database. Thereafter a ‘Thank you’ message is sent to acknowledge the wish.

Implement the Voice Webhook.

Just like the TwiML for SMS, there's also TwiML for Voice applications.

You will create the voice webhook that will select a random wish from the database and respond to an incoming call by reading out this wish.

Update the WishPlayer action with the following code:

HttpPost("WishPlayer")]
public IActionResult WishPlayer()
{
    var response = new VoiceResponse();
    
    int savedMessages = _dbContext.WishItems.Count();
    if (savedMessages > 0)
    {
        var rand = new Random().Next(savedMessages);
        string wish = _dbContext.WishItems
            .AsNoTracking()
            .Skip(rand)
            .First()
            .Message;

        response.Say("Reading out a wish for you"

The WishPlayer action retrieves a random wish from the database and replies to the call with a voice prompt that reads the wish. In the event that no wish is present, a welcoming message is used instead.

Configure the Webhooks

To test the webhooks, you need to expose them over the internet and configure the public URLs to your APIs on your Twilio Phone Number.

First, start the app using the following command:

dotnet run

Then expose your local development environment using the ngrok tool. Ngrok is a tool that exposes your local development environment over the internet using a secure tunnel. Run the ngrok command pointing to the same http port that your project is running on.

ngrok http <PORT>

Log on to the Twilio console and select your Account. Click on the Explore Products and select Phone Numbers. Then in the left-side navigation, click on Phone Numbers > Manage > Active Numbers.  

List of Active Phone Numbers on the Twilio Console.

Click the active number you'd like to use which will take you to the configuration page for the phone number.

On the configuration page, scroll to the Voice & Fax Section. The Voice & Fax section will take the WishPlayer webhook which reads out a random wish from the database.  

Under ‘A CALL COMES IN’ set the first dropdown to a Webhook, then into the text box, enter the ngrok Forwarding URL with /api/WishPlayer as the path, and lastly, set the second dropdown to HTTP POST.

Twilio Phone Number Voice and Fax section where you can configure the webhook URL for incoming calls

Next, set up the Messaging Webhook by scrolling down to the Messaging Section. The Messaging section takes the IncomingMessage webhook to save users' wish to a database.

Under ‘A MESSAGE COMES IN’, set the first dropdown to Webhook, then into the text box, enter the ngrok Forwarding URL with /api/IncomingMessage as the path, and lastly, set the second dropdown to HTTP POST.

Twilio Phone Number Messaging section where you can configure the webhook URL for incoming messages.

Click Save to complete the process.

Now, you can proceed to test. Send a text message and thereafter make a call to your Twilio Phone Number to hear the wishes.

Conclusion

In this tutorial, you built an app where well-wishers can send in their wishes to your Twilio Phone Number and the special person(s) who the wish is for can make a call to the phone number to listen to the wish.

You can go on to deploy this app on a cloud service like Azure and share the phone number with other family members so they can send in their wishes. Then you can tell that special someone to dial this Twilio Phone Number and the wishes would play to their ears.

You could improve this application further as a fun exercise by letting the users text a wish for a specific phone number of the loved one, and when the loved one calls, only wishes directed at them will play.

Check out the complete code on GitHub.

Happy holidays!

Similoluwa Adegoke is a software engineer and currently works in the banking industry. When Simi is not coding or writing about it, he is watching tv shows. Simi can be reached at adegokesimi[at]gmail.com