Grails Xmpp Plugin

  • Authors: null
1 vote
Dependency:
compile ":xmpp:0.1"

 Documentation

Summary

Installation

grails install-plugin xmpp

Description

Introduction

The xmpp plug-in provides xmpp/jabber/im based services to Grails applications easing the development of real-time xmpp based web applications (something similar to what friendfeed does). This is achieved by configuring a xmpp connection upon configuration properties. After installation each Grails application has its own Roster.

One of the most insteresting features is the ability to expose services methods as commands just by adding the expose static attribute. A service tagged as "xmpp exposer" is automatically turned into a PacketListener. And will properly delegate the message handling to a specific method following method names conventions.

Getting Started

Adding entries to Config.groovy

To get started, first, it's necessary to inform the details of your xmpp server (gtalk, jabber, etc). There is a little configuration required in your /conf/Config.groovy file. Find below 3 different configurations examples. Just set the properties according to your needs.

//configuration for jabber accounts
xmpp.autoStartup = true
xmpp.username="grails-xmpp"
xmpp.password="grails"
xmpp.connection.host="jabber.org"
xmpp.connection.port=5222
xmpp.connection.service="jabber.org"
xmpp.connection.SASLAuthenticationEnabled=true

//configuration for gtalk accounts xmpp.autoStartup = true xmpp.username="gtalkusername" xmpp.password="gtalkpwd" xmpp.connection.host="talk.google.com" xmpp.connection.port=5222 xmpp.connection.service="gmail.com" xmpp.connection.SASLAuthenticationEnabled=false

//configuration for googleapp accounts xmpp.autoStartup = true xmpp.username="username" xmpp.password="pwd" xmpp.connection.host="talk.google.com" xmpp.connection.port=5222 xmpp.connection.service="mydomain.com" xmpp.connection.SASLAuthenticationEnabled=false

Injected utility methods

The following methods are injected in all controllers and services:

sendXmppMessage( jabberId,  message )
changeXmppRosterStatus( newStatus )
addXmppContact( jabberId )
removeXmppContact( jabberId )
getAllXmppContacts()

jabberId can be a String or a List<String>

Exposing methods as commands

Another very nice feature is the ability to expose methods as commands (method name = command) making it easier to develop XmppBots, for example. In order to achieve this just add the famous exposes static attribute:

static expose = ['xmpp']

A service tagged as "xmpp exposer" is automatically turned into a PacketListener. And will properly delegate the message handling to a specific method following method names conventions.

Optionally you can also specify:

static xmppCommandPrefix = "!"
static xmppCommandMethodSuffix = ""
static listenerMethod = "handleDefaultXmppMessage"

In the example above, the message !list would be routed to a method called list or to handleDefaultXmppMessage in case the former didn't exist.

When not defined the default values are:

static xmppCommandPrefix = "@"
static xmppCommandMethodSuffix = "XmppCommand"
static listenerMethod = "onXmppMessage"

TODO: Better explain command suffix and prefix

package org.grails.xmpp

class DefaultXmppBotService {

boolean transactional = false

static expose = ['xmpp']

def helpXmppCommand(msg){ onXmppMessage(msg) }

def inviteXmppCommand(msg){ sendXmppMessage(msg.from, }

def listAllXmppCommand(msg){ def entries = getAllXmppContacts() sendXmppMessage(msg.from, entries) }

def onXmppMessage(m) { def help = """Available commands are: @help @invite @listAll """ sendXmppMessage(m.from, help) }

}

Auto detection of PacketListeners and RosterListeners

TODO Explain auto detection

PacketListener

package org.grails.xmpp

import org.jivesoftware.smack.PacketListener import org.jivesoftware.smack.packet.Packet

class PacketListenerImplementerService implements PacketListener {

boolean transactional = false

void processPacket(Packet packet) { println "Packet received: " + packet.toXML() }

}

RosterListener

package org.grails.xmpp

import org.jivesoftware.smack.RosterListener import org.jivesoftware.smack.packet.Presence

class RosterListenerImplementerService implements RosterListener {

boolean transactional = false

/** * Called when roster entries are added. */ void entriesAdded(Collection<String> addresses) { println addresses }

/** * Called when a roster entries are removed. */ void entriesDeleted(Collection<String> addresses) { println addresses }

/** * Called when a roster entries are updated. */ void entriesUpdated(Collection<String> addresses) { println addresses }

/** * Called when the presence of a roster entry is changed. */ void presenceChanged(Presence presence) { println presence.toXML() }

}

Future Enhancements

  • Instead of passing only the original message object to the command it'd be nice to start passing an args (+) parameter with the arguments properly parsed from the message body (including quoted arguments)

Known Issues

  • After configuration change and consequent reconnection the utility methods stop working. It's necessary a full application restart.

Version History

  • 0.1 - first official release