Facebook chat connect with X-FACEBOOK-PLATFORM using Jaxl 2.0

Facebook chat provides two authentication mechanisms for authenticating chat client users. DIGEST-MD5 require chat client users to enter their username and password, while X-FACEBOOK-PLATFORM can be used to provide better user experience by using simple Facebook Platform authentication. In this blog post, I will demonstrate how to use Jaxl library for X-FACEBOOK-PLATFORM authentication.

Echobot using X-FACEBOOK-PLATFORM
Setup Jaxl library on your system and edit packaged sample echobot application with facebook user account details. Alternately you can also specify connecting user details inside jaxl.ini configuration file.

        $jaxl = new JAXL(array(
                'user'=>'fbUsername',
                'pass'=>'', // Not required, we will use user session key instead
                'host'=>'chat.facebook.com',
                'domain'=>'chat.facebook.com'
        ));

Add callback for hook jaxl_get_facebook_key:

JAXLPlugin::add('jaxl_get_facebook_key', array($echobot, 'getFacebookKey'));

Complete getFacebookKey method inside echobot application, which should return back following key information:

function getFacebookKey() {
                        return array(
                                '', // Your application secret key
                                '', // Your application api key
                                '' // Connecting user session key
                        );
                }

Update doAuth method to use X-FACEBOOK-PLATFORM auth mechanism:

                function doAuth($mechanism) {
                        global $jaxl;
                        $jaxl->auth("X-FACEBOOK-PLATFORM");
                }

Finally, run echobot from command line:

root@ubuntu:/usr/share/php/jaxl/app/echobot# jaxl echobot.php
[1942] 2010-08-08 05:35:10 - Socket opened to the jabber host chat.facebook.com:5222 ...
[1942] 2010-08-08 05:35:11 - Performing Auth type: X-FACEBOOK-PLATFORM
[1942] 2010-08-08 05:35:26 - Auth completed...

XEP 0133 – Service Administration available methods in Jaxl 2.0

Jaxl 2.0 implements more than 10 XMPP extensions including XEP-0133 a.k.a. Service Administration. In this blog post, we will go through all the methods available for use in XMPP applications developed using Jaxl.

Using Service administration methods
You need to include Jaxl implementation of XEP-0133 in your application code to start using below listed available methods. Here is how this can be done at the top of your application code:

// initialize jaxl instance
$jaxl = new JAXL();

// include service administration
$jaxl->requires('JAXL0133'); // or jaxl_require('JAXL0133', $jaxl);

Service administration available methods
Below is a detailed list of methods from service administration extension:

  • $jaxl->JAXL0133(‘addUser’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘deleteUser’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘disableUser’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘reEnableUser’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘endUserSession’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘getUserPassword’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘changeUserPassword’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘getUserRoster’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘getUserLastLoginTime’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘getUserStatistics’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘editBlacklist’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘editWhitelist’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘getUserCount’, $user, $domain, $callback, $type)
  • $jaxl->JAXL0133(‘getUserList’, $user, $domain, $callback, $type)
  • $jaxl->JAXL0133(‘sendAnnouncementToActiveUsers’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘setMOTD’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘editMOTD’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘deleteMOTD’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘setWelcomeMessage’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘deleteWelcomeMessage’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘editAdminList’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘restartService’, $user, $domain, $callback)
  • $jaxl->JAXL0133(‘shutdownService’, $user, $domain, $callback)

Examples
All the methods expects 3 parameters as defined below:

  • $user: An associative array containing information about the user on whose account service administrative actions need to be taken
  • $domain: Jabber domain to which $user belongs
  • $callback: Specify where do you want to receive success/failure of executed service administration command
  • $type: Required by getUserCount and getUserList methods. Allowed values are registered, disabled, online, active and idle.

$user array MUST correspond to the fields in the request form for executing service administration commands.

Here is how to add a new user using XEP-0133:

$user = array(
        'jid' => 'newuser',
        'pass' => 'password',
        'email' => 'newuser@email.com',
        'fname' => 'Hello',
        'lname' => 'World'
);

$jaxl->JAXL0133('addUser', $user, 'jaxl.im', array($this, 'postAddUser'));

Your application code must have a methods named ‘postAddUser’ which will be called back by Jaxl core, when it finishes executing the command.

Jaxl 2.0 Core classes, available methods and directory structure

In this blog post we will dig deep into the core of Jaxl 2.0 – An XMPP framework written in PHP. Specifically, we will go through Jaxl core directory structure. Towards the end we will get familiar with various core classes and their available methods (e.g. $jaxl->sendMessage()), that developers can use in their XMPP applications.

Core Directory Structure
Now that you have the source code, lets get familiar with the Jaxl directory structure. Downloaded source code consists of following 5 directories:

  • xmpp: Contain core stack which implements XMPP rfc’s. All files follow naming convention like xmpp.*.php
  • core: Contains core stack which manages the library workflow. Also provides an xpath based XML parser, an event mechanism and various other utilities to the framework. All files follow naming convention like jaxl.*.php
  • xep: Contains implemented XMPP extensions (XEP’s). All files follow naming convention like jaxl.XEP-NUMBER.php
  • env: Contains Jaxl main() file jaxl.php, Jaxl core configuration file jaxl.conf and application environment setup file jaxl.ini. For bosh application developers jaxl.js is a must include from this directory.
  • app: Contains example applications which comes packed with Jaxl library

Core Classes and Available Methods
Below is a detailed list of all the core classes and available methods in developer land space:

JAXL
This class is located inside core/jaxl.class.php and extends base XMPP class. Following is a list of methods available:

  • __construct($config=array()) : Constructor accepts following configuration parameters. Passed parameters will overwrite corresponding jaxl.ini values:
    $config = array(
        'user'=>'', // JAXL_USER_NAME
        'pass'=>'', // JAXL_USER_PASS
        'host'=>'', // JAXL_HOST_NAME
        'port'=>'', // JAXL_HOST_PORT
        'domain'=>'', // JAXL_HOST_DOMAIN
        'component'=>'', // JAXL_COMPONENT_HOST
        'logPath'=>'', // JAXL_LOG_PATH
        'logRotate'=>'', // false or second in which to rotate log
        'logLevel'=>'', // JAXL_LOG_LEVEL
        'pidPath'=>'', // JAXL_PID_PATH
        'boshHost'=>'', // JAXL_BOSH_HOST
        'boshPort'=>'', // JAXL_BOSH_PORT
        'boshSuffix'=>'', // JAXL_BOSH_SUFFIX
        'resource'=>'', // connecting user resource identifier
        'streamTimeout'=>'', // connecting stream timeout
        'sigh'=>'', // boolean to forcible enable/disable sigh term
        'dumpStat'=>'', // false or numeric specifying second after which to dump stat
    );
  • auth($type) : Performs authentication with the jabber server. DIGEST-MD5, PLAIN, X-FACEBOOK-PLATFORM and ANONYMOUS are the supported auth $type
  • setStatus($status=FALSE, $show=FALSE, $priority=FALSE, $caps=FALSE) : Update the status of connected jabber user. Pass $caps=TRUE for sending entity capability information while setting connected user status.
  • subscribe($toJid)
  • subscribed($toJid)
  • unsubscribe($toJid)
  • unsubscribed($toJid)
  • getRosterList($callback=FALSE) : Fetch roster list for the connected user. See example usage inside echobot application.
  • addRoster($jid, $group, $name=FALSE)
  • updateRoster($jid, $group, $name=FALSE, $subscription=FALSE)
  • deleteRoster($jid)
  • sendMessage($to, $message, $from=FALSE, $type=’chat’)
  • sendMessages($to, $from, $child, $type)
  • sendPresence($to, $from, $child, $type)
  • $jaxl->requires($class) : It is an alternative for jaxl_require($class, $jaxl).
  • $jaxl->xml->xmlize($xml) : Use this method to convert raw XML string into an array.
  • $jaxl->log($log, $level) : Use this method for logging purposes

JAXLPlugin
This class is located inside core/jaxl.plugin.php. Following is a list of methods available:

  • add($hook, $callback, $priority=10) : Register callback on available hooks
  • remove($hook, $callback) : Un-register callback on a previously registered hooks using add method

JAXLCron
This class is located inside core/jaxl.cron.php. Use this call methods to run periodic background jobs. Following is a list of methods available:

  • add($callback, $interval) : $callback methods is called every $interval second
  • delete($callback, $interval) : Removes a previously registered cron job

JAXLUtil
This class is located inside core/jaxl.util.php. Following is a list of methods available:

  • isWin() : Window OS detection, return bool
  • getTime()
  • getBareJid($jid)
  • splitJid($jid)
  • curl($url, $type=’GET’, $headers=FALSE, $data=FALSE, $user=FALSE, $pass=FALSE)

More methods might get added in future and will be updated here.

Using available XEP methods
Once have included required XEP class inside your application code, either by using jaxl_require('JAXLxxxx', $jaxl) or by calling $jaxl->requires('JAXLxxxx'), you can start using the available methods inside included XEP class as follows:

$jaxl->JAXLxxxx('methodName', $param1, $param2, ....);

e.g. If you want to call joinRoom methods of Multi-User Chat XEP-0045, you can do so by calling

$jaxl->JAXL0045('joinRoom', $jid, $roomJid.'/'.$nick, $history, $seconds)

. DO-NOT call the method like JAXL0045::joinRoom(…)

Writing a command line XMPP bot (echobot) using Jaxl 2.0

In this blog post, we will write a sample XMPP bot (echobot) using Jaxl 2.0. In turn we will introduce ourselves to some of the basic functionality we can do using Jaxl e.g. fetching roster list, subscribing and unsubscribing to a user presence, etc. We will also focus on how to use XMPP extensions (XEP’s) inside our echobot code. Specifically, we will make use of XEP-0085 (chat state notification), XEP-0203 (delayed delivery) and XEP-0092 (software version) in our sample echobot application.

Echobot source code:
This sample echobot application comes packaged with Jaxl 2.0. If you have already read Installation, Usage guide and Running example apps, you might have even run this sample application.

Alternately, browse and download the sample source code from github echobot app files

Coding with Jaxl 2.0:
Every XMPP application developed using Jaxl 2.0, MUST have a jaxl.ini environment setup file inside your project directory. For example, packaged echobot sample application contains jaxl.ini which setup necessary Jaxl environment for our echobot application.

If you are developing an application from scratch, copy sample packaged jaxl.ini into your project folder:

cp /usr/share/php/jaxl/env/jaxl.ini /my/app/directory/jaxl.ini

and update JAXL_BASE_PATH and JAXL_APP_BASE_PATH with Jaxl installation path and your application directory path respectively.

Before we go on to write our echobot application code logic, lets see how an XMPP application code written using Jaxl 2.0 will generally look like:

<?php

        // Initialize Jaxl Library (#1)
        $jaxl = new JAXL();

        // Include required XEP's (#2)
        jaxl_require(array(
                'JAXL0085', // Chat State Notification
                'JAXL0092', // Software Version
                'JAXL0203'  // Delayed Delivery
        ), $jaxl);

        // Sample Echobot class (#3)
        class echobot {
                function startStream() {}
                function doAuth($mechanism) {}
                function postAuth() {}
                function getMessage($payloads) {}
                function getPresence($payloads) {}
        }
        $echobot = new echobot();

        // Add callbacks on various xmpp events (#4)
        JAXLPlugin::add('jaxl_post_connect', array($echobot, 'startStream'));
        JAXLPlugin::add('jaxl_get_auth_mech', array($echobot, 'doAuth'));
        JAXLPlugin::add('jaxl_post_auth', array($echobot, 'postAuth'));
        JAXLPlugin::add('jaxl_get_message', array($echobot, 'getMessage'));
        JAXLPlugin::add('jaxl_get_presence', array($echobot, 'getPresence'));

?>

Lets break down the above applications code structure (note the #1, #2, #3, #4 markers in the above code)

  • #1 – Create a new Jaxl instance inside your application. By doing so Jaxl core functionality and other utilities are made available inside your application code. You can also pass parameters while initializing Jaxl instance
    $jaxl = new JAXL(array(
            'user'    =>    'username',
            'pass'    =>    'password',
            'host'    =>    'talk.google.com',
            'domain' =>    'gmail.com',
            'port'    =>    5222
    ));

    Passed parameters will overwrite the values specified inside jaxl.ini file

  • #2 – Include required XMPP extensions (XEP’s) inside your application code. jaxl_require is a special method which makes sure that no Jaxl core class loads twice inside a running Jaxl instance.

    To include an implemented XEP inside your application code simply use:

    jaxl_require('JAXL0203', $jaxl);

    where 0203 is the XEP number for Delayed Delivery extension, which will help our echobot know if an incoming message is an offline message. If you wish to include more than one XEP inside your application code, simply pass the list of XEP’s as an array:

    jaxl_require(array(
    	'JAXL0085',
    	'JAXL0092',
    	'JAXL0203'
    ), $jaxl);

    where 0085 is xep number for Chat state notification extension and 0092 is the xep number for Software Version extension.

    Since version 2.1.0, jaxl_require MANDOTORY accepts Jaxl instance which require core classes, in this case $jaxl. It helps Jaxl core to keep a track of required core classes for every Jaxl instances in a multiple-instance application.

  • #3 – Now that we have Jaxl core and required XEP’s in our application environment, it’s time to write our application code logic. Application code MUST have methods which are called back by the Jaxl core when specific xmpp events occur during your application run time. Optionally, Jaxl core can pass parameters to these methods during callbacks.
  • #4 – In the final step, we will register callbacks for necessary xmpp events using JAXLPlugin class add() method inside our application logic. Syntax:
    JAXLPlugin::add($hook, $callback);

    In this example, we want to receive callbacks in our application code for following available hooks and events:

    1. jaxl_post_connect: After Jaxl has opened stream socket to the jabber server
    2. jaxl_get_auth_mech: When Jaxl have information about supported auth mechanisms by the jabber server
    3. jaxl_post_auth: After Jaxl finish authenticating the bot with the jabber server
    4. jaxl_get_message: When a new message stanza is received by Jaxl
    5. jaxl_get_presence: When a new presence stanza is received by Jaxl

Writing application logic:
Till now we have the registered callbacks for various xmpp events, it’s time to catch these callbacks inside our echobot class and implement the required functionality of our application. Below is an explanation for some of the important pieces inside echobot class:

  • startStream() method is called when jaxl_post_connect event occurs. For our application we will simply send XMPP start stream by calling $jaxl->startStream()
  • doAuth($mechanism) method is called when jaxl_get_auth_mech event occurs in Jaxl core. Jaxl core passes list of supported auth mechanism by the jabber server. Proceed with a preferred auth type by calling $jaxl->auth() method
  • postAuth() is called after Jaxl library has finished authenticating our application bot with the jabber server
  • getMessage($payloads) gets all new messages as they are received by Jaxl core
  • getPresence($payloads) gets all new presence as they are received by Jaxl core

Running Echobot:
Enter your application directory (/usr/share/php/jaxl/echobot). It MUST contain jaxl.ini, open and edit connecting echobot username, password and jabber host. Then from command line run echobot as follows:

root@ubuntu:/usr/share/pear/jaxl/app/echobot# jaxl echobot.php
== 5617 == [[2010-08-03 10:37:21]] Socket opened to the jabber host jaxl.im:5222 ...
== 5617 == [[2010-08-03 10:37:22]] Performing Auth type: DIGEST-MD5
== 5617 == [[2010-08-03 10:37:28]] Auth completed...

Jaxl 2.0 – Installation, Usage guide and Example apps

This blog post provides detailed instructions on how to download and setup Jaxl 2.0 for quick XMPP application development using PHP. We will also see how to run XMPP bots using Jaxl command line utility (now available by just typing jaxl on the terminal).

Get the source code
Jaxl 2.0 development version source code is available at github.

  • For better experience download latest stable tarball from google code
  • The development version of Jaxl is hosted here at Github, have fun cloning the source code with Git. If you are not familar with Git just use the download button to get a tarball.
    root@ubuntu:~/git# git clone git://github.com/abhinavsingh/JAXL.git

Warning: the development source code is only intended for people that want to develop Jaxl or absolutely need the latest features still not available on the stable releases.

Installation on *nix Systems
Extract the downloaded tarball and enter source directory. The available build.sh file will help us installing Jaxl library at a preferred location on our system. Type ./build.sh help to view help instructions:

root@ubuntu:~/git# cd JAXL
root@ubuntu:~/git/JAXL# ./build.sh help

Build file will default install Jaxl library core under /usr/share/php/jaxl and Jaxl command line at /usr/bin/jaxl. Open build script, edit PACKAGE_INSTALL_PATH and PACKAGE_BIN_PATH to configure installation paths.

Issue following commands to setup Jaxl library core and Jaxl command line utility:

root@ubuntu:~/git/JAXL# mkdir /usr/share/php/jaxl
root@ubuntu:~/git/JAXL# ./build.sh
building...
root@ubuntu:~/git/JAXL# ./build.sh install
uninstalling old package...
installing...
root@ubuntu:~/git/JAXL# touch /var/log/jaxl.log
root@ubuntu:~/git/JAXL# chown www-data /var/log/jaxl.log
root@ubuntu:~/git/JAXL# touch /var/run/jaxl.pid
root@ubuntu:~/git/JAXL# chown www-data /var/run/jaxl.pid

/var/log/jaxl.log is default log file for Jaxl applications and /var/run/jaxl.pid saves the process id (pid) of running Jaxl instances.

Usage guide
Now that we have setup Jaxl on our system, lets verify package installation by firing jaxl command line utility on the terminal:

root@ubuntu:~/git/JAXL# jaxl
Missing ini file...

If you get “Missing ini file” message, you have successfully verified package installation. This message is shown when current working directory doesn’t have jaxl.ini file, which is required by Jaxl cli utility before it can connects to a jabber server.

Running sample applications
Build script installs a sample application under /usr/share/php/jaxl/app/echobot directory. This directory contains two files namely:

  • echobot.php: Contains our echobot application code
  • jaxl.ini: It is application specific Jaxl configuration file

Open and update the following section inside jaxl.ini:

        // Connecting bot details
        define('JAXL_USER_NAME', 'username');
        define('JAXL_USER_PASS', 'password');

        // Connecting jabber server details
        define('JAXL_HOST_NAME', 'jabber.org');
        define('JAXL_HOST_PORT', 5222);
        define('JAXL_HOST_DOMAIN', 'jabber.org');

Now run the echobot from using jaxl cli utility:

root@ubuntu:/usr/share/php/jaxl/app/echobot# jaxl echobot.php
== 2946 == [[2010-08-02 14:37:53]] Socket opened to the jabber host jabber.org:5222 ...
== 2946 == [[2010-08-02 14:37:57]] Performing Auth type: DIGEST-MD5
== 2946 == [[2010-08-02 14:38:02]] Auth completed...

2946 is the process id of current running Jaxl instance. Same value can be found inside /var/run/jaxl.pid. Also tail the Jaxl log file for debug information:

root@ubuntu:~/git/JAXL# tail -f /var/log/jaxl.log
== 2946 == [[2010-08-02 14:38:02]] [[XMPPSend]] 123
chatOnline using Jaxl (Jabber XMPP Library in PHP)1

[[XMPPSend]] tells us that following XMPP packet was send by the Jaxl instance running with pid 2946. Also, total 123 bytes were transmitted over the socket.

Proceed to Writing your first command line bot using Jaxl for detailed explanation of the sample echobot application or if you are interested in building real-time web applications read Setup and Demo of Jaxl boshchat application