1

私は、offline_message_hook でトリガーされる MongooseIM モジュールを作成しようとしています。ユーザーのオフライン ストレージで保留中のメッセージの数をカウントし、GET メソッドを介して URL に送信します。以下は私のコードです。

send_notice(From, To, Packet) ->
    Type = xml:get_tag_attr_s(list_to_binary("type"), Packet),
    Body = xml:get_path_s(Packet, [{elem, list_to_binary("body")}, cdata]),
    PostUrl = "http://myurl.com/",
    Count = count_msg(To),
    GetParam = "?count=",
    FullUrl = PostUrl ++ GetParam ++ Count,

    ?DEBUG("POST URL : ~s",[FullUrl]),

    if (Type == <<"chat">>) and (Body /= <<"">>) ->
              Sep = "&",
        Post = [
          "alert=", url_encode(binary_to_list(Body)), Sep,
                                        "badge=", url_encode("+1"), Sep,
          % "sound=", Sound, Sep,
          "channel=", To#jid.luser, Sep,
          "info[from]=", From#jid.luser, Sep],
          % "auth_token=", Token],

        ?INFO_MSG("Sending post request to ~s with body \"~s\"", [FullUrl, Post]),

        httpc:request(post, {binary_to_list(FullUrl), [], "application/x-www-form-urlencoded", list_to_binary(Post)},[],[]),
        ok;
      true ->
        ok
    end.

count_msg(To) ->
     Username = To#jid.luser,
     LServer = To#jid.lserver,
     Count = ejabberd_odbc:sql_query(
      LServer,
      ["select count(*) from offline_message "
       "where username='", Username, "';"]),
     ?DEBUG("Count = ~s",[Count]),
     Count.

実行すると、以下のエラーが表示されます

2015-03-09 16:37:11.598 [debug] <0.763.0>@mod_zeropush:count_msg:102 FORMAT ERROR: "Count = ~s" [{selected,[<<"count">>],[{<<"5">>}]}]
["select count(*) from offline_message where username='",<<"reader">>,"';"]
2015-03-09 16:37:11.599 [debug] <0.763.0>@mod_zeropush:send_notice:72 FORMAT ERROR: "POST URL : ~s" [[104,116,116,112,58,47,47,107,107,104,97,110,46,100,108,99,119,111,114,108,100,119,105,100,101,46,99,111,109,47,63,99,111,117,110,116,61|{selected,[<<"count">>],[{<<"5">>}]}]]
2015-03-09 16:37:11.599 [info] <0.763.0>@mod_zeropush:send_notice:84 FORMAT ERROR: "Sending post request to ~s with body \"~s\"" [[104,116,116,112,58,47,47,107,107,104,97,110,46,100,108,99,119,111,114,108,100,119,105,100,101,46,99,111,109,47,63,99,111,117,110,116,61|{selected,[<<"count">>],[{<<"5">>}]}],["alert=","xxx","&","badge=","%2B1","&","channel=",<<"reader">>,"&","info[from]=",<<"kkhan">>,"&"]]
2015-03-09 16:37:11.602 [error] <0.763.0>@ejabberd_hooks:run1:240 {badarg,[{erlang,binary_to_list,[[104,116,116,112,58,47,47,107,107,104,97,110,46,100,108,99,119,111,114,108,100,119,105,100,101,46,99,111,109,47,63,99,111,117,110,116,61|{selected,[<<"count">>],[{<<"5">>}]}]],[]},{mod_zeropush,send_notice,3,[{file,"src/mod_zeropush.erl"},{line,86}]},{safely,apply,3,[{file,"src/safely.erl"},{line,19}]},{ejabberd_hooks,run1,3,[{file,"src/ejabberd_hooks.erl"},{line,236}]},{ejabberd_sm,route,3,[{file,"src/ejabberd_sm.erl"},{line,108}]},{ejabberd_local,route,3,[{file,"src/ejabberd_local.erl"},{line,139}]},{ejabberd_router,route,3,[{file,"src/ejabberd_router.erl"},{line,78}]},{ejabberd_c2s,session_established2,2,[{file,"src/ejabberd_c2s.erl"},{line,1098}]}]}

SQLクエリの結果をerlangで取得する適切な方法は何ですか? httpc:request はどのような形式を期待していますか?

4

1 に答える 1

2

表示されるエラーは、正確には SQL または MongooseIM 固有のエラーではありません。io_lib:format/2これらは、または同様の文字列書式設定関数の誤った使用です。

このエラー:

2015-03-09 16:37:11.598 [debug] <0.763.0>@mod_zeropush:count_msg:102 FORMAT ERROR: "Count = ~s" [{selected,[<<"count">>],[{<<"5">>}]}]

に関し:

?DEBUG("Count = ~s", [Count])

ただしCount、文字列でもバイナリでも iolist でもアトムでもありません (これらの型のみを使用して出力できます~s- 文字列書式設定文字; man iofunctionformat/3を参照してください)。デフォルトの Erlang 用語構文を使用して複雑な用語を出力するには、~pまたはを使用してください~w

あなたのFORMAT ERRORエラーはすべてこの種のものです - 渡すデータ型に間違ったフォーマット指定子を使用しています.

では、SQL クエリの結果の形式は何ですか? エラー行の 1 つに出力されます。

{selected, [<<"count">>], [{<<"5">>}]}

これは、SQL シェルで得られるものを簡単に音訳したものです (この例は、私が PostgreSQL で手元に持っていたランダム テーブルからのものです)。

> SELECT count(*) FROM conversation_state;
 count
-------
     2
(1 row)

以下は、Erlang シェルからの同等の実行です。

> ejabberd_odbc:sql_query(<<"localhost">>, ["SELECT count(*) FROM conversation_state;"]).
{selected,[<<"count">>],[{<<"2">>}]}

したがって、結果は常に 3 タプルになります。最初の要素はselected(またはinsertedupdatedクエリに応じて ...) です。2 番目の要素は列ヘッダーのリストです (ここでは列が 1 つだけありますcount)。3 番目の要素はタプルのリストで、各タプルは結果セットの 1 行に対応します。rows-as-tuples の要素は、列ヘッダーと同じ順序です。

最後のエラーについて:

2015-03-09 16:37:11.602 [error] <0.763.0>@ejabberd_hooks:run1:240 {badarg,[{erlang,binary_to_list,[[104,116,116,112,58,47,47,107,107,104,97,110,46,100,108,99,119,111,114,108,100,119,105,100,101,46,99,111,109,47,63,99,111,117,110,116,61|{selected,[<<"count">>],[{<<"5">>}]}]],[]},{mod_zeropush,send_notice,3,[{file,"src/mod_zeropush.erl"},{line,86}]},{safely,apply,3,[{file,"src/safely.erl"},{line,19}]},{ejabberd_hooks,run1,3,[{file,"src/ejabberd_hooks.erl"},{line,236}]},{ejabberd_sm,route,3,[{file,"src/ejabberd_sm.erl"},{line,108}]},{ejabberd_local,route,3,[{file,"src/ejabberd_local.erl"},{line,139}]},{ejabberd_router,route,3,[{file,"src/ejabberd_router.erl"},{line,78}]},{ejabberd_c2s,session_established2,2,[{file,"src/ejabberd_c2s.erl"},{line,1098}]}]}

FullUrl = PostUrl ++ GetParam ++ Counttoで作成したリストを渡そうとしていerlang:binary_to_list/1ます。名前が示すように、この関数はリストではなくバイナリを取ります。Erlang は動的ですが、厳密に型付けされており、暗黙的な型変換はほとんどありません。SQL クエリの結果を適切にアンパックし、数値だけを返し、そこからcount_msgHTTP 要求 URL を構築します。

于 2015-03-10T10:05:05.540 に答える