Using the Campfire “API” in Django

I’m working on a group chat feature at my day job right now. The requirement is for a robust group chat widget to run alongside a live streaming video feed (via Ustream) of a two-day conference. If the solution works well, we want to consider using it for other purposes, e.g. webinars.

I was pretty dissatisified with my brief survey of existing chat widgets out there. This is a professional conference, so I really didn’t want a widget that was all yucked up with ads or smileys.

Anyhow, since I use Campfire a lot at my day job, I figured, why not give it a shot?

The good news is, Campfire does have an API, known as Tinder.

The bad news is, it’s an unoffical API, written in Ruby. (Not that there’s anything wrong with that, but I didn’t want to deal with configuring a reliable production environment for what was hopefully a small project.)

The good news is, someone ported the Tinder API over to Python, calling it Pinder. Which rocks, because now I get to use Django.

To make a long story short, here’s what I ended up doing:

  • Set up a custom django-admin command to execute the listener. So now I just run $ python manage.py listen_to_campfire at the command prompt and away it goes.
  • Created a listener class that implements the Pinder API and that basically continually loops over the transcript and adds any new messages it finds to the DB. Here’s the main function:
    def listening_to_campfire(self):
        """
        The actual listening method. This method checks for new campfire messages and writes any it finds
        to the Message model. It returns True if everything goes okay, and False if any errors get caught.
        """

        try:
            current_messages = self.room.transcript(self.room.transcripts()[0])
            most_current_message_id = int(current_messages[-1]['id'])
            if not most_current_message_id == self.last_message_id: # i.e. there are new messages

                # compares the id of each new message with the latest existing message id,
                # only keeps those that are newer
                new_messages = filter(
                    lambda cm: int(cm['id']) > self.last_message_id,
                    current_messages
                )

                for nm in new_messages:
                        m = Message.create_from_campfire_message(nm)
                        if m:
                            m.save()
                            print m

                self.last_message_id = most_current_message_id
            else:
                print "..."
        except KeyboardInterrupt:
            script_halted()
        except:
            return False

        return True
  • Created a view of the latest messages from the database and returned them in JSON.
  • Implemented an Ajax routine to poll the JSON feed and add any new results to the chat widget in real time.

This works pretty nicely. The only thing the chat widget does not allow at present is the ability to type messages from the widget itself…for that you have to enter the Campfire chat room. This may turn out to be a important requirement though, in which case I will need to extend the Pinder API to allow for anonymous room logins.

To be continued…perhaps.

UPDATE: The yucks won. I’m using a Meebo room, which I managed to format decently though.

2 comments

  1. skyl

    Interesting, thanks on the tip about Pinder. Always looking around for possible apis to Django.

  2. mike

    Very nice. Why did you switch to Meebo? Is it because the lack of login functionality in Pinder, or was it not even supported by the API?

Post a comment

Contact Info
will not be published

include http://

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>