tipfy.ext.xmpp ¶
So, you'd like to create a nifty bot on your appengine application? Cool! Us too! XMPP allows you to connect with users such as GTalk, and a few others.
Setup¶
This service uses a specially crafted URL within your application to deliver XMPP messages to your handler. Essentially, App Engine will do all the processing of converting an XMPP message into something to your application can reply to. All you have to do is handle and respond!
First, we need to enable this feature by editing the app.yaml file like below:
app.yaml
application: your_app_id
version: 1
runtime: python
api_version: 1
inbound_services:
- xmpp_message
Secondly, you'll need to add the tipfy.ext.xmpp package to your buildout.cfg file.
buildout.cfg
eggs =
tipfy
... (many others snipped out) ...
tipfy.ext.xmpp
Lastly, run your bin/buildout to download the packages.
Understanding¶
XMPP is handled exactly like a traditional http post or get request. Simply, we'll just respond to an incoming message with some details of the transaction. This will help us understand what's really happening.
Test Case Implementation¶
Lets create a handler and url rule for your XMPP messages. This style of handler is the simplest type, and will have a single handler for all incoming requests. Later, we'll add some custom command handlers.
apps/xmpp/urls.py
from tipfy import Rule
def get_rules(app):
rules = [
# API Handlers
Rule('/_ah/xmpp/message/chat/',
endpoint='services/xmpp',
handler='apps.xmpp.handlers.XMPPHandler',
),
]
return rules
apps/xmpp/handlers.py
import logging
from tipfy.ext.xmpp import BaseHandler as XMPPBaseHandler
class XMPPHandler(XMPPBaseHandler):
# Define the base message handler
def message_received(self, message):
logging.info('Incoming XMPP Message')
# A quick sanity check
if message is not None:
logging.info(u'message.sender: ' + message.sender)
logging.info(u'message.arg: ' + message.arg)
# Reply back
return 'Hello, World!\n' + str(message)
To test this code, fire up the dev_appserver.py, and head to http://localhost:8080/_ah/admin. You'll notice an entry called XMPP, select it. We can send test commands to our app. It's important to put in what could be a valid XMPP From: address. Something like test@test.com will work fine. If you don't know what a From: address could look like, please read up on the JID. Enter the To: address as your-app-id@appspot.com. Lastly, enter any message and click Send Message.
Real World Implementation¶
So, that was a really really simple example. Lets do something more useful and also take advantage of the CommandHandler to allow bot-style commands to be send to the app. CommandHandler is actually an empty class which already extends the CommandHandlerMixin and BaseHandler classes. We'll use that one this time. We'll also remove the message_received method as it's automatically taken care of now.
apps/xmpp/handlers.py
import logging
from tipfy.ext.xmpp import CommandHandler
class XMPPHandler(CommandHandler):
# Define the first command handler, which expects /askme <unicode_string>
def askme_command(self, message):
logging.info('Incoming XMPP AskMe Message')
# A quick sanity check
if message is not None:
return u'AskMe Command response here'
# Define the base message handler for non-slash prefixed messages
def text_message(self, message):
logging.info('Incoming XMPP Message')
# A quick sanity check
if message is not None:
logging.info(u'message.sender: ' + message.sender)
logging.info(u'message.arg: ' + message.arg)
# Reply back
return 'Hello, World!\n' + str(message)
# Define the unhandled command entry, which acts as a catch all
def unhandled_command(self, message):
logging.info('Incoming XMPP Unhandled Message')
return 'Invalid Command, try a supported one!'
You can see we've added 2 new methods, and removed the message_received method. Essentially, if they send a standard message, it's handled by text_message. If they send a command starting with a '/' or '\' followed by some string, it will call the associated command. Eg. If the message contains '/foo bar', the foo_command method is called within this class. The command itself is available within the method as message.command, and it is stripped from the message.arg.
Conclusion¶
So, your app can talk to XMPP users and respond to commands. Now it's time to put on your thinking cap, and imagine the best use for this module. Here's a short list of our favorites:
- Incoming notification to trigger batch cleanup of datastore
- Incoming request to flush memcache
- Outgoing notification to an admin that a user registered, or updated your wiki
- Outgoing notification containing a daily overview of usage of your app
- A self-help portal for your application
- Notifying users of downtime (using the capabilities api)
Extension Reference¶
- Name: tipfy.ext.xmpp
- Author: Rodrigo Moraes, ported from App Engine SDK
- License: Apache License
- Tags: XMPP, jabber, gtalk, external APIs
- URL: http://www.tipfy.org/wiki/extensions/xmpp/
- PyPi page: http://pypi.python.org/pypi/tipfy.ext.xmpp/
- Source code: http://code.google.com/p/tipfy-ext-xmpp/
- Issue tracker: http://code.google.com/p/tipfy-ext-xmpp/issues/list
- Version: latest
- Edited by moraes on 7/26/10 4:33 AM
- Save on Delicious | Submit to Reddit
- History
- Edit
