2017-02-03 6 views
1

私はオフラインメッセージが受信された場合、この機能を起動するというコードにフックがあります。erlang、ejabberd、対処する方法

offline_msg_received(From, To, Packet) -> 

パケットは、コードのように探しています

{message,<<"purple2d957668">>,chat,<<>>,undefined,{jid,<<"admin">>,<<"localhost">>,<<"5280">>,<<"admin">>,<<"localhost">>,<<"5280">>},[],[{text,<<>>,<<"Hello">>}],undefined,[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]}],#{}} 

私はこのうちたかった何を私のメッセージを含む部分です。これは次のとおりです。

[{text,<<>>,<<"Hello">>}] 

この部分は、パッケージ変数全体と一致するパターンで取得できます。しかし、私のメッセージと一致するパターンを試したとき、それは悪い議論をしています。

{text,<<>>,<<"Hello">>} 

と変数を指定すると、そのパターンマッチングが可能であることがわかります。私の理解から、何かの周りにある[]を見ることは、それがリストまたは文字列であることを意味します。

私はここにいくつかのコードを示すことができます。今

{P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11} = Packet, %% P8 is the message I want. 
?INFO_MSG("----------------------P8: ~p~n", P8), %% This shows {text,<<>>,<<"Hello">>} 
{A, B, C} = P8, %% This gives me a badmatch error. 

私が代わりにコードのシェルで手動でこれを実行した場合、:

{text,<<>>,<<"Hello">>} = P8, 
{A, B, C} = P8, 

その後のコードは動作し、C変数に< <「こんにちは」>>置きます。

私の推測では、 "Package"変数の中の[]は私のbadmatchエラーと関係がありますが、何らかの理由でそれらのシンボルが表示されません。誰も良い提案をなぜそれが動作しませんか?私はそれが隠された[]と関係があると推測しています。そうでなければ、私のシェルコードテストと同じに見えるからです。

ありがとうございました。これは初めての質問ですので、間違ったことはしないことを願っています。

答えて

3

あなたINFO_MSG呼び出しで値の周りに角括弧を見ていない理由はINFO_MSGは値だけではなく、単一の値のリストを期待していることです。上記のコードでは、フォーマット文字列には単一のディレクティブしか含まれていないため、値は1つの要素のリストであるため、大括弧が黙って削除されるのはこのためです。

%% two arguments 
io:format("~p ~p\n", [foo, bar]). 
%% one argument - we still need square brackets 
io:format("~p\n", [foo]). 

あなたはこれをやっているハードな方法:) messagetextがレコードに定義されています。あなたはシェルでこれを試してみることができるように

INFO_MSGマクロ作品にio:formatと同じで、 xmpp_codec.hrl。あなたがシェルにロードされたレコード定義を持っていない場合、レコードは要素の多くが付いているタプルのように見えるが、あなたはレコード定義をロードする場合は、あなたのメッセージは、代わりに次のようになります。

1> rr("include/xmpp_codec.hrl"). 
[address,addresses,adhoc_actions,adhoc_command,adhoc_note, 
bind,block,block_list,bob_data,bookmark_conference, 
bookmark_storage,bookmark_url,bytestreams,caps, 
carbons_disable,carbons_enable,carbons_private, 
carbons_received,carbons_sent,chatstate,client_id,compress, 
compress_failure,compressed,compression,csi,db_feature, 
db_result,db_verify|...] 
2> {message,<<"purple2d957668">>,chat,<<>>,undefined,{jid,<<"admin">>,<<"localhost">>,<<"5280">>,<<"admin">>,<<"localhost">>,<<"5280">>},[],[{text,<<>>,<<"Hello">>}],undefined,[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]}],#{}}. 
#message{id = <<"purple2d957668">>,type = chat,lang = <<>>, 
     from = undefined, 
     to = {jid,<<"admin">>,<<"localhost">>,<<"5280">>, 
        <<"admin">>,<<"localhost">>,<<"5280">>}, 
     subject = [], 
     body = [#text{lang = <<>>,data = <<"Hello">>}], 
     thread = undefined, 
     sub_els = [{xmlel,<<"active">>, 
          [{<<"xmlns">>, 
          <<"http://jabber.org/protocol/chatstates">>}], 
          []}], 
     meta = #{}} 

あなたがデータを探しているのはbodyです。

はのは、変数Mにこのレコードを割り当てると体のフィールドを抽出してみましょう:

4> Body = M#message.body. 
[#text{lang = <<>>,data = <<"Hello">>}] 

だから、1つのtextのレコードを含むリストです。のは、そこからdataフィールドを抽出してみましょう:

それはシェルの中でどのように動作するかだ
6> [#text{data = Data}] = Body. 
[#text{lang = <<>>,data = <<"Hello">>}] 
7> Data. 
<<"Hello">> 

からrr機能付きレコード定義をロードします。レコード定義を使用するモジュールを書くとき、あなたはhrlファイルをインクルードする必要があるだろう:

-include_lib("xmpp/include/xmpp_codec.hrl"). 

-include_libディレクトリがロードパス上のxmppアプリケーションを探し、そしてそのincludeディレクトリ内のファイルxmpp_codec.hrlを検索します。コンパイラへのコードパスを指定する必要があります。erlc -pa path/to/xmpp/ebin my_module.erlなど - アプリケーション内のebinディレクトリがコードパス上にある必要があります。

+1

'#message.body'からテキストを取得するには、' xmpp:get_text/1'や 'xmpp:get_text/2'関数を使うのが良いでしょう。後者は、言語でテキストを選択する必要がある場合に便利です。 別のポイントは、 'xmpp_codec.hrl'を直接インクルードするべきではないということです。代わりに 'xmpp.hrl'をインクルードしてください。 – user2610053

関連する問題