我为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.
答案 0 :(得分:0)
offline_message_hook
。每次服务器从客户端收到节时,都会运行user_send_packet
。这可能解释了为什么处理程序没有运行,尽管它取决于你如何测试。官方维基上有an article with one section describing some hooks in MongooseIM。
至于检索数据包属性的问题,要么记录传入的数据包以供检查,要么在服务器Erlang shell中使用dbg
来跟踪模块执行的实际调用,这可能是告诉我们的问题的方法。发生。
调试问题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中启动模块。我尝试了你上面分享的内容,我认为你错过了第4个命令,它可能是一个如何启动模块的例子。
这是我的控制台的原始转储,没有任何编辑 - 我没有错过任何部分。
你不必在dbg中启动一个模块。&#34;您只需以常规方式启动模块,然后从服务器shell使用dbg
。
我所做的是我将您的示例代码放入apps/ejabberd/src/mod_test.erl
文件并构建了一个版本。之后,您可以在版本的ejabberd.cfg
中启用该模块(查找modules
部分,并按照示例中的示例进行操作),或者您可以使用{{1}以实时模式启动服务器并使用mongooseimctl live
手动启动模块(其中gen_mod:start_module(<<"localhost">>, mod_test, [])
只是一个示例XMPP域 - 在那里替换您自己合适的域名。)
当模块运行时(可以使用<<"localhost">>
进行检查),您必须启用gen_mod:is_loaded(<<"your-xmpp-domain">>, mod_name_goes_here)
。这在我之前添加的列表中显示。我没有深入研究如何将dbg
用作a very good introduction is already available on StackOverflow。
如何测试属性是否存在的示例
dbg
或者,您可以使用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
,它也是MongooseIM的一部分(但不是原始的ejabberd),并且更明确地没有找到您要求的属性:
exml