How to filter messages in Ejabberd

2019-01-17 22:13发布

问题:

I have Ejabberd up and running with test users, and its working fine. I want to write a module that can intercept messages and modify them, as follows :

  1. intercept "messages"
  2. send them to a php file
  3. get the result from the same php file (immediate)
  4. Modify the message stanza and send it down the wire to the recipient

The ejabberd documentation is weak and tutorials are non-existent. Can you give me some sample code that does this. I can then figure how to configure it for my needs.

Thanks a bundle!

Adil

回答1:

Here's the basic example of such module:

-module(packet_interceptor).
-behaviour(gen_mod).

-export([start/2,
         stop/1]).

-export([on_filter_packet/1]).


start(Host, _Opts) ->
    ejabberd_hooks:add(filter_packet, global, ?MODULE, on_filter_packet, 0).

on_filter_packet({From, To, XML} = Packet) ->
    %% does something with a packet
    %% should return modified Packet or atom `drop` to drop the packet
    Packet.

And make sure to add this module into ejabberd's configuration into module section:

{modules,
 [...
  ...
  ...
  {packet_interceptor, []}
 ]}.

Just extend on_filter_packet/1 the way you want and return appropriately modified packet.



回答2:

gleber's example is excellent. I also wrote a more complex example of packet manipulation that I built for Chesspark called mod_sunshine.

How can send this XML data to php (via ?xml=) and retrieve the resulting XML and then pass it to the recipient?

If you have a recent version of ejabberd that uses exmpp, you can use exmpp_xml:node_to_binary/1 or exmpp_xml:node_to_list/1 to turn the internal representation of the XML to a binary or a string respectively.

There were similarly named functions in the older ejabberd, but within the xml module.



回答3:

It seems that what you want to do there is to create an XMPP server component. Lots of things has already been said on that post Which XMPP server to experiment developing a server component.

I can link you some useful links:

  • Jabber Component Protocol

  • An Echo-Bot in Python from metajack.im, a very nice blog from an XMPP guru. This bot listen for any message stanzas and reply to some of them.

Gleber's solution is really "ejabberd" oriented (certainly the easiest one in your case), whereas this one can scale with other XMPP servers.



回答4:

There is the interface:

ejabberd_router:register_route(MyHost)

which I have used in the past and works well. Once the MyHost is registered with ejabberd, the module will receive the communications intended to MyHost through info messages (assuming gen_server).

As noted by @gleber, don't forget to add your module to the configuration file.