Instant Lead Alerts with C# and ASP.NET MVC

Download the Code

You probably already have landing pages or product detail views in your web application which you're using to generate some excellent leads for your business.  Would you like to let the sales team know right away when you've got a new qualified lead?

In this tutorial we'll use Twilio Programmable SMS to send a message when a new lead is found for a C# and ASP.NET MVC application.

Lead Alerts Flow

In this example, we'll be implementing instant lead alerts for real estate.

We'll create a landing page for a new house on the market and notify a real estate agent when a user requests more information.

Learn how Porch uses Twilio SMS to send home contractors instant alerts when they are selected for a new project.

Loading Code Samples...
Language
@model LeadAlerts.Web.ViewModels.Lead

<div class="row">
    <div class="col-sm-8">
        <h1>@ViewBag.Title</h1>
        <h3>@ViewBag.Price</h3>
        <img src="~/Content/Images/house.jpg" alt="House" />
        <p>@ViewBag.Description</p>
    </div>
    <div class="col-sm-2 demo">
        <h4>Talk To An Agent</h4>
        <p>
            A trained real estate professional is standing by to answer any
            questions you might have about this property. Fill out the form below
            with your contact information, and an agent will reach out soon.
        </p>
        @using (Html.BeginForm("Create", "Notifications"))
        {
            @Html.HiddenFor(m => m.HouseTitle)
            <div class="form-group">
                @Html.LabelFor(m => m.Name)
                @Html.TextBoxFor(m => m.Name, new { @class = "form-control", placeholder = "John Appleseed" })
            </div>
            <div class="form-group">
                @Html.LabelFor(m => m.Phone)
                @Html.TextBoxFor(m => m.Phone, new { @class = "form-control", placeholder = "+16512229988" })
            </div>
            <div class="form-group">
                @Html.LabelFor(m => m.Message)
                @Html.TextBoxFor(m => m.Message, new { @class = "form-control" })
            </div>
            <button type="submit" class="btn btn-primary">Request Info</button>
        }
    </div>
</div>
LeadAlerts.Web/Views/Home/Index.cshtml
Landing page template

LeadAlerts.Web/Views/Home/Index.cshtml

Click the button below to begin!

Populate Landing Page Data

To display a landing page for our house, we'll first need some data about the fictional house we've put on the market.

For demonstration purposes, we've hard-coded the information we need as you can see in this code sample.

Loading Code Samples...
Language
using System.Web.Mvc;
using LeadAlerts.Web.ViewModels;

namespace LeadAlerts.Web.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            const string houseTitle = "555 Sunnybrook Lane";
            ViewBag.Title = houseTitle;
            ViewBag.Price = "$349,999";
            ViewBag.Description =
                "You and your family will love this charming home. " +
                "Featuring granite appliances, stainless steel windows, and " +
                "high efficiency dual mud rooms, this joint is loaded to the max. " +
                "Motivated sellers have priced for a quick sale, act now!";

            return View(new Lead {HouseTitle = houseTitle});
        }
    }
}
LeadAlerts.Web/Controllers/HomeController.cs
Default application route to render listing data

LeadAlerts.Web/Controllers/HomeController.cs

Now that we have the route that will provide our data let's look at how we will render it.

Rendering the Landing Page

In our template, we insert data about the house.  

We also put a form into the sidebar so a user can request additional information about the house and provide contact details.

Loading Code Samples...
Language
@model LeadAlerts.Web.ViewModels.Lead

<div class="row">
    <div class="col-sm-8">
        <h1>@ViewBag.Title</h1>
        <h3>@ViewBag.Price</h3>
        <img src="~/Content/Images/house.jpg" alt="House" />
        <p>@ViewBag.Description</p>
    </div>
    <div class="col-sm-2 demo">
        <h4>Talk To An Agent</h4>
        <p>
            A trained real estate professional is standing by to answer any
            questions you might have about this property. Fill out the form below
            with your contact information, and an agent will reach out soon.
        </p>
        @using (Html.BeginForm("Create", "Notifications"))
        {
            @Html.HiddenFor(m => m.HouseTitle)
            <div class="form-group">
                @Html.LabelFor(m => m.Name)
                @Html.TextBoxFor(m => m.Name, new { @class = "form-control", placeholder = "John Appleseed" })
            </div>
            <div class="form-group">
                @Html.LabelFor(m => m.Phone)
                @Html.TextBoxFor(m => m.Phone, new { @class = "form-control", placeholder = "+16512229988" })
            </div>
            <div class="form-group">
                @Html.LabelFor(m => m.Message)
                @Html.TextBoxFor(m => m.Message, new { @class = "form-control" })
            </div>
            <button type="submit" class="btn btn-primary">Request Info</button>
        }
    </div>
</div>
LeadAlerts.Web/Views/Home/Index.cshtml
Render a landing page

LeadAlerts.Web/Views/Home/Index.cshtml

Now that we have rendered our listing let's see how to setup a Twilio REST Client to send messages.

Create a Twilio REST API Client

Here we create a helper class with an authenticated Twilio REST API client that we can use anytime we need to send a text message.

We initialize it with our Twilio account credentials in our Local.config file.  You can find them in the console:

console credentials

 

Credentials and PhoneNumbers are just a thin wrapper for values from Local.config.  Here's how it might look:

public static string AccountSID
{
    get
    {
        return
          WebConfigurationManager.AppSettings["TwilioAccountSid"];
    }
}
Loading Code Samples...
Language
using Twilio.Types;
using Twilio.Rest.Api.V2010.Account;
using System.Threading.Tasks;
using Twilio.Clients;

namespace LeadAlerts.Web.Domain
{
    public interface INotificationService
    {
        Task<MessageResource> SendAsync(string message);
    }

    public class NotificationService: INotificationService
    {
        private readonly TwilioRestClient _client;

        public NotificationService() {
            _client = new TwilioRestClient(Credentials.AccountSID, Credentials.AuthToken);
        }

        public async Task<MessageResource> SendAsync(string message)
        {
            var to = new PhoneNumber(PhoneNumbers.Twilio);
            return await MessageResource.CreateAsync(
                to,
                from: new PhoneNumber(PhoneNumbers.Agent),
                body: message,
                client: _client
            );
        }
    }
}
LeadAlerts.Web/Domain/NotificationService.cs
Send a message with the Twilio Client

LeadAlerts.Web/Domain/NotificationService.cs

Now that our Twilio REST Client is ready, let's see how we handle a new lead.

Handle a POST Request

This code handles the HTTP POST request from our landing page when our customer fills out a form.

It uses our MessageSender class to send a SMS message to the real estate agent's phone number, which is set as an environment variable.

We include the lead's name, phone number, and inquiry directly in the body of the text message we send to the agent.

Loading Code Samples...
Language
using System.Web.Mvc;
using LeadAlerts.Web.Domain;
using LeadAlerts.Web.ViewModels;
using Vereyon.Web;
using System.Threading.Tasks;

namespace LeadAlerts.Web.Controllers
{
    public class NotificationsController : Controller
    {
        private readonly INotificationService _notificationService;

        public NotificationsController() : this(new NotificationService()) { }

        public NotificationsController(INotificationService notificationService)
        {
            _notificationService = notificationService;
        }

        // POST: Notifications/Create
        [HttpPost]
        public async Task<ActionResult> Create(Lead lead)
        {
            var message = await _notificationService.SendAsync(FormatMessage(lead));

            if (message.ErrorCode.HasValue)
            {
                FlashMessage.Danger("Oops! There was an error. Please try again.");
            }
            else
            {
                FlashMessage.Confirmation("Thanks! An agent will be contacting you shortly.");
            }

            return RedirectToAction("Index", "Home");
        }

        private static string FormatMessage(Lead lead)
        {
            return $"New lead received for {lead.HouseTitle}. Call {lead.Name} at {lead.Phone}. Message: {lead.Message}";
        }
    }
}
Uses the MessageSender to send messages to sales team members.
Handling a new Lead

Uses the MessageSender to send messages to sales team members.

That's it!  Now the agent has all the information they need to immediately follow up on the lead.  

We've just implemented an application to instantly route leads to a salesperson using text messages. Let's look at some other possible features for your application on the next slide.

Where to Next?

There's a lot you can build easily with .NET and Twilio!  Here are just a couple ideas for what to do next:

Browser Calls

Twilio Client allows your website users to make and receive phone calls directly from their browsers.

Call Tracking

Call Tracking helps you measure the effectiveness of different marketing campaigns.

Did this help?

Thanks for checking out this tutorial!  Let us know what you've built - or what you're building - on Twitter.

Agustin Camino
Paul Kamp
Hector Ortega
Andrew Baker
Jose Oliveros

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd browsing the Twilio tag on Stack Overflow.

1 / 1
Loading Code Samples...
@model LeadAlerts.Web.ViewModels.Lead

<div class="row">
    <div class="col-sm-8">
        <h1>@ViewBag.Title</h1>
        <h3>@ViewBag.Price</h3>
        <img src="~/Content/Images/house.jpg" alt="House" />
        <p>@ViewBag.Description</p>
    </div>
    <div class="col-sm-2 demo">
        <h4>Talk To An Agent</h4>
        <p>
            A trained real estate professional is standing by to answer any
            questions you might have about this property. Fill out the form below
            with your contact information, and an agent will reach out soon.
        </p>
        @using (Html.BeginForm("Create", "Notifications"))
        {
            @Html.HiddenFor(m => m.HouseTitle)
            <div class="form-group">
                @Html.LabelFor(m => m.Name)
                @Html.TextBoxFor(m => m.Name, new { @class = "form-control", placeholder = "John Appleseed" })
            </div>
            <div class="form-group">
                @Html.LabelFor(m => m.Phone)
                @Html.TextBoxFor(m => m.Phone, new { @class = "form-control", placeholder = "+16512229988" })
            </div>
            <div class="form-group">
                @Html.LabelFor(m => m.Message)
                @Html.TextBoxFor(m => m.Message, new { @class = "form-control" })
            </div>
            <button type="submit" class="btn btn-primary">Request Info</button>
        }
    </div>
</div>
using System.Web.Mvc;
using LeadAlerts.Web.ViewModels;

namespace LeadAlerts.Web.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            const string houseTitle = "555 Sunnybrook Lane";
            ViewBag.Title = houseTitle;
            ViewBag.Price = "$349,999";
            ViewBag.Description =
                "You and your family will love this charming home. " +
                "Featuring granite appliances, stainless steel windows, and " +
                "high efficiency dual mud rooms, this joint is loaded to the max. " +
                "Motivated sellers have priced for a quick sale, act now!";

            return View(new Lead {HouseTitle = houseTitle});
        }
    }
}
@model LeadAlerts.Web.ViewModels.Lead

<div class="row">
    <div class="col-sm-8">
        <h1>@ViewBag.Title</h1>
        <h3>@ViewBag.Price</h3>
        <img src="~/Content/Images/house.jpg" alt="House" />
        <p>@ViewBag.Description</p>
    </div>
    <div class="col-sm-2 demo">
        <h4>Talk To An Agent</h4>
        <p>
            A trained real estate professional is standing by to answer any
            questions you might have about this property. Fill out the form below
            with your contact information, and an agent will reach out soon.
        </p>
        @using (Html.BeginForm("Create", "Notifications"))
        {
            @Html.HiddenFor(m => m.HouseTitle)
            <div class="form-group">
                @Html.LabelFor(m => m.Name)
                @Html.TextBoxFor(m => m.Name, new { @class = "form-control", placeholder = "John Appleseed" })
            </div>
            <div class="form-group">
                @Html.LabelFor(m => m.Phone)
                @Html.TextBoxFor(m => m.Phone, new { @class = "form-control", placeholder = "+16512229988" })
            </div>
            <div class="form-group">
                @Html.LabelFor(m => m.Message)
                @Html.TextBoxFor(m => m.Message, new { @class = "form-control" })
            </div>
            <button type="submit" class="btn btn-primary">Request Info</button>
        }
    </div>
</div>
using Twilio.Types;
using Twilio.Rest.Api.V2010.Account;
using System.Threading.Tasks;
using Twilio.Clients;

namespace LeadAlerts.Web.Domain
{
    public interface INotificationService
    {
        Task<MessageResource> SendAsync(string message);
    }

    public class NotificationService: INotificationService
    {
        private readonly TwilioRestClient _client;

        public NotificationService() {
            _client = new TwilioRestClient(Credentials.AccountSID, Credentials.AuthToken);
        }

        public async Task<MessageResource> SendAsync(string message)
        {
            var to = new PhoneNumber(PhoneNumbers.Twilio);
            return await MessageResource.CreateAsync(
                to,
                from: new PhoneNumber(PhoneNumbers.Agent),
                body: message,
                client: _client
            );
        }
    }
}
using System.Web.Mvc;
using LeadAlerts.Web.Domain;
using LeadAlerts.Web.ViewModels;
using Vereyon.Web;
using System.Threading.Tasks;

namespace LeadAlerts.Web.Controllers
{
    public class NotificationsController : Controller
    {
        private readonly INotificationService _notificationService;

        public NotificationsController() : this(new NotificationService()) { }

        public NotificationsController(INotificationService notificationService)
        {
            _notificationService = notificationService;
        }

        // POST: Notifications/Create
        [HttpPost]
        public async Task<ActionResult> Create(Lead lead)
        {
            var message = await _notificationService.SendAsync(FormatMessage(lead));

            if (message.ErrorCode.HasValue)
            {
                FlashMessage.Danger("Oops! There was an error. Please try again.");
            }
            else
            {
                FlashMessage.Confirmation("Thanks! An agent will be contacting you shortly.");
            }

            return RedirectToAction("Index", "Home");
        }

        private static string FormatMessage(Lead lead)
        {
            return $"New lead received for {lead.HouseTitle}. Call {lead.Name} at {lead.Phone}. Message: {lead.Message}";
        }
    }
}