Friday, October 9, 2009

Python - Custom Google Voice API - Installable Module

Google Voice is a great service, but it lacks a couple of important things:
  1. An official API from Google
  2. A way to send mass SMS messages
I have spend some time creating my own unofficial API that is, I hope, easy to use and extend. I am by no means a seasoned Python developer, but I know enough to get what I want done. Many of the posts on my blog that interact with Google Voice depend on a "" script that I wrote, which contains several helpful classes. These class allow you to perform some basic actions, such as:

  1. Logging in to your Google Voice Account
  2. Sending a text message
  3. Placing a phone call

The script also allows you to:
  1. Download your Google Contacts into memory (Used mainly to get contact information to call or send a message)
  2. Programmatically select from you Contact Groups which people to contact
  3. Retrieve the numbers you have set up to work with your Google Voice account

Currently the script has only been tested using Python 2.6 (Python 3 might work, but I am not sure).

You can download the module with installation instructions below. Or, just scroll down to the bottom of the post to see the source in it's entirety.

Here are some of the posts where I show examples on how to use this module:

And the complete source:


Created by: Scott Hillman

This module comes as is an with no warranty.
You are free to use, modify and distribute this
code however you wish, but I ask that if you post
it anywhere, you at least make reference to me and
my blog where you acquired it.

import csv
import sys
import re
import urllib
import urllib2

class GoogleVoiceLogin:
Class that attempts to log in the Google Voice using the provided

If either no password or email is provided, the user will be
prompted for them.

Once instantiated, you can check to see the status of the log in
request by accessing the "logged_in" attribute

The primary usage of a GoogleVoiceLogin object is to be passed
in to other constructors, such as the TextSender, or NumberDialer

def __init__(self, email = None, password = None):
Given the email and password values, this method will attempt to log
in to Google Voice. The "response" attribute can be checked to
see if the login was a success or not.

If the login was successful, the "opener" and "key" attributes will
be available to use when creating other objects.

To use an this object with the other classes in this module, simply
pass it in to the constructor. (ie text_sender = TextSender(gv_login))

if email is None:
email = raw_input("Please enter your Google Account username: ")
if password is None:
import getpass
password = getpass.getpass("Please enter your Google Account password: ")

# Set up our opener
self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())

# Define URLs
self.login_page_url = ''
self.authenticate_url = ''
self.gv_home_page_url = ''

# Load sign in page
login_page_contents =

# Find GALX value
galx_match_obj ='name="GALX"\s*value="([^"]+)"', login_page_contents, re.IGNORECASE)

galx_value = if is not None else ''

# Set up login credentials
login_params = urllib.urlencode({
'Email' : email,
'Passwd' : password,
'continue' : '',
'GALX': galx_value

# Login, login_params)

# Open GV home page
gv_home_page_contents =

# Fine _rnr_se value
key ='name="_rnr_se".*?value="(.*?)"', gv_home_page_contents)

if not key:
self.logged_in = False
self.logged_in = True
self.key =

class ContactLoader():
This class is used to download and organize a csv file
of Google Contacts.It is often used in conjunction with
the ContactSelector class.


contact_loader = ContactLoader(gv_login)
contact_selector = ContactSelector(contact_loader)
def __init__(self, gv_login):
Pass in a GoogleVoiceLogin object, and the persons Google Contacts
Will be downloaded and organized into a structure called
which is organized in form:

[(1, ('group_name', [contact_list])), (2, ('group_name', [contact_list]))]

Which allows for easy access to any group.
self.opener = gv_login.opener
self.contacts_csv_url = ""
self.contacts_csv_url += "?groupToExport=^Mine&exportType=ALL&out=OUTLOOK_CSV"

# Load ALL Google Contacts into csv dictionary
self.contacts = csv.DictReader(

# Create dictionary to store contacts and groups in an easier format
self.contact_group = {}
# Assigned each person to a group that we can get at later
for row in self.contacts:
if row['First Name'] != '':
for category in row['Categories'].split(';'):
if category == '':
category = 'Ungrouped'
if category not in self.contact_group:
self.contact_group[category] = [Contact(row)]

# Load contacts into a list of tuples...
# [(1, ('group_name', [contact_list])), (2, ('group_name', [contact_list]))]
self.contacts_by_group_list = [(id + 1, group_contact_item)
for id, group_contact_item in enumerate(self.contact_group.items())]

class Contact():
Simple class to contain information on each Google Contact person.

Only stores information on:
First Name
Last Name
Mobile Number
Email address
def __init__(self, contact_detail):
Extract data from the given contact_detail

The following attributes are available:

self.first_name = contact_detail['First Name'].strip()
self.last_name = contact_detail['Last Name'].strip() = contact_detail['Mobile Phone'].strip() = contact_detail['E-mail Address'].strip()

def __str__(self):
return self.first_name + ' ' + self.last_name

# Class to assist in selected contacts by groups
class ContactSelector():
Class with helps select contacts after using the ContactLoader
object to download them.

Provides methods to:
1) Display the list of groups (get_group_list())
2) Set the selected group to work with (set_selected_group(group_id))
3) Get the contacts from the working list (get_contacts_list())
4) Remove names from the working list(remove_from_contact_list(contacts_to_remove_list))
def __init__(self, contact_loader):
Initialize the object - a ContactLoader object is expected here
self.contacts_by_group_list = contact_loader.contacts_by_group_list
self.contact_list = None

def get_group_list(self):
Extract a list of all the groups.
List is in the form:
[(1, 'Group Name'), (2, 'Groups Name'), ...]
return [(item[0], item[1][0]) for item in self.contacts_by_group_list]

def set_selected_group(self, group_id):
Select the group to work with.

This method will make the working contact_list contain all the
contacts from the selected group.
self.contact_list = self.contacts_by_group_list[group_id - 1][1][1]

# Return the contact list so far
def get_contacts_list(self):
Return a list of all the contacts, and assign them each a number

List is in the form:
[(1, Contact), (2, Contact), ...]
return [(id + 1, contact) for id, contact in enumerate(self.contact_list)]

def remove_from_contact_list(self, contacts_to_remove_list):
Accepts a one based list of ids, indicating which contacts
to remove from the list.

List needs to be a list in ints:
[3, 6, 7]
if self.contact_list is None:
for id in contacts_to_remove_list:
if id in range(0, len(self.contact_list) + 1):
self.contact_list[id - 1] = None
self.contact_list = [contact for contact in self.contact_list if contact is not None]

class NumberRetriever():
Class that will allow you to retrieve all stored phone numbers and their aliases

def __init__(self, gv_login):
Pass in the GoogleVoiceLogin object, this class will then
download all the numbers and aliases of the persons GV Account
self.opener = gv_login.opener
self.phone_numbers_url = ''
phone_numbers_page_content =

# Build list of all numbers and their aliases
self.phone_number_items = [(,
for match
in re.finditer('"name":"([^"]+)","phoneNumber":"([^"]+)"',

def get_phone_numbers(self):
Return the list of phone numbers in the form:
[(1, number), (2, number)...]
return [(id + 1, (phone_number_item))
for id, phone_number_item
in enumerate(self.phone_number_items)]

class TextSender():
Class used to send text messages.

Example usage:

gv_login = GoogleVoiceLogin('username', 'password')
text_sender = TextSender(gv_login)
text_sender.text = "This is an example"

if text_sender.response:
print "Success!"
print "Fail!"
def __init__(self, gv_login):
Pass in a GoogleVoiceLogin object, set the text message
and then call send_text
self.opener = gv_login.opener
self.key = gv_login.key
self.sms_url = ''
self.text = ''

def send_text(self, phone_number):
Sends a text message containing self.text to phone_number
sms_params = urllib.urlencode({
'_rnr_se': self.key,
'phoneNumber': phone_number,
'text': self.text
# Send the text, display status message
self.response = "true" in, sms_params).read()

class NumberDialer():
Class used to make phone calls.

Example usage:

gv_login = GoogleVoiceLogin('username', 'password')
number_dialer = NumberDialer(gv_login)
number_dialer.forwarding_number = 'number-to-call-you-at'


if number_dialer.response:
print "Success!"
print "Fail!"
def __init__(self, gv_login):
self.opener = gv_login.opener
self.key = gv_login.key
self.call_url = ''
self.forwarding_number = None

def place_call(self, number):
Pass in a GoogleVoiceLogin object, set the forwarding_number
and then call place_call('number-to-call')
call_params = urllib.urlencode({
'outgoingNumber' : number,
'forwardingNumber' : self.forwarding_number,
'subscriberNumber' : 'undefined',
'remember' : '0',
'_rnr_se': self.key

# Send the text, display status message
self.response =, call_params).read()
blog comments powered by Disqus