• Subscribe to the RSS feed! RSS icon
  • Subscribe by Email
  • home
  • blog
  • dev
  • Recent Posts

    • Automatically upload screenshots in XFCE4
    • Zend Framework full page cache tips
    • No more Wordpress
    • Xdebug is full of awesome
    • Creating a chat bot with PHP and Dbus
    • A year in review: 2011
    • Notes on shell scripting
    • Listening to Dbus signals with PHP
    • Configuring 2 monitors with xrandr
    • A quick note on Dojo's data grids and dojox.data.HtmlStore
  • Recent Comments

    • Robert on Zend Framework full page cache tips
    • Stephen S. Musoke on Zend Framework full page cache tips
    • David on Zend Framework full page cache tips
    • Anon on A quick note on Dojo's data grids and dojox.data.HtmlStore
    • James on Communicating with Pidgin from PHP via D-Bus
    • Robert on A Zend Framework 2 EventManager use case
    • Jowee on A Zend Framework 2 EventManager use case
    • Jurian Sluiman on A Zend Framework 2 EventManager use case
    • Jurian Sluiman on A Zend Framework 2 EventManager use case
    • djozsef on Webkonf 2011 recap
  • Tags

    php, about, random, framework, zend, example, ubuntu, blog, site, zend framework, book, conference, me, python, wordpress, apache, introduction, lamp, linux, open source, review, script, setup, signals, ape, community, contributing, dbus, dojo, events, hack, mysql, netbeans, pidgin, plugin, pyqt, security, shell, svn, talk
  • Categories

    • Blablabla
    • Development
    • Free time
    • Places on the web
    • Programming
    • Software
    • Uncategorized
  • Archives

    • February, 2012
    • January, 2012
    • December, 2011
    • November, 2011
    • October, 2011
    • September, 2011
    • August, 2011
    • July, 2011
    • May, 2011
    • April, 2011
    • March, 2011
    • January, 2011
    • December, 2010
    • November, 2010
    • October, 2010
    • July, 2010
    • June, 2010
    • April, 2010
    • February, 2010
    • January, 2010
    • December, 2009
    • November, 2009
    • October, 2009
    • August, 2009
    • May, 2009
    • March, 2009
    • February, 2009
    • January, 2009
    • December, 2008
    • November, 2008
    • October, 2008
    • September, 2008

Communicating with Pidgin from PHP via D-Bus

by Robert Basic on December 18th, 2011

Earlier this week I got an idea of trying to communicate with Pidgin, a chat client, via the terminal. Sounded like a fun thing to hack on, plus, could be made useful (in my head, at least), for things like logging from a web application directly to IM, or, heck, even creating something like Github's Hubot, commanding a server or an application just via chat. Surely I wasn't the first one to come up with this idea and after a bit of a googling found out that Pidgin's libpurple has a nice API for that, exposed via D-Bus.

I first planned to write some scripts for this in Python or C, but when I finally sat down over the weekend to hack on this, realized there is a PHP D-Bus extension, thanks to Derick Rethans! As I rarely have the opportunity/need to play with more "obscure" PHP extensions, decided to give this one a spin... (Note: apart from that D-Bus is used for processes communicating with each other, I have zero knowledge about it, so I might be wrong with some things down below.)

Installing D-Bus for PHP

As the extension requires the dbus-devel package, first make sure it is installed:

$ yum install dbus-devel

The installation of the extension itself is pretty easy:

$ pecl install dbus-beta

Add the extension=dbus.so line to your php.ini, restart Apache if needed and have a look at the phpinfo();, there should be an entry for D-Bus listed.

Note that there is no documentation for this extension at the moment, but, luckily, the sources include an examples directory full of goodies! After fiddling around with those for an hour or so, got the basics of the extension figured out.

One thing I haven't figured out completely, is how to run scripts which use the Dbus extension via the browser, as in those cases the scripts are dying with a terrible X11 error message. So, run Dbus scripts from the console and all should be fine.

The a-ha! moment

What I learned by looking at the examples, is that the Dbus class is used for creating a proxy, which can be used to call methods on the service/application we're interested in. But, what methods are available, what arguments do those methods accept (if any), and what will they return as a result?

This can easily be found out by introspection. Create a proxy to an object which implements the Introspectable interface and call the Introspect method on that proxy:

<?php

$dbus = new Dbus;

$proxy = $dbus->createProxy("im.pidgin.purple.PurpleService",
                            "/im/pidgin/purple/PurpleObject",
                            "org.freedesktop.DBus.Introspectable");

$data = $proxy->Introspect();

file_put_contents('introspect.xml', $data);

As the result of the introspection is returned in an XML and can be quite big, putting it in a file for easier viewing.

By looking at the XML file, it's pretty easy to figure out what's going on; method names, method arguments, their names and types, and the returned result:


  
  

With all this information at our disposal, it's easy to write a script which does something useful, like, listing all the connected accounts and the protocols they are using:

<?php

$dbus = new Dbus;

$proxy = $dbus->createProxy("im.pidgin.purple.PurpleService",
                            "/im/pidgin/purple/PurpleObject",
                            "im.pidgin.purple.PurpleInterface");

$accounts = $proxy->PurpleAccountsGetAllActive();

foreach ($accounts->getData() as $account) {
    if ($proxy->PurpleAccountIsConnected($account)) {
        $username = $proxy->PurpleAccountGetUsername($account);
        $protocolId = $proxy->PurpleAccountGetProtocolId($account);
        $protocolName = $proxy->PurpleAccountGetProtocolName($account);
        echo $username . " is connected on the " . $protocolName
                       . " (" . $protocolId . ") protocol.\n";
    }
}

A sample output would be something like: "robertbasic@irc.freenode.net is connected on the IRC (prpl-irc) protocol."

Next steps

Of course, this is far from a chat bot which can execute commands on a remote server, but at least we have some foundation to build on. In the coming days I'll try to figure out how to create a loop which can be used to listen to different purple events - when a contact comes online, a chat is sent, or received, etc.

Also, it is quite fun trying to figure out a PHP extension just by looking at examples and the C source itself. One can learn a lot this way.

Happy hackin'!

P.S.: Code samples are up on Github!

Update 2011-12-26: the 2nd post, listening to dbus signals with php, is published!

Tags: communication, dbus, pecl, php, pidgin, xmpp.
Categories: Development, Programming.
Comments: 1 comment.

Comments: 1

  • James

  • December 18th, 2011
I recently had a play around with Jabber + PHP. I wanted to write a very quick and dirty bot that sits in our dev chat room (on our Jabber server) without learning a new language, that sat there and tells us when deployments happen using GoDeploy. So I found JAXL (https://github.com/abhinavsingh/jaxl) and hacked it up a bit - in about 45 minutes I had a bot up and running, and another 15 minutes I had it checking the deployment JSON file that GoDeploy spits out to check for new deployments. Tis rather funky if I do say so myself. Slightly different approach to what you had in mind though, but thought I'd add my two pennies! :)

Leave a Reply

Robert Basic © 2008 — 2012
Design & graphics by: Livia Radvanski
Coded by: Robert Basic
Home page last updated on November 30th, 2009.
Frameworks used: Zend Framework, Dojo, 960 Grid System