Groupchat for Your WordPress website

Hello kids, in this episode of Sesame Street we learn the letters ‘M’ for MongooseIM, ‘G’ for GroupChat and ‘X’ for XMPP. We assume you should already know letters ‘W’ for WordPress and ‘S’ for (My)SQL and you are just looking for a method to embed a groupchat on your website.

Sure, there are many WordPress plugins for doing this but the ones that allow you to choose your own Jabber server are usually paid or simply don’t match your concept. You can benefit from this tutorial in two ways:

  1. You already have a chat plugin but you’d like to host your own Jabber server for better control.
  2. You have some programming skills and you need a guide on how to integrate your custom solution with Jabber.

In first case, you’d probably be limited to plain old username/password authentication unless you have some really cool plugin that integrates with your site’s sessions. In second case you’ll be able to create a really nice integration but you will need at least moderate knowledge of JavaScript, PHP and CSS is required.

This tutorial assumes you have no previous knowledge of XMPP and Erlang. Of course it’s always better to know at least some basics but don’t worry – you can make it. πŸ™‚ Also you need to be quite comfortable with Linux console and basic administrative tasks.

Preparing the server

For our setup, we’ll use MongooseIM, which is an ejabberd server fork we developed at Erlang Solutions. The recently released version (1.2.2) doesn’t have a WordPress plugin yet (most probably it will be included in next release) so we’ll need to build MongooseIM from sources. Instructions below are for Fedora 17; They should be similar for any RedHat-based Linux. For Debian/Ubuntu you’ll need to install equivalents of yum’s packages.

OK, I assume you already have WordPress installed and MySQL database created. Important: Auth plugin assumes that your WordPress tables have wp_ prefix!
Now, follow these steps:

  1. Install Erlang using the instructions from Erlang Solutions website.
  2. Install essential packages & tools:
    # yum install git gcc expat-devel openssl-devel pam-devel
  3. Checkout MongooseIM repo:
    git clone git://github.com/esl/ejabberd.git
    and enter ejabberd directory.
  4. Checkout WordPress branch:
    git checkout wordpress
  5. Edit rel/vars.config and adjust following parameters:
    • hosts: can by anything but most convenient would be the same domain as your website has
    • odbc_server: remove %% at the beginning and enter your WordPress database config; it is recommended to create separate user just for MongooseIM and limit its privileges to read-only, but using the same account both for WordPress and Jabber will work just fine
    • auth_method: set it to [wordpress, internal] or [wordpress, anonymous, internal], should you need to allow guests to access the chat
    • wp_logged_in_key, wp_logged_in_salt: enter exactly the same values as you’ve entered in wp-config.php
  6. Execute make rel and wait… πŸ™‚
  7. Now in folder rel/ejabberd you have a standalone MongooseIM instance ready to be used with both ordinary Jabber clients, Websockets or BOSH (AJAX calls encapsulating Jabber requests); you can move this folder anywhere you want and start it with any user
  8. You can start the server with rel/ejabberd/bin/ejabberd start and stop with rel/ejabberd/bin/ejabberd stop

What about SSL?

Adding SSL support requires some additional steps. Let’s say you have your certificate already or use steps 1-4 from this site to create self-signed one. You’ll need to prepare three files (all in PEM format):

  • with both private key certificate; if you used tutorial above, do
    cat server.crt server.key > server.pem
    Private key in this file must not be protected by password
  • with private key only (server.key)
  • with certificate only (server.crt)

You may keep them anywhere you want, as long as the user running MongooseIM has read privileges for them. Now we start with editing rel/vars.config:

  • tls_config: remove %% at the beginning and set path to the file with both private key and certificate
  • wss_config: remove %% (don’t remove the comma, it’s there on purpose!) and enter paths to the files plus key password

BOSH doesn’t support SSL connections yet, so above configuration is for ordinary Jabber connection and Websockets.

And it’s done! Now you can execute make rel again to rebuild the release. If you get following error during rebuild:

ERROR: Failed to generate target from spec: "copy file /usr/lib/
    erlang/erts-5.9.3.1/bin/epmd -> /home/mongoose/ejabberd/rel/
    ejabberd/erts-5.9.3.1/bin/epmd: text file or pseudo-device busy\n"
ERROR: Unexpected error: rebar_abort
ERROR: generate failed while processing /home/mongoose/ejabberd/rel:
    rebar_abort

just execute killall epmd and don’t worry. πŸ™‚

Here are ports used by MongooseIM. You might need them for configuring your client and firewall.
Ordinary Jabber: 5222
BOSH: 5280
Websockets: 5288
Websockets Secure: 5289

Creating rooms

The easiest way to manage rooms is to use ordinary Jabber client to connect to the server. My personal choice for development is Psi, as it comes with good XML Console but any other will also do the trick.

  1. Install Psi client. Assuming you’re using some graphical environment on your Fedora box:
    # yum install psi
  2. On first launch Psi will ask you if you want to create an account. Choose option for existing account.
  3. If such startup window didn’t pop up, navigate to General->Account Setup and press Add
  4. Call your new account whatever you like, for example “Site Admin”
  5. Your Jabber ID is [Wordpress admin username]@[XMPP domain], e.g. admin@localhost
  6. Your Password is the same as you use for WordPress account
  7. If you haven’t enabled SSL in MongooseIM config, switch to Connection tab and in Allow plaintext authentication select Always
  8. Now go online and after Psi connects, select General->Join Groupchat
  9. Your Host is muc.[XMPP domain], e.g. muc.localhost
  10. Choose any room name and nickname you like and click Join
  11. In new window click a button with an arrow pointing down (it’s in upper right corner) and select Configure Room
  12. Switch to General tab. Most default settings are nice enough but it’s important to Make room persistent and set some room title. Then click Apply and Close

Repeat above steps with joining a room and configuring it for every room you’d like to be available for your users. There you go! Now the only thing left is to configure web client…

Client-side configuration

Connecting with ordinary Jabber client is easy. Enter username, domain, password and you’re there. But what if we would like to integrate chat with WordPress (or any other CMS/MVC framework) session system?

Good news: we can use “logged in” cookie! The name is wordpress_logged_in_[site name hash here]. The bad news is, it’s HttpOnly cookie, so it cannot be accessed via JavaScript. This means a bit of coding in PHP. We will create our example using MUCkl, which you can obviously customize to match your site look and feel. It is not a very active project but modifying it is quite simple, so it’s good learning material. πŸ™‚

  1. Clone MUCkl repository (original software created by Stefan Strigler, my fork modified it a bit for sake of this tutorial):
    git clone git://github.com/fenek/MUCkl.git
  2. Clone JSJaC repository:
    git clone git://github.com/sstrigler/JSJaC.git
  3. Enter JSJaC directory and just run make
  4. Copy jsjac.js to [MUCkl dir]/lib/jsjac/
  5. Enter MUCkl directory and create config file:
    cp config.js.example config.js
  6. Edit configuration:
    • BACKENDTYPE: set it to binding if you’d like to have the same chat open across multiple pages or websockets if your groupchat is designed to be unique for specific page (e.g. discussion under video stream) and you don’t care if users of some browsers won’t be able to use your chat.
    • HTTPBASE: should be http://your.host.name:5280/http-bind/ or if you’ve chosen to use Websockets: ws://your.host.name:5288/ws-xmpp (should begin with wss:// if you configured SSL)
    • XMPPDOMAIN: set it to the same value as you’ve entered in hosts in vars.config
    • AUTHTYPE: set it to sasl if you want to login with username and password or saslanon for anonymous authentication; you can also make the value generated by PHP based on user status:
      <?php
      global $user_login;
      
      if($user_login == '')
        $authtype = 'saslanon';
      else
        $authtype = 'sasl';
      ?>
      
      var AUTHTYPE='<?php echo $authtype; ?>';
    • MUCKLJID, MUCKLPASS: if you’re using saslanon authentication, you don’t need to bother with it; you can hardcode this parameter but the best solution is to generate values (again) with PHP:
      <?php
      global $user_login;
      ?>
      var MUCKLJID='<?php echo $user_login; ?>';
      var MUCKLPASS='<?php echo $_COOKIE["wordpress_logged_in_"
                                     .COOKIEHASH; ?>';
    • Add MUCKLNICK below MUCKLPASS: this will be specific user’s nick in rooms; You can always set it to:
      var MUCKLNICK = MUCKLJID;
    • ROOMS: Using the template in config file, create a list of rooms to which your users will be able to connect; default server for your setup is muc.[xmpp_domain]
  7. Done! If you chose to use some PHP, follow steps below. If not, you can open muckl.html in your browser and enjoy your chat. πŸ™‚
  8. Easiest way of embedding the groupchat in WordPress page is to insert iframe into post/page content:
    <iframe style="display: block; width: 966px; height: 400px;"
                    src="http://path/to/your/MUCkl/muckl.html?room=[room ID]">

    where [room ID] is the sequence number of room entry in config.js starting at 0; if you want to allow users to choose room, just skip ?room= in URL

What if I used PHP in config file?

  1. First of all, you need to rename config.js to config.js.php
  2. Replace old config file name in index.html:8, muckl.html:9 and groupchat.html:9
  3. At the beginning of config.js.php add:
    <?php
    include_once '../wp-config.php';
    include_once '../wp-includes/pluggable.php';
    include_once '../wp-includes/default-constants.php';
    ?>
  4. Copy MUCkl folder into WordPress root dir

Conclusion

That’s all. Maybe it’s not a short process but unfortunately custom solutions always cost more time than generic ones. This is not the last post about MongooseIM & Web integration. Next one will describe some more advanced aspects of configuration and another will cover WordPress plugin still under development, which you may observe already as Erlang Central Cafe chatbox.

The only downside of the current wordpress branch is that the groupchat module there is experimental and even though it passes unit tests, it is still not considered stable yet. The “experimental” part is possibility of single user joining room from multiple tabs but with the same nick. Original groupchat module doesn’t allow such behaviour and as you might guess – it is quite vital.

Have a nice programming session! πŸ˜‰

Advertisements
This entry was posted in Erlang, MongooseIM, XMPP and tagged , , , , . Bookmark the permalink.

One Response to Groupchat for Your WordPress website

  1. Great article! Do you know of how to get secure websockets working? I’ve been trying for hours and I can’t seem to do it. The TLS works for the xmpp side of things, but when I try to wss to any of the cowboy ports it just doesn’t work 😦

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s