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サーバーがクライアントからスタンザを受信するたびに実行されます。これは、テスト方法にもよりますが、ハンドラーが実行されない理由を説明している可能性があります。MongooseIM のいくつかのフックを説明する 1 つのセクションを含む記事が、公式 wiki で入手できます。

パケット属性の取得に関する問題については、検査のために着信パケットをログに記録するかdbg、サーバーの Erlang シェルを使用して、モジュールによって行われた実際の呼び出しをトレースすることで、何が起こっているかを知ることができます。


問題をデバッグするセッションの例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 でモジュールを開始」しません。通常の方法でモジュールを起動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。これは、以前に追加したリストに表示されています。非常に優れた紹介が 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

exmlまたは、 MongooseIM の一部でもあり (元の ejabberd ではありません)、必要な属性が見つからないことをより明示的に示す which を使用することもできます。

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