How To Build a Group SMS Application with ASP.NET MVC
We present a very good test application here and we are sure it will add a plus to your knowledge.
Build Your Own Group Messaging App
With Twilio’s REST API it’s easy to send text messages to any number of recipients. We’ve put together an example demonstrating how to build a simple group messaging application. The example uses ASP.NET MVC and C# but the concepts can be easily applied to any other framework. Below we’ll discuss how to process incoming messages, handle subscribe and unsubscribe requests, and most importantly, forward messages from group members to the rest of the group.
In our group SMS app, members can join the group by texting START to your group 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, send STOP.
Group SMS Messaging Concepts
This example demonstrates receiving an incoming SMS via a POST request to your SMS URL, sending SMS messages to group members via the REST API and responding to the sender using a plain-text response to the incoming message HTTP request.
Implementation Overview
- An SMS message is sent to your Twilio phone number
- Twilio sends a POST request to your phone number’s SMS URL (for this example it would be http://example.com/IncomingMessage).
- The message processor checks the message body for a command like START or STOP and changes the member’s group membership accordingly (the member list is stored in a database).
- If the message contains any other content and the sender is a member of the group, forward the included message to all other members via the Twilio REST API.
- Respond to the original sender with a confirmation message of the action taken.
Technical Requirements
This example was built with Visual Studio 2010, .NET 4, ASP.NET MVC 2, LINQ to SQL and SQL Server Express 2008. The code will work with a Visual Studio 2008, .NET 3.5 SP1 and ASP.NET MVC 1 project as well. This example also uses the TwilioRest C# SDK which can be found at http://github.com/twilio/twilio-csharp
Download
Setup
For this example we’re using a simple LINQ to SQL class. You don’t have to use LINQ to SQL; any .NET data access strategy will work. Just replace the calls to the database with the equivalents in your favorite ORM. A sample database and .dbml file are included in the download.
1
2
3
4
|
CREATE TABLE [Member] ( [MemberId] [ int ] IDENTITY(1,1) NOT NULL , [PhoneNumber] [nvarchar](50) NULL ) |
In one of your controllers, create an action method to receive the SMS messages. Here’s a sample controller structure that also includes a LINQ-to-SQL DataContext for easy reference. We’ll fill in the contents of IncomingMessage below with our message processing logic.
1
2
3
4
5
6
7
8
9
|
public class HomeController : Controller { GroupSmsDataContext DB = new GroupSmsDataContext(); [HttpPost] // or [AcceptVerbs(HttpVerbs.Post)] in MVC1 public ActionResult IncomingMessage( string From, string To, string Body) { return View(); } } |
Update your routes to allow this action to be accessed at /IncomingMessage:
1
2
3
4
|
public static void RegisterRoutes(RouteCollection routes) { routes.MapRoute( "Default" , "{action}" , new { controller = "Home" , action = "Index" } ); } |
Message Handling
All of our message processing will be handled inside the IncomingMessage action method.
When Twilio makes the POST request to your SMS URL it includes three values (To, From, Body) which will be bound by ASP.NET MVC to the appropriate method parameter. Once we know who the message is from, where it’s going and what it contains we can process it.
We first check for a join or leave command. If the contents of the message are one of the four supported commands, we add or remove the number from the group accordingly.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public ActionResult IncomingMessage( string From, string To, string Body) { string response; switch (Body.ToLowerInvariant().Trim()) { case "start" : case "join" : // subscribe member AddMemberToGroup(From); response = "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 = "SYSTEM: See ya later alligator." ; break ; |
If the message contains any other content we want to 1) check to see if they’re a member of the group already and 2) if so, forward the message on to all other members in the group.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
default : // prevent non-members from sending messages to the group var member = DB.Members.FirstOrDefault(m => m.PhoneNumber == From); if (member == null ) { response = "SYSTEM: Send START to send/receive messages from this group" ; break ; } // set up the Twilio client var accountSid = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ; // TODO: replace with your account ID var secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ; // TODO: replace with your key var account = new TwilioRest.Account(accountSid, secretKey); // grab all the members of the group, except the sender var members = DB.Members.Where(m => m.MemberId != member.MemberId).ToList(); foreach (var recipient in members) { // send the message to each member var url = string .Format( "/2008-08-01/Accounts/{0}/SMS/Messages" , accountSid); var values = new Hashtable(); values.Add( "To" , recipient.PhoneNumber); values.Add( "From" , To); values.Add( "Body" , From + ": " + Body.Trim()); account.request(url, "POST" , values); } response = string .Format( "SYSTEM: Message sent to {0} members" , members.Count); break ; } |
Lastly we respond back to the sender by outputting some plain text which Twilio reads and sends via SMS to the original sender.
1
2
3
|
// respond with confirmation message return Content(response, "text/plain" ); } |
The membership management methods are implemented as follows. You can replace this implementation with the data access method of your choice.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
private void RemoveMemberFromGroup( string phoneNumber) { // retrieve member for this phone number var member = DB.Members.FirstOrDefault(m => m.PhoneNumber == phoneNumber); // if they exist, delete them from the database if (member != null ) { DB.Members.DeleteOnSubmit(member); DB.SubmitChanges(); } } private void AddMemberToGroup( string phoneNumber) { // retrieve member for this phone number var member = DB.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; DB.Members.InsertOnSubmit(member); DB.SubmitChanges(); } |
Next Steps
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
Courtesy : Twilio