Instant Lead Alerts with Python and Flask

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 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 Python and Flask application.

Lead Alerts Flow

We'll be implementing instant lead alerts for a fictional real estate company.

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

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

Let's see how it works!  Click the below button to begin.

Populate a Landing Page

To display a landing page for our house, we first need to add some data so the customers can see if it's a good fit.

For demonstration purposes we've hard-coded a dictionary containing information we need.

Loading Code Samples...
Language
from lead_alerts import app
from flask import flash, redirect, render_template, request
from twilio.base.exceptions import TwilioRestException


from .services.twilio_service import TwilioService

@app.route('/')
def index():
    house = {
                'title': '555 Sunnybrook Lane',
                'price': '$349,999',
                '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 render_template('index.html', house=house)

@app.route('/notifications', methods=['POST'])
def create():
    house_title = request.form["house_title"]
    name = request.form["name"]
    phone = request.form["phone"]
    message = request.form["message"]

    twilio_service = TwilioService()

    formatted_message = build_message(house_title, name, phone, message)
    try:
        twilio_service.send_message(formatted_message)
        flash('Thanks! An agent will be contacting you shortly', 'success')
    except TwilioRestException as e:
        print(e)
        flash('Oops! There was an error. Please try again.', 'danger')

    return redirect('/')

def build_message(house_title, name, phone, message):
    template = 'New lead received for {}. Call {} at {}. Message {}'
    return template.format(house_title, name, phone, message)
lead_alerts/views.py
Set up routes to render house details and qualify leads

lead_alerts/views.py

Let's look at how to render the page next.

Render a Landing Page

In our template we insert data about the house and in a sidebar we'll include a form for our home-shopping user.

Here an interested shopper would enter their contact information to request more info about the home.

Loading Code Samples...
Language
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Lead Alerts</title>

    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
    <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet">
    <link href="/static/stylesheets/main.css" rel="stylesheet">
</head>
<body>
    <div id="main" class="container">
        {% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
                <div class="alert alert-{{ messages.0.0 }}" role="alert">
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                    {% for category, message in messages %}
                        {{ message }} </br>
                    {% endfor %}
                </div>
            {% endif %}
        {% endwith %}
        <div class="row">
            <div class="col-sm-8">
                <h1>{{house.title}}</h1>
                <h3>{{house.price}}</h3>
                <img src="/static/images/house.jpg" alt="House" />
                <p>{{house.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>
                <form action="/notifications" method="POST">
                    <input type="hidden" name="house_title" value="{{house.title}}" />
                    <div class="form-group">
                        <label for="name">Your Name</label>
                        <input type="text" id="name" name="name" class="form-control" placeholder="John Appleseed" />
                    </div>
                    <div class="form-group">
                        <label for="phone">Your Phone Number</label>
                        <input type="text" id="phone" name="phone" class="form-control" placeholder="+16512229988" />
                    </div>
                    <div class="form-group">
                        <label for="message">How can we help?</label>
                        <input type="text" id="message" name="message" class="form-control" />
                    </div>
                    <button type="submit" class="btn btn-primary">Request Info</button>
                </form>
            </div>
        </div>
    </div>
    <footer class="container">
        Made with <i class="fa fa-heart"></i> by your pals <a href="http://www.twilio.com">@twilio</a>.
    </footer>
    <script src="//code.jquery.com/jquery-2.1.4.js"></script>
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</body>
</html>
lead_alerts/templates/index.html
Home landing page template

lead_alerts/templates/index.html

Next, let's see how to initialize our Twilio Client for use later on.

Initialize the Twilio REST API Client

Now we need to create 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 stored as environment variables.  You can find the Auth Token and Account SID in the console:

console credentials

Loading Code Samples...
Language
from lead_alerts import app
from twilio.rest import Client

class TwilioService:
    client = None

    def __init__(self):
        # Find these values at https://twilio.com/user/account
        account_sid = app.config['TWILIO_ACCOUNT_SID']
        auth_token = app.config['TWILIO_AUTH_TOKEN']
        self.client = Client(account_sid, auth_token)

    def send_message(self, message):
        agent_phone_number = app.config['AGENT_PHONE_NUMBER']
        twilio_phone_number = app.config['TWILIO_PHONE_NUMBER']
        self.client.messages.create(to=agent_phone_number,
                                    from_=twilio_phone_number,
                                    body=message)
lead_alerts/services/twilio_service.py
Wrap the Twilio REST Client to simplify message sending

lead_alerts/services/twilio_service.py

Next up, let's see how to handle an incoming lead.

Handle the POST Request

This code handles the HTTP POST request triggered by the user from our landing page.

It uses our TwilioService class to send an SMS message to the real estate agent's phone number, which is also set as a environment variable. We include the lead's name, phone number, and inquiry directly in the body of the text message sent to the agent.

Now the agent has all the information they need to follow up on the lead!

Loading Code Samples...
Language
from lead_alerts import app
from flask import flash, redirect, render_template, request
from twilio.base.exceptions import TwilioRestException


from .services.twilio_service import TwilioService

@app.route('/')
def index():
    house = {
                'title': '555 Sunnybrook Lane',
                'price': '$349,999',
                '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 render_template('index.html', house=house)

@app.route('/notifications', methods=['POST'])
def create():
    house_title = request.form["house_title"]
    name = request.form["name"]
    phone = request.form["phone"]
    message = request.form["message"]

    twilio_service = TwilioService()

    formatted_message = build_message(house_title, name, phone, message)
    try:
        twilio_service.send_message(formatted_message)
        flash('Thanks! An agent will be contacting you shortly', 'success')
    except TwilioRestException as e:
        print(e)
        flash('Oops! There was an error. Please try again.', 'danger')

    return redirect('/')

def build_message(house_title, name, phone, message):
    template = 'New lead received for {}. Call {} at {}. Message {}'
    return template.format(house_title, name, phone, message)
lead_alerts/views.py
Set up routes to render house details and qualify leads

lead_alerts/views.py

That's it! We've just implemented an application to instantly route leads to sales people using text messages.

Next, let's look at some other easy to add features for your application.

Where to Next?

We love Python here at Twilio - here are some other Python tutorials we've written:

Appointment Reminders

Learn to implement appointment reminders on your web app with Twilio, and cut down on the no-shows.

Two-Factor Authentication with Authy

Learn to implement two-factor authentication (2FA) on your web app with Twilio-powered Authy.

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
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...
from lead_alerts import app
from flask import flash, redirect, render_template, request
from twilio.base.exceptions import TwilioRestException


from .services.twilio_service import TwilioService

@app.route('/')
def index():
    house = {
                'title': '555 Sunnybrook Lane',
                'price': '$349,999',
                '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 render_template('index.html', house=house)

@app.route('/notifications', methods=['POST'])
def create():
    house_title = request.form["house_title"]
    name = request.form["name"]
    phone = request.form["phone"]
    message = request.form["message"]

    twilio_service = TwilioService()

    formatted_message = build_message(house_title, name, phone, message)
    try:
        twilio_service.send_message(formatted_message)
        flash('Thanks! An agent will be contacting you shortly', 'success')
    except TwilioRestException as e:
        print(e)
        flash('Oops! There was an error. Please try again.', 'danger')

    return redirect('/')

def build_message(house_title, name, phone, message):
    template = 'New lead received for {}. Call {} at {}. Message {}'
    return template.format(house_title, name, phone, message)
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Lead Alerts</title>

    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
    <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet">
    <link href="/static/stylesheets/main.css" rel="stylesheet">
</head>
<body>
    <div id="main" class="container">
        {% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
                <div class="alert alert-{{ messages.0.0 }}" role="alert">
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                    {% for category, message in messages %}
                        {{ message }} </br>
                    {% endfor %}
                </div>
            {% endif %}
        {% endwith %}
        <div class="row">
            <div class="col-sm-8">
                <h1>{{house.title}}</h1>
                <h3>{{house.price}}</h3>
                <img src="/static/images/house.jpg" alt="House" />
                <p>{{house.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>
                <form action="/notifications" method="POST">
                    <input type="hidden" name="house_title" value="{{house.title}}" />
                    <div class="form-group">
                        <label for="name">Your Name</label>
                        <input type="text" id="name" name="name" class="form-control" placeholder="John Appleseed" />
                    </div>
                    <div class="form-group">
                        <label for="phone">Your Phone Number</label>
                        <input type="text" id="phone" name="phone" class="form-control" placeholder="+16512229988" />
                    </div>
                    <div class="form-group">
                        <label for="message">How can we help?</label>
                        <input type="text" id="message" name="message" class="form-control" />
                    </div>
                    <button type="submit" class="btn btn-primary">Request Info</button>
                </form>
            </div>
        </div>
    </div>
    <footer class="container">
        Made with <i class="fa fa-heart"></i> by your pals <a href="http://www.twilio.com">@twilio</a>.
    </footer>
    <script src="//code.jquery.com/jquery-2.1.4.js"></script>
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</body>
</html>
from lead_alerts import app
from twilio.rest import Client

class TwilioService:
    client = None

    def __init__(self):
        # Find these values at https://twilio.com/user/account
        account_sid = app.config['TWILIO_ACCOUNT_SID']
        auth_token = app.config['TWILIO_AUTH_TOKEN']
        self.client = Client(account_sid, auth_token)

    def send_message(self, message):
        agent_phone_number = app.config['AGENT_PHONE_NUMBER']
        twilio_phone_number = app.config['TWILIO_PHONE_NUMBER']
        self.client.messages.create(to=agent_phone_number,
                                    from_=twilio_phone_number,
                                    body=message)
from lead_alerts import app
from flask import flash, redirect, render_template, request
from twilio.base.exceptions import TwilioRestException


from .services.twilio_service import TwilioService

@app.route('/')
def index():
    house = {
                'title': '555 Sunnybrook Lane',
                'price': '$349,999',
                '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 render_template('index.html', house=house)

@app.route('/notifications', methods=['POST'])
def create():
    house_title = request.form["house_title"]
    name = request.form["name"]
    phone = request.form["phone"]
    message = request.form["message"]

    twilio_service = TwilioService()

    formatted_message = build_message(house_title, name, phone, message)
    try:
        twilio_service.send_message(formatted_message)
        flash('Thanks! An agent will be contacting you shortly', 'success')
    except TwilioRestException as e:
        print(e)
        flash('Oops! There was an error. Please try again.', 'danger')

    return redirect('/')

def build_message(house_title, name, phone, message):
    template = 'New lead received for {}. Call {} at {}. Message {}'
    return template.format(house_title, name, phone, message)