如何在 Ejabberd 中过滤消息

Posted

技术标签:

【中文标题】如何在 Ejabberd 中过滤消息【英文标题】:How to filter messages in Ejabberd 【发布时间】:2010-12-28 17:36:31 【问题描述】:

我已启动 Ejabberd 并与测试用户一起运行,它运行良好。我想写一个可以拦截消息并修改它们的模块,如下:

    拦截“消息” 将它们发送到 php 文件中 从同一个 php 文件中获取结果(立即) 修改消息节并将其通过网络发送给收件人

ejabberd 文档薄弱,教程也不存在。你能给我一些执行此操作的示例代码吗?然后我可以弄清楚如何根据需要对其进行配置。

谢谢你!

阿迪尔

【问题讨论】:

【参考方案1】:

这是此类模块的基本示例:

-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 并返回经过适当修改的数据包。

【讨论】:

谢谢格莱伯。我已经走了这么远,我可以从 ?INFO_MSG 看到我的 packet_interceptor 正在被调用。如何将此 XML 数据发送到 php(通过 ?xml=)并检索生成的 XML,然后将其传递给收件人? 您可能应该使用 http:request/1,2,3 来调用您的 PHP 脚本。 IIRC on_filter_packet 将在与 ejabberd 的路由器进程相同的进程中被调用,所以你不应该在那里做任何太耗时的事情。所以一个解决方案是为此产生一个新进程,返回一个drop atom(丢弃数据包),当从PHP返回修改的节时,使用ejabberd_router:route(From, To, Packet)发送它。很可能 on_filter_packet 会在你发送的新数据包上被再次调用,所以一定要检测到它,不要处理两次。 要检测数据包,您可以将<x/>标签添加到带有您自己的xmlns的数据包中。 @gleber 从 start/2 方法返回后,模块的进程不会被杀死(完成执行)。这里是不是需要用到gen_server模块?【参考方案2】:

看来您要做的是创建一个 XMPP 服务器组件。那个帖子Which XMPP server to experiment developing a server component已经说了很多事情。

我可以给你一些有用的链接:

Jabber Component Protocol

An Echo-Bot in Python 来自 metajack.im,来自 XMPP 大师的一个非常好的博客。此机器人侦听任何消息节并回复其中一些。

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

【讨论】:

问题是面向 ejabberd 的;)【参考方案3】:

有接口:

ejabberd_router:register_route(MyHost)

我过去使用过并且效果很好。一旦MyHost 被ejabberd 注册,模块将接收到MyHostinfo 消息的通信(假设gen_server)。

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

【讨论】:

你好 jldupont。我不太明白 register_route 的作用以及 MyHost 的作用。你能指出我应该进一步阅读的地方吗? ejabberd_router:register_route/1 用于创建您自己的(子)域并捕获发送到此(子)域中 JID 的所有数据包。你可以在这里阅读更多 - process-one.net/en/wiki/ejabberd_route_table【参考方案4】:

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 模块中。

【讨论】:

感谢元杰克。我之前读过你的文章。它帮助我开始了

以上是关于如何在 Ejabberd 中过滤消息的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ejabberd 中撤回消息?

如何在 Ejabberd 中归档消息并存储在 MongoDB 中

如何在 ejabberd 中的 xmpp 消息正文中附加自定义数据

如何在 ejabberd 上为 muc(多用户聊天)设置不同的消息间隔?

从 ejabberd 检索聊天记录时如何识别已发送和未发送的消息?

如何使用 XMPPFramework 从 ejabberd 中删除两个用户之间的特定消息?