Section 11.4. Example Service: Echo

Using Twitter to Build a SMS Service > Example Service: Echo

11.4. Example Service: Echo

As an example, we'll create a service in Python that will echo back at you whatever you send to it.

For example, if you send the following message to Twitter's 40404 short code:

    d echo "What's up?"

it will respond with:

    ECHO: What's up? (reply? send: d echo hi)

The text in parentheses is added automatically by Twitter you can't get rid of it.

11.4.1. How To: Creating a Simple Twitter Service

Start by creating a new Twitter user for your service. We chose echo for this example, but you will have to choose your own. For the purpose of simplicity, we will set its password to 'echo' as well.

Users can add the service as their friend and then send it direct messages, to which the service will respond.

The Echo service will use a Twitter interface class that we'll be creating. We'll go over that class first and then over the details of the Echo service itself.

To create your Twitter service, you'll need:

  • Python 2.4 or higher

  • The json-py module (called python-json in pypi) for JSON support (http://cheeseshop.python.org/pypi/python-json)

  • A Twitter account for your service (http://www.twitter.com/)

A code listing will be provided after we go over the basic functionality provided by the Twitter class.

11.4.2. Functionality

Our Twitter interface provides most of the functions that you'll want to use to implement a Twitter service. Some of them are documented in the public API, but some of them are not. Here are the methods we'll be using:

  • get_followers (public): Gets a list of users that are following you. People who are following you will hear your messages. http://twitter.com/statuses/followers.json

  • get_friends (public): Gets a list of users that you consider your friends you'll receive their updates and their direct messages. http://twitter.com/statuses/friends.json

  • get_direct_messages (public): Returns every (non-deleted) direct message you've ever received. (Ideally there would be a function just to return unread messages, but it doesn't exist as of this writing.) http://twitter.com/direct_messages.json

  • befriend_all (undocumented): This function makes everyone who is following you your friend. This is important because in Twitter, you can only receive message from people who are your friends. http://twitter.com/followers/befriend_all

  • send_direct_message (public): Given a user name or id and a message to send, this method will send the message to the user - provided that user has accepted you as a friend. As noted in the API documentation, this method must be called using POST. http://twitter.com/direct_messages/new.json

  • delete_direct_message (undocumented): Lets you delete a message, given its message id. A service needs to delete messages every time it reads them to avoid acting twice on the same message. http://twitter.com/direct_messages/destroy/[MessageID]

  • delete_one_page_of_sent_messages (undocumented): Gets the Message IDs of all the sent messages that will show up on the user's sent direct message panel. It uses the IDs and repeatedly calls delete_direct_message. There might be a better way of doing this, but as of this writing it is the best mechanism we could find. http://twitter.com/direct_messages/sent(This is normal user-visible page, not an API call.)

    twitter.py:

#!/usr/bin/python import sys import os import urllib2 import urllib import json import time import re import random TWITTER_URL = "http://twitter.com" class Twitter(object):        def __init__(self, useremail, password):               authstring = "%s:%s"%(useremail, password)               self.__twitter = urllib2.build_opener()               self.__twitter.addheaders = [                ('Authorization', 'Basic %s'% (authstring.encode("base64").strip()))               ]               self.__sent_destroy_re = re.compile("/direct_messages/destroy/([0-9]+)")        def get_followers(self):               page = self.__twitter.open(TWITTER_URL + "/statuses/followers.json")               return json.read(page.read())        def get_friends(self):               page = self.__twitter.open(TWITTER_URL + "/statuses/friends.json")               return json.read(page.read())        def befriend_all(self):               page = self.__twitter.open(TWITTER_URL + "/followers/befriend_all")        def get_direct_messages(self):               page = self.__twitter.open(TWITTER_URL + "/direct_messages.json")               return json.read(page.read())        def send_direct_message(self, friend_id, text):               params = {                      'text' : text,                      'user' : friend_id,               }               page = self.__twitter.open(TWITTER_URL + "/direct_messages/new.json", data=urllib.urlencode(params))               return json.read(page.read())        def delete_direct_message(self, direct_message_id):               page = self.__twitter.open(TWITTER_URL + "/direct_messages/destroy/%s" % direct_message_id)        def delete_one_page_of_sent_messages(self):               page = self.__twitter.open(TWITTER_URL + "/direct_messages/sent")               for line in page.readlines():                      m = self.__sent_destroy_re.search(line)                      if m:                            self.delete_direct_message(m.group(1)) def main():        #simple usage example        twit = Twitter("username", "password")        print twit.get_friends() if __name__ == '__main__':        main()     

Twitter requires that most commands be authenticated using Basic Authentication. The constructor builds an object that will attach the appropriate authorization header every time we make a request. The code inside the constructor for Twitter base64 encodes the text "username:password" and then puts it in an "Authorization" header prefixed with the word "Basic." You can read more about Basic Authentication at http://www.ietf.org/rfc/rfc2617.txt.

Almost every method simply uses the opener we created in the constructor to access one URL. The URL returns a JSON dictionary that we convert into a python dictionary.

The .json appended to the URL tells Twitter to return the results as JSON dictionaries. XML and RSS are supported for many methods as well. JSON was chosen here because it is lightweight and translates easily into Python dictionaries. All we have to do is call the read method of the JSON module on the results, and we get a Python dictionary back with all the results

A JSON dictionary for a get_friends call looks something like this (this user has one friend named testinos:

[{"name":"testinos","description":null,"location":null, "profile_image_url":"http:\/\/assets0.twitter.com\/images\/ default_image.gif?1181015407","url":null,"id":5719462, "screen_name":"testinos","protected":false}]

After calling json.read() on the text of the JSON, we get a Python dictionary that looks like this:

[{'name': 'testinos', 'url': None, 'profile_image_url': 'http://assets0.twitter.com/images/default_image.gif?1181015407', 'screen_name': 'testinos', 'location': None, 'protected': False, 'id': 5719462, 'description': None}]

There are a few methods that warrant some additional explanation:

11.4.3. The Echo application

We'll use the commands described above to build our service. The Twitter API only supports polling right now, so we'll be doing everything in a loop.

echo.py:

#!/usr/bin/python import twitter import time twit = twitter.Twitter('servicename', 'servicepass') while True:        twit.befriend_all()        print "checking..."        dms = twit.get_direct_messages()        for dm in dms:               twit.delete_direct_message(dm['id'])               print "Echoing! %s" % dm['text']               twit.send_direct_message(dm['sender_screen_name'], "ECHO: " + dm['text'])        time.sleep(120)        twit.delete_one_page_of_sent_messages()

Once you have the Twitter interface written, the service itself is trivial. Every two minutes we befriend anyone who has added us as their friend, and check for new messages. If we have a new message, we get the contents of it, delete it, and then send it back to the originator prefixed with ECHO:.

To try this out for yourself:

Have fun tweating!

 

 



How to Build an SMS Service
How to Build an SMS Service
ISBN: 789742233
EAN: N/A
Year: 2007
Pages: 52
BUY ON AMAZON

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net