如何在Ejabberd中过滤消息

14

我已经成功运行了Ejabberd并创建了测试用户,目前一切正常。我想编写一个模块,可以拦截并修改消息,具体要求如下:

  1. 拦截“messages”
  2. 将它们发送到一个php文件
  3. 立即从同一个php文件中获取结果
  4. 修改消息语句并将其发送给接收方

Ejabberd的文档非常简单,教程几乎不存在。你能否提供一些完成这件事的样例代码?我会自己配置以满足我的需求。

谢谢!

Adil

4个回答

14

以下是这种模块的基本示例:

-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.

并且请确保将此模块添加到ejabberd的配置文件中的module部分:

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

只需按照您想要的方式扩展on_filter_packet/1,并返回适当修改后的数据包即可。


谢谢gleber。我已经走了这么远,从INFO_MSG中可以看出我的packet_interceptor正在被调用。如何将此XML数据发送到php(通过?xml=<base64编码字符串>),并检索生成的XML,然后将其传递给接收者? - Adil
2
你应该使用http:request/1,2,3来调用你的PHP脚本。如果我没记错,on_filter_packet将在ejabberd路由器进程中调用,因此你不应该在那里做任何耗时的操作。因此,一个解决方案是为此生成一个新进程,返回一个drop原子(以丢弃数据包),并在从PHP返回修改后的stanza时使用ejabberd_router:route(From, To, Packet)发送它。可能会再次调用on_filter_packet处理你发送的新数据包,所以请确保检测到它并且不要重复处理。 - gleber
为了检测数据包,您可以在数据包中添加带有自己的xmlns<x/>标签。 - gleber
@gleber 在 start/2 方法返回后,模块的进程不会被杀死(执行完成)吗?这里难道不需要使用 gen_server 模块吗? - Talespin_Kit

1

gleber 的示例非常棒。我也写了一个更复杂的数据包操作示例,为 Chesspark 构建了 mod_sunshine

如何将这个 XML 数据发送到 PHP(通过 ?xml=),并检索生成的 XML,然后将其传递给收件人?

如果你使用的是使用 exmpp 的最新版本的 ejabberd,你可以使用 exmpp_xml:node_to_binary/1 或者 exmpp_xml:node_to_list/1 将 XML 的内部表示转换成二进制或字符串。

在旧版的 ejabberd 中也有类似命名的函数,但位于 xml 模块中。


谢谢metajack。我之前读过你的文章,它帮助我入门了。 - Adil

0

看起来您想要做的是创建一个XMPP服务器组件。关于这个话题已经有很多讨论哪个XMPP服务器可以实验开发服务器组件

我可以给您提供一些有用的链接:

Gleber的解决方案确实是“ejabberd”导向的(在您的情况下肯定是最简单的),而这个解决方案可以与其他XMPP服务器一起扩展使用。


它是以ejabberd为导向的,因为问题就是这样的 ;) - gleber

0

这里有一个接口:

ejabberd_router:register_route(MyHost)

我过去使用过它,效果很好。一旦MyHost在ejabberd中注册成功,模块将通过info消息(假设使用gen_server)接收到发送给MyHost的通信。

正如@gleber所指出的,不要忘记将您的模块添加到配置文件中。


1
嗨,jldupont。我不太明白register_route的作用以及MyHost具体是什么。你能告诉我应该在哪里阅读更多相关信息吗? - Adil
ejabberd_router:register_route/1 用于创建自己的(子)域并捕获发送到该(子)域中JID的所有数据包。 您可以在此处阅读更多信息 - http://www.process-one.net/en/wiki/ejabberd_route_table/ - gleber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接