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

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

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

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

谢谢你!

阿迪尔

【问题讨论】:

    标签: erlang hook 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已经说了很多事情。

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

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

    【讨论】:

    • 感谢元杰克。我之前读过你的文章。它帮助我开始了
    猜你喜欢
    • 2016-07-17
    • 1970-01-01
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    • 2015-08-07
    • 2022-01-17
    • 2013-01-10
    • 2014-09-19
    相关资源
    最近更新 更多