C# backend for web-based chat application that features Catapult SMS and MMS capabilities.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


C Sharp Web SMS Chat

This application is outdated, but will be updated soon!

C# backend for web-based chat application that features Catapult SMS and MMS capabilities


  • Configured Machine with Ngrok/Port Forwarding -OR- Azure Account
  • Visual Studio 2015
  • Git
  • Common Azure Tools for Visual Studio (they are preinstalled with Visual Studio)

Build and Deploy

Azure One Click

Deploy to Azure

How it works


Routes.cs contains, well, the routes for the application.

There are two main endpoints:

  • post /upload add media to Catapult
  • post /{userId}/callback callback URL for catapult events

Grab client and upload media to catapult

Post["/upload", true] = async (c, t) =>
  Debug.Print("Uploading file");
  var file = Request.Files.First();
  var fileName = Guid.NewGuid().ToString("N");
  var serializer = new JavaScriptSerializer();
  var auth = serializer.Deserialize<Dictionary<string, string>>(Request.Headers.Authorization);
  var client = new Client(auth["UserId"], auth["ApiToken"], auth["ApiSecret"]);
  await client.Media.UploadAsync(new UploadMediaFileData
    MediaName = fileName,
    Stream = file.Value,
    ContentType = file.ContentType
  return new Dictionary<string, string>
    {"fileName", fileName}

Each user has their own callback path from catapult

Post["/{userId}/callback", true] = async (c, t) =>
  var userId = (string) c.UserId;
  Debug.Print("Handling Catapult callback for user Id {0}", userId);
  using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
    var json = await reader.ReadToEndAsync();
    Debug.Print("Data from Catapult for {0}: {1}", userId, json);
    var serializer = new JavaScriptSerializer();
    var data = serializer.DeserializeObject(json);
    WebSocketHandler[] sockets;
    lock (WebSocketSmsChatHandler.ActiveSockets)
      sockets = WebSocketSmsChatHandler.ActiveSockets.ToArray();
    foreach (var socket in sockets.Where(s => (string) s.WebSocketContext.Items["userId"] == userId))
      Debug.Print("Sending Catapult data to websocket client");
      socket.EmitEvent("message", data);
    return "";


WebSocketSmsChatHandler.cs contains all the information shuttled between the client and Server

Check if application already exists for user

var applicationId =
            (client.Application.List(new ApplicationQuery {Size = 1000})
               .FirstOrDefault(a => a.Name == applicationName) ?? new Application()).Id;
if (applicationId == null)
  applicationId = await client.Application.CreateAsync(new CreateApplicationData
    Name = applicationName,
    IncomingMessageUrl = $"{baseUrl}{userId}/callback"

Check if phone number exists for user, if not create new number

Debug.Print("Getting phone number");
var phoneNumber = (client.PhoneNumber.List(new PhoneNumberQuery
  ApplicationId = applicationId,
  Size = 1
}).FirstOrDefault() ?? new PhoneNumber()).Number;
var number = "";
if (phoneNumber == null)
  Debug.Print("Reserving new phone number");
  number = (await client.AvailableNumber.SearchLocalAsync(new LocalNumberQuery
    City = "Cary",
    State = "NC",
    Quantity = 1
  await client.PhoneNumber.CreateAsync(new CreatePhoneNumberData
    ApplicationId = applicationId,
    Number = number

Messages are stored on catapult, so we need to fetch those

{"getMessages", async (message, socket) =>
    var client = GetCatapultClient(message);
    var data = (Dictionary<string, object>) message["Data"];
    var outMessages = client.Message.List(new MessageQuery
      Size = 1000,
      Direction = MessageDirection.Out,
      From = data["PhoneNumber"] as string
    var inMessages = client.Message.List(new MessageQuery
      Size = 1000,
      Direction = MessageDirection.In,
      To = data["PhoneNumber"] as string
    var messages = inMessages.Concat(outMessages).OrderBy(m => m.Time).Select(m => m.ToDictionary());
    socket.WebSocketContext.Items["userId"] = (string)((Dictionary<string, object>)message["Auth"])["UserId"];
    return messages;

How to send a messages

{"sendMessage", async (message, socket) =>
    var client = GetCatapultClient(message);
    var data = (Dictionary<string, object>) message["Data"];
    var messageId = await client.Message.SendAsync(new MessageData
      From = data["from"] as string,
      To = data["to"] as string,
      Text = data["text"] as string,
      Media = data["media"] as string[]
    var newMessage = await client.Message.GetAsync(messageId);
    socket.WebSocketContext.Items["userId"] = (string)((Dictionary<string, object>)message["Auth"])["UserId"];
    return newMessage.ToDictionary();


Clone the web application.

git clone https://github.com/BandwidthExamples/csharp-web-sms-chat.git

Open solution file in Visual Studio and build it.

You can run compiled C# code with IIS Express on local machine if you have ability to handle external requests or use any external hosting (like Azure).

Note: If you are going to use Azure as hosting please after deployment open this site in Azure Management Console, select app settings and switch on Web Sockets. Otherwise the app will not work correctly.