Rewind: Build a Group Messaging Application with ASP.NET MVC

April 22, 2014
Written by

devin-rader-lo-res

Back in 2010 we wrote a post that detailed how to build a simple group messaging application with Twilio and ASP.NET MVC. Well a lot has changed in four years and we wanted to update that post, so in this post I’ll show you how you can use the latest versions of Twilio and ASP.NET MVC to build a simple group messaging application.

I’ll show you how to process incoming messages, handle subscribe and unsubscribe requests, and most importantly, forward messages from group members to the rest of the group.

Note that although I’ll be using ASP.NET MVC to build my application, the concepts I’m showing can easily be applied to just about other programming language or framework.

Group Messaging Concepts

Our simple group messaging application has three basic concepts: group members, commands and messages. In our app, members can join the group by texting the command START to the groups Twilio phone number. After joining the group, any messages sent to the group number will be forwarded to all of the other members. To leave room for the sender’s number in the forwarded message, messages are limited to 140 characters in length. To leave the group, members can send the command STOP.

As users send messages to the groups Twilio phone number, Twilio will initiate a POST request to my ASP.NET MVC application. It is the job of that application to process those messages, either adding or removing members from the group based on the commands outlined above or broadcasting text messages to group members via the REST API. In either case my application will return a response the the original message sender by responding to Twilios POST request with a set of TwiML commands.

The image below shows the basic flow of the application:

6a0105364227ca970b0134800dbbbd970c-800wi

To build this application I’ll use Visual Studio 2013, .NET 4.5, ASP.NET MVC 5 and EntityFramework 6. I’ll also use the Twilio .NET Helper Library which you can find out more about on the Twilio website.

Creating a Backend

For my application I need to store the phone numbers of group members so that as messages arrive I know who I should broadcast them to. For this I’m going create a simple data model using Entity Framework 6 but you can really use any data strategy you want for your application.

When using Entity Framework I’m a fan of using the code-first approach, so I start my data model by creating Database Context class, then a simple Members model class:

public class Member
{
    [Key]
    public int MemberId { get; private set; }

    public string PhoneNumber { get; set; }
}

Thats it for my backend. Entity Framework will take care of creating the actual database for me when I run the application.

Message Handling

Now that I have a backend, I need to create a new MVC Controller and Action Method that will process the incoming POST requests Twilio makes each time it receives a text message. All of our message processing will be handled inside the IncomingMessage action method.

public ActionResult IncomingMessage(string From, string To, string Body)
{
    var response = new TwilioResponse();
            
}

Notice that when I defined the IncomingMessage action method, I included three method parameters: To, From and Body. When Twilio makes its POST request it includes a number of form encoded parameters. Using ASP.NET MVC’s Model Binding feature I can define a set of method parameters whose names match the incoming form encoded paramters and ASP.NET MVC will automatically map those into my method parameters. This allows me to know who the incoming message is from, where it’s going and what it contains so that I can process it.

Processing begins by first checking for one of the four supported commands in the message body. If a supported command is found the application adds or removes the phone number from the group accordingly.

switch (Body.ToLowerInvariant().Trim()) 
{
    case "start":
    case "join":
        // subscribe member
        AddMemberToGroup(From);
        response.Message("SYSTEM: Welcome to the club :) Keep those messages under 140 characters! Send STOP to leave.");
        break;
    case "stop":
    case "leave":
        // unsubscribe member
        RemoveMemberFromGroup(From);
        response.Message("SYSTEM: See ya later alligator.");
        break;
}

The group membership management methods are implemented as follows. You can replace this implementation with the data access method of your choice.

private void RemoveMemberFromGroup(string phoneNumber)
{
    // retrieve member for this phone number
    var member = ctx.Members.FirstOrDefault(m => m.PhoneNumber == phoneNumber);

    // if they exist, delete them from the database
    if (member != null)
    {
        ctx.Members.Remove(member);
        ctx.SaveChanges();
    }
}

private void AddMemberToGroup(string phoneNumber)
{
    // retrieve member for this phone number
    var member = ctx.Members.FirstOrDefault(m => m.PhoneNumber == phoneNumber);

    // if they're already a member, just ignore
    if (member != null) return;

    // add new member to database
    member = new Member();
    member.PhoneNumber = phoneNumber;
    ctx.Members.Add(member);
    ctx.SaveChanges();
}

If the message contains any other content I want to first make sure that the sender is an existing member of the group and if so forward the message on to all other members in the group.

switch (Body.ToLowerInvariant().Trim()) 
{
    case "start":
    case "join":
        // subscribe member
        AddMemberToGroup(From);
        response.Message("SYSTEM: Welcome to the club :) Keep those messages under 140 characters! Send STOP to leave.");
        break;
    case "stop":
    case "leave":
        // unsubscribe member
        RemoveMemberFromGroup(From);
        response.Message("SYSTEM: See ya later alligator.");
        break;
    default:
        // prevent non-members from sending messages to the group
        var member = ctx.Members.FirstOrDefault(m => m.PhoneNumber == From);
        if (member == null)
        {
            response.Message("SYSTEM: Send START to send/receive messages from this group");
            break;
        }

        // set up the Twilio client
        var client = new TwilioRestClient(Credentials.AccountSid, Credentials.AuthToken);

        // grab all the members of the group, except the sender
        var members = ctx.Members.Where(m => m.MemberId != member.MemberId).ToList();
        foreach (var recipient in members) 
        {
            var result = client.SendMessage(
                recipient.PhoneNumber,
                To,
                From + ": " + Body.Trim()
            );

        }

        response.Message(string.Format("SYSTEM: Message sent to {0} members", members.Count));
        break;
}

Finally, I want to let the original sender know that i’ve processed their message which I do by responding to Twilios POST request with some TwiML. Twilio then executes that TwiML sending a response text message to the original sender.

return TwiML(response);

That’s it, you’re done!

As I’ve shown in this post, it’s super easy to build a group messaging application with Twilio and ASP.NET MVC. If you want to set this sample up to use for yourself, check out the source available on GitHub. Its easy to create a free Twilio account and start chatting away!

Of course there are a lot of ways you can extend this application. Here are a couple ideas to get you started:

  • Require a PIN to join the group
  • Allow members to set a display name
  • Handle messages longer than 140 characters
  • Add an option to mute messages for X hours
  • Allow members to specify quiet hours

I’d love to know how you’re using Twilio to create your own group messaging applications, so hit me up on email or twitter with your ideas.