2015-12-14

Looking for a new apartment in your city? Is it election day and you want to remind people to get out and vote? Want to poll residents for the best restaurant in their neighborhood?

In this blog post, we’ll build a messaging application where messages are broadcast to recipients based on the city reported by their browser location. Having everyone in your city join together in a chat application may seem crazy, but buckle up, because we’re going to give it a try. By combining Python, Django, Twilio IP Messaging and the Google Maps API we’ll take our best shot at making it easier to find an apartment, remind your neighbors to vote or poll your fellow city residents.

Tools We’ll Need

Before we dive into building our neighborhood-based chat application, let’s take a look at the tools we’ll be using throughout this blog post.

The 1.9 version of the Django web framework

Twilio Python helper library >= version 5.0.0

A free Twilio account and the Twilio IP Messaging public beta API

Google’s Maps API for determining what city a user is located in

Don’t worry about installing these tools just yet – we’ll handle that in the sections below as we go through this tutorial. If you want to see the completed code from this blog post at any time check out the GitHub repository with the finished project. Before we start writing our code though let’s walk through preparing our Python environment for development.

Python Environment Setup

Our prep work starts with getting our Python development environment ready to build our neighborhood-based chat application. In this section we’ll handle the following steps to make sure you’re ready to run the code:

Check that Python is installed correctly

Set up and activate a new virtualenv

Install required Python dependencies into our virtualenv using pip

Setup Step 1: Check the Python installation

If you’re on Mac OS X or Linux, you’ve already got Python installed on your system. Check the version by going into the terminal and typing python —version. You’ll see the precise version number, something like Python 2.7.6. If you’re on Python 2.6 or greater, you’re good to go.

For Windows, make sure you download and install the Python .exe installation package. Either Python 2 or 3 is fine. If you want further information about the 2 versus 3 version debate, there’s plenty more information written by experienced Python developers on the topic. My recommendation is to use Python 3.5 unless you have a pressing reason to use an earlier version, because the Python community is now migrating to Python 3.

Once Python is installed on your system and you can run it with the python command, we’re ready to set up a virtualenv.

Setup Step 2: Set up a new virtualenv and activate it

Virtualenv is a dependency isolation library that makes it much easier to switch between Python versions and various code packages you’re using on different projects. Create a virtualenv in a location you’ll remember using the following command. In my case, I have a folder called Envs under my home directory that keeps my virtualenvs organized.

We have our virtualenv activated and we should see our command prompt show the name of our virtualenv, such as (citychat)$. With the virtualenv in place and activated, we can use pip to install our dependencies.

Setup Step 3: Install dependencies with pip

pip handles Python library installations. With your virtualenv still activated, run the following command to install our Django and Twilio library dependencies.

You may be able to install the very latest versions of the Django and Twilio packages but it’s preferable to peg dependencies to specific version numbers just in case there are future backwards-incompatible modifications. With those libraries installed, we can start building our Django project that will run the chat application.

Starting Our Django Project

We now have Django installed along with the django-admin command. django-admin helps get the boilerplate directories and code created for our project. Run the following two commands to start the project and change into the newly created directory.

We also need to create an app within the project with the following command.

Django’s just created a whole bunch of files for us. To make sure we’ve got the right set up, ensure the created folders look like the directory and subdirectories in the following image.



We’ll also have __init__.py, settings.py, urls.py and wsgi.py files created for us in the citychat/citychat subdirectory. Our tutorial will modify most of these files along the way. If you’re unfamiliar with why Django created these folders and files be sure to go through the Django quickstart for more context.

We need to modify a few lines in settings.py and set up our environment variables to connect our Django project to our Twilio settings.

Add the following line to the INSTALLED_APPS list in settings.py to add the chat app to our Django project.

Before you close settings.py, append the following lines to the file so we can establish the necessary Twilio IP Messaging settings we’ll use a bit later in the post.

Next we need to set up our environment variables so the os module can get them when our Django project starts up. How to set environment variables depends on your operating system. Here are some handy guides if you’re on Windows, Mac OS X or Ubuntu Linux that’ll help with the specific steps.

Five environment variables will need to be set:

TWILIO_ACCOUNT_SID – found on your Twilio account dashboard

TWILIO_AUTH_TOKEN – also found on your Twilio account dashboard; not required by our Django app but will be used to create the IP Messaging Service SID later

TWILIO_API_KEY – an API key created specifically for this application

TWILIO_API_SECRET – a secret string just for this API key

TWILIO_IPM_SERVICE_SID – a unique identifier registered with Twilio for our IP Messaging application

On Mac OS X and Linux, you can set environment variables with the export shell command. Typically, I store these environment variables in a .env file at the root directory of the project during development. We haven’t yet created the TWILIO_API_KEY, TWILIO_API_SECRET or TWILIO_IPM_SERVICE_SID credentials yet though, so let’s walk through how to create those now.

In order to get chat working we have to handle our remaining environment variables.

Let’s create and then set the TWILIO_API_KEY and TWILIO_API_SECRET now. Head into the Twilio portal and click on Dev Tools in the navigation bar.


Click the Dev Tools link in the top navigation bar. We’re taken to the API Explorer but we want to go to the API Keys page. Click the API Keys link in the secondary nav bar.



Click the “Create an API Key” button. We’re taken to the following page where we can given our new API key a friendly name. Call it “City Chat” and click the “Create API Key” button.

After pressing the “Create API Key” button you’ll be taken to a page with the new Sid and Secret tokens are presented. Make sure to copy the Secret token as it will not be displayed again after you exit from this page.

There’s one more environment variable called TWILIO_IPM_SERVICE_SID that we’ll need to create via the command line before we have everything ready to modify our .env file.

There are two ways to create this IPM Service and grab the SID. One way is to go to the IP Messaging Services page, click the “Create an IP Messaging Service” button, enter a friendly name and let Twilio produce the new service. The second way is to programmatically generate the service via an API call. Let’s use the second method and create the IPM Service from the command line using the following cURL command. The IPM Service we create will include a SID value we need to specify in our TWILIO_IPM_SERVICE_SID environment variable.

Make sure your $TWILIO_ACCOUNT_SID and $TWILIO_AUTH_TOKEN environment variables are still set if you receive an error. If not, your response should look something like the following JSON string.

We need the string that is the value to the “sid” key for our TWILIO_IPM_SERVICE_SID environment variable. With the final value created, we can set all of the environment variables for our application.

It’s time to test out our application to make sure our environment settings are in place and that we’re on a solid foundation to keep coding. From the root directory of our project where manage.py is located, run the Django development server.

With your favorite web browser go to http://127.0.0.1:8000 and you should see the following default success page.

Our basic application files and environment variables are set up. Now let’s build a web page with a map that’ll serve our chat application.

Mapping Our Location

Now we can flesh out the code for our chat app within the citychat Django project. Start by updating the chat/views.py file with the following two highlighted lines. This function will look for the chat.html template and render the template after we create the file.

Create a new file named chat/urls.py with the following code to route our application’s default endpoint to the chat view function we just wrote.

The urls.py file maps routes for our application to views in the views.py file. In our case, there is a single url for the chat function that matches the root url for the server.

In order for the chat/urls.py to be found, we need to update the citychat/citychat/urls.py file, which handles url mappings for every app in a Django project. Update the following two lines so this urls.py file can match with the chat/urls.py routes.

One more file needs to be created then we can give our application a quick test. Create a directory under citychat/chat named templates. Under templates create a file that matches up with the name of the Django template used in the chat function, which in our case is chat.html. Write or copy the following markup into the new chat.html file.

In the above template, we’re setting the stage to display a map showing our current location with a chat box below the map.

There is a referenced JavaScript file, chat.js, that is not hosted externally so it doesn’t exist yet in our Django project. Since that file won’t load our page would look like the screenshot below if we accessed it now. If you pull up http://localhost:8000 in Chrome you can see in the Chrome DevTools that a couple of files are not loading.

We need to fix that missing file to get our map displayed and determine the city in which we should be chatting.

Create a directory under citychat/chat named static that will hold our static files. Under citychat/chat/static create one more subdirectory named js. Create the file named chat.js under citychat/chat/static/js with the following code.

Head back to your web browser and refresh http://localhost:8000/. Make sure to click “Allow” or “Accept” when asked by the browser whether or not you want to share your current location. For example, in Chrome you’d click accept to the little dropdown from the URL bar.

Okay, now we’ve got the user’s latitude and longitude displayed on the page! However, there’s still that ugly gray box taking up space where our map should be.

Let’s initialize a map using the user’s location and translate the latitude and longitude into a marker on our page. Modify the citychat/chat/static/js/chat.js JavaScript file we were just working on that obtained the user’s browser location.

Hey now, that looks a little bit better! Unfortunately, chat is still not yet working.

Adding Chat via IP Messaging

Our embedded map may look slick but chat has yet to land in our app. Earlier in this post we set all the environment variables we need to hook Twilio IP Messaging into our application. With those credentials in place we can now create JSON Web Tokens (JWT) on the server that will be requested by the browser and sent as soon as they are generated. Our application will need a new endpoint though for the browser to request the token by so open up citychat/chat/urls.py and add the single line highlighted below.

The new line added to urls.py creates a /token endpoint for our application and references a views.token function. We need to write that token function in the citychat/chat/views.py file as highlighted below.

In the above code, we include a few new imports for our project’s settings and the JsonResponse from the Django library. The AccessToken and IpMesssagingGrant are specific to Twilio IP Messaging. They allow us to create the appropriate JWT token to return to the requesting client based on our Twilio account credentials stored in our environment variables.

What about the front end browser code that calls for the access token? We need to take care of that now by modifying citychat/chat/static/js/chat.js with the following highlighted lines. These two functions, print and printMessage are just to help us attach the information messages and chat messages that need to be displayed on the page.

Show more