Grails Xmpp Plugin
Dependency :
compile ":xmpp:0.1"
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()
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']static xmppCommandPrefix = "!" static xmppCommandMethodSuffix = "" static listenerMethod = "handleDefaultXmppMessage"
static xmppCommandPrefix = "@" static xmppCommandMethodSuffix = "XmppCommand" static listenerMethod = "onXmppMessage"
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 detectionPacketListener
package org.grails.xmppimport org.jivesoftware.smack.PacketListener import org.jivesoftware.smack.packet.Packetclass PacketListenerImplementerService implements PacketListener { boolean transactional = false void processPacket(Packet packet) { println "Packet received: " + packet.toXML() }}
RosterListener
package org.grails.xmppimport org.jivesoftware.smack.RosterListener import org.jivesoftware.smack.packet.Presenceclass 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