02 May 2016, 09:39

XMPP Components in Go, Part 1

XMPP is a communications protocol specializing in messaging and presence, using XML as the underlying data format.

XMPP/Jabber components (XEP-0114) is a specification for extending the functionality of an XMPP server externally. Unlike a standard XMPP client, an XMPP component is trusted with additional functionality.

In practice, an XMPP component is represented by a domain. In our case our XMPP server will be ‘chat.local’ and our XMPP component will be under that: ‘$name.chat.local’. Any communication to an XMPP entity under that hostname will be forwarded to the component. We can define virtual users on the component by accepting messages directed to those users and generated presence messages for those users.

http://github.com/sheenobu/go-xco is a small library for writing XMPP components. The overriding messaging format is XML, however, your components communication is not tied to the XML format. In this tutorial, we will be using a mixture of plaintext, HTML, and JSON.

Lets look at a hello world component, that uppercases its input and responds:

import "github.com/sheenobu/go-xco"

c := xco.NewComponent(xco.Options{...})

// Uppercase Echo Component using the BodyResponseHandler helper function
c.MessageHandler = xco.BodyResponseHandler(func(msg *xco.Message) (string, error) {
    return strings.ToUpper(msg.Body), nil
})

// Run our component
c.Run()

Our component now runs in the foreground waiting for interactions from the upstream server.

We can operate on a raw message, providing asyncronous and formatted responses:

// Long form version of the uppercase Echo Component
c.MessageHandler = func(c *xco.Component, msg *xco.Message) error {
    resp := xco.Message{
        Header: xco.Header{
            From: msg.To,
            To:   msg.From,
            ID:   msg.ID,
        },
        Subject: msg.Subject,
        Thread:  msg.Thread,
        Type:    msg.Type,
        Body:    strings.ToUpper(msg.Body),
        XMLName: msg.XMLName,
    }

    return c.Send(resp)
}

Some Use Cases

See xmpp-usecases for some example use cases that were originally planned for this series of blog posts.

Next

  • In part 2, we will configure ejabberd and build a sample component.
  • In part 3, we will add presence and persistence support.