0

我为 MongooseIM 编写了以下模块,但没有任何内容发布到 PHP 文件中。

start(_Host, _Opt) -> 
    inets:start(),
    ejabberd_hooks:add(user_send_packet, _Host, ?MODULE, fetchPacketData, 50).
stop (_Host) -> 
    ejabberd_hooks:delete(user_send_packet, _Host, ?MODULE, fetchPacketData, 50).
fetchPacketData(_From, _To, Packet) ->
    To = xml:get_tag_attr_s(<<"to">>, Packet),
    httpc:request(post, {"http://example.com/receiver.php",[],
            "application/x-www-form-urlencoded",
            lists:concat(["To=",To,"&Type=1","&Body=ABC"])}, [], []).

在遵循 erszcz 的建议后,我能够成功实现该模块(请参见下文)。下面是我使用的代码。希望它对其他人也有帮助:)

start(Host, _Opts)->
  inets:start(),
  ejabberd_hooks:add(user_send_packet, Host, ?MODULE, sendMessage, 50),
  ok.
stop(Host)->
  ejabberd_hooks:delete(user_send_packet, Host, ?MODULE, sendMessage, 50),
  ok.
sendMessage(_From, _To, Packet) ->
  case xml:get_tag_attr_s(<<"type">>, Packet) of
    <<"chat">> ->
      To = lists:flatten(io_lib:format("~s", [xml:get_tag_attr_s(<<"to">>, Packet)])),
      ** post variables to PHP file using httpc:request **
      ok;
    _ ->
      ok
    end.
4

1 回答 1

0

offline_message_hook仅当服务器将消息路由给不在线的用户时才调用。user_send_packet每次服务器从客户端接收到节时运行。这可以解释为什么处理程序没有运行,尽管它取决于您如何测试。官方 wiki 上有一篇文章,其中一节描述了 MongooseIM 中的一些钩子。

至于检索数据包属性的问题,要么记录传入的数据包以供检查,要么dbg在服务器 Erlang shell 中使用来跟踪模块完成的实际调用,这可能是判断发生了什么的方法。


调试问题的示例会话dbg可能如下所示:

(mongooseim@localhost)1> dbg:tracer().
{ok,<0.570.0>}
(mongooseim@localhost)2> dbg:p(all, call).
{ok,[{matched,mongooseim@localhost,279}]}
(mongooseim@localhost)3> dbg:tpl(mod_test, x).
{ok,[{matched,mongooseim@localhost,5},{saved,x}]}
(mongooseim@localhost)4> (<0.576.0>) call mod_test:fetchPacketData({jid,<<"alice">>,<<"localhost">>,<<"escalus-default-resource">>,<<"alice">>,
     <<"localhost">>,<<"escalus-default-resource">>},{jid,<<"alice">>,<<"localhost">>,<<>>,<<"alice">>,<<"localhost">>,<<>>},{xmlel,<<"presence">>,[{<<"xml:lang">>,<<"en">>}],[]})
(<0.576.0>) exception_from {mod_test,fetchPacketData,3} {error,function_clause}
2015-03-15 11:46:03.028 [error] <0.576.0>@ejabberd_hooks:run1:240 {function_clause,[{lists,thing_to_list,[<<>>],[{file,"lists.erl"},{line,601}]},{lists,flatmap,2,[{file,"lists.erl"},{line,1248}]},{lists,flatmap,2,[{file,"lists.erl"},{line,1248}]},{mod_test,fetchPacketData,3,[{file,"src/mod_test.erl"},{line,15}]},{safely,apply,3,[{file,"src/safely.erl"},{line,19}]},{ejabberd_hooks,run1,3,[{file,"src/ejabberd_hooks.erl"},{line,236}]},{ejabberd_c2s,session_established2,2,[{file,"src/ejabberd_c2s.erl"},{line,1063}]},{p1_fsm_old,handle_msg,10,[{file,"src/p1_fsm_old.erl"},{line,542}]}]}
    Running hook: {user_send_packet,[{jid,<<"alice">>,<<"localhost">>,<<"escalus-default-resource">>,<<"alice">>,<<"localhost">>,<<"escalus-default-resource">>},{jid,<<"alice">>,<<"localhost">>,<<>>,<<"alice">>,<<"localhost">>,<<>>},{xmlel,<<"presence">>,[{<<"xml:lang">>,<<"en">>}],[]}]} 
    Callback: mod_test:fetchPacketData

我们看到处理程序function_clause在调用lists:thing_to_list(<<>>). 空二进制文件是xml:get_tag_attr_s/2未找到所要求的属性的结果。lists:thing_to_list/1调用将每个参数转换lists:concat/1为列表,但不可能将空二进制转换<<>>为列表,因此崩溃。

匹配结果xml:get_tag_attr_s/2并针对每种情况制定适当的逻辑:何时找到属性,何时不存在。


我不知道如何在 dbg 中启动模块。我尝试了您在上面分享的内容,我认为您错过了第四个命令,这可能是如何启动模块的示例。

这是我的控制台的原始转储,没有任何编辑 - 我没有错过任何部分。您不会“在 dbg 中启动模块”。您只需以通常的方式启动一个模块,然后dbg从服务器外壳中使用。

我所做的是将您的示例代码放入apps/ejabberd/src/mod_test.erl文件中并构建了一个版本。之后,您可以在ejabberd.cfg发行版中启用模块(查找该modules部分并按照此处显示的示例进行类似操作),或者您可以在实时模式下启动服务器mongooseimctl live并手动启动模块gen_mod:start_module(<<"localhost">>, mod_test, [])(其中<<"localhost">>只是一个示例 XMPP 域- 在那里替换您自己合适的域)。

当模块运行时(可以用 进行检查gen_mod:is_loaded(<<"your-xmpp-domain">>, mod_name_goes_here)),您必须启用dbg. 这显示在我之前添加的清单中。我不会深入描述如何使用dbg,因为StackOverflow 上已经有很好的介绍


如何测试属性是否存在的示例

case xml:get_tag_attr_s(<<"some-attribute">>, Packet) of
    <<>> ->
        %% attribute does not exist, as get_tag_attr_s returned the default value
        ok;
    <<"some-value">> ->
        %% do something sensible with <<"some-value">>
        ok
end

或者,您可以使用exml它也是 MongooseIM 的一部分(但不是原始 ejabberd),并且更明确地指出找不到您要求的属性:

case exml_query:attr(Packet, <<"some-attribute">>) of
    undefined ->
        %% not found
        ok;
    <<"some-value">> ->
        %% do something
        ...
end
于 2015-03-15T10:26:19.737 回答