Build ETA Notifications with Twilio SMS

Companies like Uber, TaskRabbit, and Instacart use ETA Notifications to keep their customers up to date on the status of their order or request. More and more services rely on SMS as the primary way of communicating with their customers for on-demand purchases.

The key to those services working? Notifying customers when things change.

In this tutorial, we'll build a notification system for Laundr.io, a fictional on-demand laundry service. You'll learn how to set up Twilio's REST client, handle notification triggers, send your SMS notification, and handle a callback from Twilio.

Loading Code Samples...
Language
from eta_notifications_flask import app, db
from flask import url_for, flash, redirect, render_template, request
from twilio.rest import Client

from eta_notifications_flask.models import Order

def _send_sms_notification(to, message_body, callback_url):
    account_sid = app.config['TWILIO_ACCOUNT_SID']
    auth_token = app.config['TWILIO_AUTH_TOKEN']
    twilio_number = app.config['TWILIO_NUMBER']
    client = Client(account_sid, auth_token)
    client.messages.create(to=to,
                           from_=twilio_number,
                           body=message_body,
                           status_callback=callback_url)

@app.route('/')
def home():
    return render_template('home.html')

@app.route('/orders')
def order_index():
    orders = Order.query.all()

    return render_template('index.html', orders=orders)

@app.route('/order/<order_id>')
def order_show(order_id):
    order = Order.query.get(order_id)

    return render_template('show.html', order=order)

@app.route('/order/<order_id>/pickup', methods=["POST"])
def order_pickup(order_id):
    order = Order.query.get(order_id)
    order.status = 'Shipped'
    order.notification_status = 'queued'
    db.session.commit()

    callback_url = request.base_url.replace('/pickup', '') + '/notification/status/update'
    _send_sms_notification(order.customer_phone_number,
                          'Your laundry is done and on its way to you!',
                          callback_url)

    return redirect(url_for('order_show', order_id=order_id))

@app.route('/order/<order_id>/deliver', methods=["POST"])
def order_deliver(order_id):
    order = Order.query.get(order_id)
    order.status = 'Delivered'
    order.notification_status = 'queued'
    db.session.commit()

    callback_url = request.base_url.replace('/deliver', '') + '/notification/status/update'
    _send_sms_notification(order.customer_phone_number,
                          'Your laundry is arriving now.',
                          callback_url)

    return redirect(url_for('order_index'))

@app.route('/order/<order_id>/notification/status/update', methods=["POST"])
def order_deliver_status(order_id):
    order = Order.query.get(order_id)
    order.notification_status = request.form['MessageStatus']
    db.session.commit()

    return render_template('show.html', order=order)
eta_notifications_flask/views.py
Send SMS notification on delivery

eta_notifications_flask/views.py

Find your language and framework of choice below to get to the source code in your language and follow step-by-step instructions to learn how to build ETA notifications yourself:

Happy building!

Kat King

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.

Loading Code Samples...
from eta_notifications_flask import app, db
from flask import url_for, flash, redirect, render_template, request
from twilio.rest import Client

from eta_notifications_flask.models import Order

def _send_sms_notification(to, message_body, callback_url):
    account_sid = app.config['TWILIO_ACCOUNT_SID']
    auth_token = app.config['TWILIO_AUTH_TOKEN']
    twilio_number = app.config['TWILIO_NUMBER']
    client = Client(account_sid, auth_token)
    client.messages.create(to=to,
                           from_=twilio_number,
                           body=message_body,
                           status_callback=callback_url)

@app.route('/')
def home():
    return render_template('home.html')

@app.route('/orders')
def order_index():
    orders = Order.query.all()

    return render_template('index.html', orders=orders)

@app.route('/order/<order_id>')
def order_show(order_id):
    order = Order.query.get(order_id)

    return render_template('show.html', order=order)

@app.route('/order/<order_id>/pickup', methods=["POST"])
def order_pickup(order_id):
    order = Order.query.get(order_id)
    order.status = 'Shipped'
    order.notification_status = 'queued'
    db.session.commit()

    callback_url = request.base_url.replace('/pickup', '') + '/notification/status/update'
    _send_sms_notification(order.customer_phone_number,
                          'Your laundry is done and on its way to you!',
                          callback_url)

    return redirect(url_for('order_show', order_id=order_id))

@app.route('/order/<order_id>/deliver', methods=["POST"])
def order_deliver(order_id):
    order = Order.query.get(order_id)
    order.status = 'Delivered'
    order.notification_status = 'queued'
    db.session.commit()

    callback_url = request.base_url.replace('/deliver', '') + '/notification/status/update'
    _send_sms_notification(order.customer_phone_number,
                          'Your laundry is arriving now.',
                          callback_url)

    return redirect(url_for('order_index'))

@app.route('/order/<order_id>/notification/status/update', methods=["POST"])
def order_deliver_status(order_id):
    order = Order.query.get(order_id)
    order.notification_status = request.form['MessageStatus']
    db.session.commit()

    return render_template('show.html', order=order)