Saturday, 30 April 2011

Send and Receive SMS with Python

I was thinking about writing a text-based game similar to the classic Fighting Fantasy books, but using SMS as the delivery mechanism. To do that I would need a way to send and receive SMS text messages to and from a server. As a challenge to see how that would work I wanted to write a prototype that would look like this:

CPU>>User: "Hello! What is your name?"
User>>CPU: "Fred"
CPU>>User: "Nice to meet you Fred"

The program itself is obviously easy. The problem is how to do the input and output over SMS. On to Google to see if I could find anything. Second link down on my first search I found the Active State code recipe 'Send and receive SMS messages using TextMagic'. It had a nice looking python package available. Reading the TextMagic website it seems that the only way to get started is to buy 200 SMS credits for £20. Hmm a little pricey as a barrier to entry.
I remember using Clickatell for this sort of thing ages ago. I took a look back at their site. The reality-check came in pretty quickly as Clickatell was going to cost minimum of €100 to set up and then €25 per month to run. So, back to TextMagic. And then I found out how to sign up for a free trial account!
With the free trial set up the next job was to set up the python environment. I use virtualenv to keep my python installation clean. To get started therefore created a new virtualenv.

$ virtualenv sms
$ source sms/bin/activate

I then installed the PyTextMagicSMS package.
$ sms/bin/easy_install PyTextMagicSMS
The first job was to try the sample sending program:

import textmagic.client
client = textmagic.client.TextMagicClient('your_username', 'your_api_password')
result = client.send("Hello, World!", "1234567890")

...which worked a treat. Obviously change the method parameters to match your settings.
So onwards to reading the Text Magic documentation to find out how to receive a reply. There are two ways of receiving a reply. Either you can poll your in-box to see what messages you have received, or you can set a callback URL to be notified of the response. The callback URL is clearly the way to go for anything of any complexity, but just to get started we will poll the in-box.

import textmagic.client
client = textmagic.client.TextMagicClient('name', 'pw')

received_messages = client.receive(0)
messages_info = received_messages['messages']
print('%d messages in in-box' % len(messages_info))
if len(messages_info) > 0:
first_message = messages_info[0]
print("Message from: %s" % first_message['from'])
print(first_message['text'])
client.delete_reply(first_message['message_id'])


Okay, so we're getting close to a solution. I'll have one program that sends the hello part of the conversation, a second program that checks the in-box for replies and then sends the final message. Here's the sending one...

import sys
import textmagic.client


client = textmagic.client.TextMagicClient('username', 'password')
no = sys.argv[1]

result = client.send("Hello! What is your name?", no)


...and here's the receiving one...

import textmagic.client
client = textmagic.client.TextMagicClient('username', 'password')

received_messages = client.receive(0)
messages_info = received_messages['messages']
print('%d messages in in-box' % len(messages_info))
if len(messages_info) > 0:
first_message = messages_info[0]
from_no = first_message['from']
name = first_message['text']
print("Message from: %s" % from_no)
print(name)

client.send("Nice to meet you %s!" % name, from_no)
print("I have sent a reply")
client.delete_reply(first_message['message_id'])


All this needs is a main loop round it to keep polling for input and we're done.

5 comments:

Anonymous said...

it seems textmagic use some "credit" system for calculating your balance, and 200 credits actually gives you 250 messages to UK numbers.

This kind of thing is, for me, a solution looking for a problem, though I'd like to find a use for it (probably texting in to control my server)

Dave Potts said...

I did have a small problem with TextMagic. There are three reply numbers that TextMagic lets you use for the UK. All of them worked with my phone on Orange. A different phone with O2 only worked the the reply number 447624800500. The other two number failed to receive the response. TextMagic support were very helpful in working this out.

Anonymous said...

Have you tried looking into something like gmailsms (http://code.google.com/p/gmailsms/) which sends/receives SMS through a gmail account. It may be US-focused but I think you can find the mappings to the UK providers yourself...

Chad said...

You should check out Twilio, here's a sample text adventure with it: https://github.com/jjinux/pyteladventure

Dave Potts said...

Twilio does look interesting. I'll take a look. Thanks!