Building Ejabberd Modules - Part 2 - Generic Modules

Published on: 17 Jul 2008 by Anders Conbere

Continued from Building Ejabberd Modules - Part 1 - Compiling Erlang

Ejabberd uses a plugin system based on Erlang modules. All Ejabberd Plugins implement the "genmod" behavior (or the genmod interface if not explicitly evoking the behavior). Behaviors are simple methods within Erlang to protect an interface, which can be used (as is the case with many of the OTP behaviors) to encapsulate a certain set of functionality.

The genmod behavior required by all Ejabberd modules is exceptionally simple, and is defined in the <a href="http://www.process-one.net/en/wiki/ejabberdmodule_development/">ejabbed module documentation.

start(Host, Opts) -> ok

stop(Host) -> ok

* Host = string()

* Opts = [{Name, Value}]

* Name = Value = string()

Note: The module name must match the filename. (Thanks Damon!)

A sample ejabberd module would then look something like this:

-module(my_module).

-author("Anders Conbere").

-behavior(gen_mod).

-include("ejabberd.hrl").
-export([start/2, stop/1]).
start(_Host, _Opt) -> ok.

stop(_Host) -> ok.

Most of the time however you'll be implementing a set of particular callbacks to match up with the requirements of internal processes. As an example when making HTTP modules, you'll need to export the process function which captures an HTTP request, and returns an HTTP response. The set of callbacks for a custom auth module are slightly more complex, but are still rather straight forward.

So with a little bit of editing we could turn the example above into a completely useless but installable module. To do that let's first edit the start function to output a debug message.

start(_Host, _Opt) -> 
    ?DEBUG("EXAMPLE MODULE LOADING", []).

We'll now want to save and compile our file (let's call it modfirstmodule.erl). To compile the module run this command.

$ erlc -I ~/path/to/ejabberd/src mod_first_module.erl

Or if you're running ejabberd trunk

$ erlc -I ~/path/to/ejabberd/include mod_first_module.erl

This will build the file modfirstmodule.beam a byte-compiled Erlang file capable of being run on the Erlang beam interpreter. And finally we'll want to put this file on a path that can be sourced by ejabberd. For most people that will mean linking it into the ejabberd bin directory.

/var/lib/ejabberd/ebin $ ln -s /path/to/mod_first_module.beam

And last but not least you need to tell Ejabberd to start your module when it begins. So we'll edit the ejabberd.cfg file and add to the modules config

{modules,
[
  {mod_adhoc,    []},
  ...
  {mod_first_module, []},% to send options to your module populate the [] list
  ...
]
}

now when we restart our ejabbed server (making sure that the loglevel is set to 5), we should see in the module loading phase.

=INFO REPORT==== 2008-07-17 15:33:27 === D(<0.37.0>:ejabberdauthmy_auth:44) : EXAMPLE MODULE LOADING

And there you have it, pretty much the most basic ejabberd module you could possibly install.