esl / MongooseIM

MongooseIM is Erlang Solutions' robust, scalable and efficient XMPP server, aimed at large installations. Specifically designed for enterprise purposes, it is fault-tolerant and can utilise the resources of multiple clustered machines.
Other
1.64k stars 422 forks source link

Custom module not working #1805

Closed sandeepjangir closed 5 years ago

sandeepjangir commented 6 years ago

MongooseIM version: 2.1.1 Installed from: Ubuntu package Erlang/OTP version: the one that comes with 2.1.1

I have created one custom module for calling one REST api, but module is not working and mongooseim crashing.

Crash logs:

Problem starting the module mod_sendpush for host <<"localhost">> options: [{url,"https://rapi.ngageapp.com/index.php/apipush/sendpush"}] error: undef [{mod_sendpush,start, [<<"localhost">>, [{url,"https://rapi.ngageapp.com/index.php/apipush/sendpush"}]], []}, {gen_mod,start_module,3, [{file,"/home/ubuntu/MongooseIM/_build/prod/lib/mongooseim/src/gen_mod.erl"}, {line,113}]}, {lists,foreach,2,[{file,"lists.erl"},{line,1337}]}, {ejabberd_app,start,2, [{file,"/home/ubuntu/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_app.erl"}, {line,70}]}, {application_master,start_it_old,4, [{file,"application_master.erl"},{line,273}]}]

module code: mod_sendpush


-module(mod_sendpush).
-author('sandeep@techsbiz.com').

-behaviour(gen_mod).

-export([start/2,
         stop/1,
     send_notice/3]).

-define(PROCNAME, ?MODULE).

-include("mongoose.hrl").
-include("mongoose_logger.hrl").
-include("jlib.hrl").

start(Host, _Opts) ->
    inets:start(),
    ssl:start(),
    ?INFO_MSG("Starting mod_sendpush", [] ),
    ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, send_notice, 10),

ok.

stop(Host) ->
    ejabberd_hooks:delete(offline_message_hook, Host, ?MODULE, send_notice, 10),
     ?INFO_MSG("Stopping mod_sendpush", [] ),

ok.

send_notice(From, To, Packet) ->

    Type = xml:get_tag_attr_s(<<"type">>, Packet),
    MessageId = xml:get_tag_attr_s(<<"id">>, Packet),
    Body = xml:get_path_s(Packet, [{elem, <<"body">>}, cdata]),
    Chat_sent =  xml:get_tag_attr_s(list_to_binary("chat_sent"), Packet),
    Subject = xml:get_path_s(Packet, [{elem, list_to_binary("subject")}, cdata]),
    PostUrl = gen_mod:get_module_opt(To#jid.lserver, ?MODULE, url, [] ),
    Xml_without_quots = re:replace(Packet,"\"","\\\"",[global,{return,list}]),
    ?INFO_MSG("Sending  push......", [] ),

    if (Body /= <<"">>) ->
        Sep = "&",
        Post = [
            "from=", From#jid.luser, Sep,
            "to=", To#jid.luser, Sep,
            "body=", binary_to_list(Body), Sep,
            "type=", binary_to_list(Type),Sep,
            "chat_sent=", binary_to_list(Chat_sent),Sep,
            "subject=",binary_to_list(Subject),Sep,
            "message_id=", binary_to_list(MessageId),Sep,
            "xml=",binary_to_list(xml:element_to_binary(Xml_without_quots)),Sep,
            "App_id=6001"
        ],
        ?INFO_MSG("Sending post request to ~s with body \"~s\"", [PostUrl, Post]),
        httpc:request(post, {PostUrl, [], "application/x-www-form-urlencoded", list_to_binary(Post)},[],[]),
        ok;
      true ->
        ok
    end.

%%% The following url encoding code is from the yaws project and retains it's original license.
%%% https://github.com/klacke/yaws/blob/master/LICENSE
%%% Copyright (c) 2006, Claes Wikstrom, klacke@hyber.org
%%% All rights reserved.
url_encode([H|T]) when is_list(H) ->
    [url_encode(H) | url_encode(T)];
url_encode([H|T]) ->
    if
        H >= $a, $z >= H ->
            [H|url_encode(T)];
        H >= $A, $Z >= H ->
            [H|url_encode(T)];
        H >= $0, $9 >= H ->
            [H|url_encode(T)];
        H == $_; H == $.; H == $-; H == $/; H == $: -> % FIXME: more..
            [H|url_encode(T)];
        true ->
            case integer_to_hex(H) of
                [X, Y] ->
                    [$%, X, Y | url_encode(T)];
                [X] ->
                    [$%, $0, X | url_encode(T)]
            end
     end;

url_encode([]) ->
    [].

integer_to_hex(I) ->
    case catch erlang:integer_to_list(I, 16) of
        {'EXIT', _} -> old_integer_to_hex(I);
        Int         -> Int
    end.

old_integer_to_hex(I) when I < 10 ->
    integer_to_list(I);
old_integer_to_hex(I) when I < 16 ->
    [I-10+$A];
old_integer_to_hex(I) when I >= 16 ->
    N = trunc(I/16),
    old_integer_to_hex(N) ++ old_integer_to_hex(I rem 16).

ejabberd.cfg file Configuration

{mod_sendpush, [{url, "https://restapiurl"}]},

Is anything missing , or is this a known issue? Please let me know.

kzemek commented 6 years ago

Hi @sandy5487

Where is mod_sendpush.erl located? More importantly, where is the compiled mod_sendpush.beam module?

sandeepjangir commented 6 years ago

Hi @kzemek

mod_sendpush.erl is located in MongooseIM/src/ folder and after compiling it, the mod_sendpush.beam is located in MongooseIM/_build/default/lib/mongooseim/ebin/mod_sendpush.beam

Copied it to /home/ubuntu/MongooseIM/_build/prod/lib/mongooseim/ebin/mod_sendpush.beam

sandeepjangir commented 6 years ago

Hi @kzemek @fenek

any update on this?

kzemek commented 6 years ago

@sandy5487 You mentioned that you installed MongooseIM from the Ubuntu package, but you put the module into a local directory which suggests a source build. Is that correct?

If you want to add a compiled module to the MongooseIM installed from the package, you have to copy the .beam file into /usr/lib/mongooseim/lib/mongooseim-2.1.1/ebin directory.

sandeepjangir commented 6 years ago

Hi @kzemek

Apologies for the incorrect information. I have compiled MongooseIM from source and not installed from package. Hence after compiling the mod_sendpush.erl, the beam file located at MongooseIM/_build/default/lib/mongooseim/ebin/mod_sendpush.beam was copied to MongooseIM/_build/prod/lib/mongooseim/ebin/ folder.

I hope the location mentioned above is correct.

Thanks

kzemek commented 6 years ago

How did you compile MongooseIM? Instead of copying the .beam file manually to production directories I'd recommend running make rel in /home/ubuntu/MongooseIM directory, which will do everything for you.

Please note that the production release uses _build/prod/rel/mongooseim/lib/mongooseim-*/ebin/ and not _build/prod/lib/mongooseim/ebin/ (the files from where are copied into release directories during the release process).

fenek commented 6 years ago

To rephrase what @kzemek has recommended: when you add custom modules to MongooseIM please either create a new project with MongooseIM as a dependency (harder) or put your extra source file in src/ and build the release in usual way (./rebar3 compile and make rel, easier way). Manually copying files between lib directories is always risky.

sandeepjangir commented 6 years ago

Hi @kzemek

I followed your instructions and it seems working but I am not able to hit my custom REST API and getting these logs whenever I fire any message:

[error] <0.1623.0>@ejabberd_hooks:run_fold1:264 {undef,[{mod_sendpush,send_notice,[#{attrs => [{<<"type">>,<<"chat">>},{<<"id">>,<<"purple1fdc47ec">>},{<<"to">>,<<"918128184101@abc.ngageapp.com">>}],element => {xmlel,<<"message">>,[{<<"type">>,<<"chat">>},{<<"id">>,<<"purple1fdc47ec">>},{<<"to">>,<<"918128184101@abc.ngageapp.com">>}],[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]},{xmlel,<<"body">>,[],[{xmlcdata,<<"?">>}]}]},from => <<"sandeep@abc.ngageapp.com/Sandeeps-MacBook-Pro">>,from_jid => {jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>},mongoose_acc => true,name => <<"message">>,ref => #Ref<0.2898403463.3160408067.245273>,result => allow,server => <<"abc.ngageapp.com">>,timestamp => {1524,228236,305909},to => <<"918128184101@abc.ngageapp.com">>,to_jid => {jid,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>},type => <<"chat">>,user => <<"sandeep">>,{cached_privacy_check,<<"abc.ngageapp.com">>,<<"sandeep">>,<<"sandeep@abc.ngageapp.com/Sandeeps-MacBook-Pro">>,<<"918128184101@abc.ngageapp.com">>,<<"message">>,<<"chat">>,out} => allow},{jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>},{jid,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>},{xmlel,<<"message">>,[{<<"type">>,<<"chat">>},{<<"id">>,<<"purple1fdc47ec">>},{<<"to">>,<<"918128184101@abc.ngageapp.com">>}],[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]},{xmlel,<<"body">>,[],[{xmlcdata,<<"?">>}]},{xmlel,<<"stanza-id">>,[{<<"by">>,<<"918128184101@abc.ngageapp.com">>},{<<"id">>,<<"AQI71AAJK101">>},{<<"xmlns">>,<<"urn:xmpp:sid:0">>}],[]}]}],[]},{safely,apply,3,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/safely.erl"},{line,19}]},{ejabberd_hooks,hook_apply_function,5,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,278}]},...]} running hook: {offline_message_hook,[{jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>},{jid,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>},{xmlel,<<"message">>,[{<<"type">>,<<"chat">>},{<<"id">>,<<"purple1fdc47ec">>},{<<"to">>,<<"918128184101@abc.ngageapp.com">>}],[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]},{xmlel,<<"body">>,[],[{xmlcdata,<<"?">>}]},{xmlel,<<"stanza-id">>,[{<<"by">>,<<"918128184101@abc.ngageapp.com">>},{<<"id">>,<<"AQI71AAJK101">>},{<<"xmlns">>,<<"urn:xmpp:sid:0">>}],[]}]}]}

Where is the problem?

Thanks

fenek commented 6 years ago

send_notice callback in this module is not compatible with current hooks API. The function head should be send_notice(Acc, From, To, Packet) and it should return Acc as a function result.

sandeepjangir commented 6 years ago

Hi @fenek

I have tried your soltution and it showing me this console logs:

2018-04-20 16:54:27.723 [error] <0.1623.0>@ejabberd_hooks:run_fold1:264 {badarg,[{re,replace,[{xmlel,<<"message">>,[{<<"type">>,<<"chat">>},{<<"id">>,<<"purplea42af699">>},{<<"to">>,<<"918128184101@abc.ngageapp.com">>}],[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]},{xmlel,<<"body">>,[],[{xmlcdata,<<"push ?">>}]},{xmlel,<<"stanza-id">>,[{<<"by">>,<<"918128184101@abc.ngageapp.com">>},{<<"id">>,<<"AQIAHA31M6O1">>},{<<"xmlns">>,<<"urn:xmpp:sid:0">>}],[]}]},"\"","\\\"",[global,{return,list}]],[{file,"re.erl"},{line,362}]},{mod_sendpush,send_notice,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/mod_sendpush.erl"},{line,48}]},{safely,apply,3,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/safely.erl"},{line,19}]},{ejabberd_hooks,hook_apply_function,5,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,278}]},{ejabberd_hooks,run_fold1,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,261}]},{ejabberd_hooks,run_fold,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,146}]},{ejabberd_sm,do_route,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_sm.erl"},{line,613}]},{ejabberd_sm,route,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_sm.erl"},{line,150}]}]} running hook: {offline_message_hook,[{jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>},{jid,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>},{xmlel,<<"message">>,[{<<"type">>,<<"chat">>},{<<"id">>,<<"purplea42af699">>},{<<"to">>,<<"918128184101@abc.ngageapp.com">>}],[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]},{xmlel,<<"body">>,[],[{xmlcdata,<<"push ?">>}]},{xmlel,<<"stanza-id">>,[{<<"by">>,<<"918128184101@abc.ngageapp.com">>},{<<"id">>,<<"AQIAHA31M6O1">>},{<<"xmlns">>,<<"urn:xmpp:sid:0">>}],[]}]}]}

And my send_notice is edited now. Please have a look:

`send_notice(Acc, From, To, Packet) ->

    Type = xml:get_tag_attr_s(<<"type">>, Packet),
    MessageId = xml:get_tag_attr_s(<<"id">>, Packet),
    Body = xml:get_path_s(Packet, [{elem, <<"body">>}, cdata]),
    Chat_sent =  xml:get_tag_attr_s(list_to_binary("chat_sent"), Packet),
    Subject = xml:get_path_s(Packet, [{elem, list_to_binary("subject")}, cdata]),
    PostUrl = gen_mod:get_module_opt(To#jid.lserver, ?MODULE, url, [] ),
    Xml_without_quots = re:replace(Packet,"\"","\\\"",[global,{return,list}]),
    ?INFO_MSG("Sending  push......", [] ),

    if (Body /= <<"">>) ->
        Sep = "&",
        Post = [
            "from=", From#jid.luser, Sep,
            "to=", To#jid.luser, Sep,
            "body=", binary_to_list(Body), Sep,
            "type=", binary_to_list(Type),Sep,
            "chat_sent=", binary_to_list(Chat_sent),Sep,
            "subject=",binary_to_list(Subject),Sep,
            "message_id=", binary_to_list(MessageId),Sep,
            "xml=",binary_to_list(xml:element_to_binary(Xml_without_quots)),Sep,
            "App_id=6001"
        ],
        ?INFO_MSG("Sending post request to ~s with body \"~s\"", [PostUrl, Post]),
        httpc:request(post, {PostUrl, [], "application/x-www-form-urlencoded", list_to_binary(Post)},[],[]),
        ok;
      true ->
        ok
    end,

Acc.`

P.S.: I am new to Erlang

fenek commented 6 years ago

This code has a bug, maybe there is a fork that is better maintained?

Anyway, please try to change

Xml_without_quots = re:replace(Packet,"\"","\\\"",[global,{return,list}])

into

Xml_without_quots = re:replace(exml:to_binary(Packet),"\"","\\\"",[global,{return,list}])

sandeepjangir commented 6 years ago

Hi @fenek

After changing the code line I am getting the same error logs.

2018-04-21 09:14:47.268 [error] <0.1623.0>@ejabberd_hooks:run_fold1:264 {undef,[{xml,element_to_binary,["<message type='chat' id='purplece139e31' to='918128184101@abc.ngageapp.com'><active xmlns='http://jabber.org/protocol/chatstates'/><body>testing mod_sendpush</body><stanza-id by='918128184101@abc.ngageapp.com' id='AQIO7HOI4FO1' xmlns='urn:xmpp:sid:0'/></message>"],[]},{mod_sendpush,send_notice,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/mod_sendpush.erl"},{line,64}]},{safely,apply,3,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/safely.erl"},{line,19}]},{ejabberd_hooks,hook_apply_function,5,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,278}]},{ejabberd_hooks,run_fold1,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,261}]},{ejabberd_hooks,run_fold,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,146}]},{ejabberd_sm,do_route,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_sm.erl"},{line,613}]},{ejabberd_sm,route,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_sm.erl"},{line,150}]}]} running hook: {offline_message_hook,[{jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Air">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Air">>},{jid,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>},{xmlel,<<"message">>,[{<<"type">>,<<"chat">>},{<<"id">>,<<"purplece139e31">>},{<<"to">>,<<"918128184101@abc.ngageapp.com">>}],[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]},{xmlel,<<"body">>,[],[{xmlcdata,<<"testing mod_sendpush">>}]},{xmlel,<<"stanza-id">>,[{<<"by">>,<<"918128184101@abc.ngageapp.com">>},{<<"id">>,<<"AQIO7HOI4FO1">>},{<<"xmlns">>,<<"urn:xmpp:sid:0">>}],[]}]}]}

fenek commented 6 years ago

The error is not the same. :) This time is about xml:element_to_binary call. It should be removed and the line actually should be

"xml=",Xml_without_quots,Sep,

sandeepjangir commented 6 years ago

Hi @fenek
Thanks for the comment, the module is running now but the API is only calling when the receiver is offline. According to me, I didn't mention this thing anywhere in the code.

Any update on this?

kzemek commented 6 years ago

The send_notice/4 function is registered as a callback for offline_message_hook:

start(Host, _Opts) ->
    inets:start(),
    ssl:start(),
    ?INFO_MSG("Starting mod_sendpush", [] ),
    ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, send_notice, 10),

offline_message_hook is only run when the recipient is offline. You can look through the documentation for other hooks that better suit your use case.

sandeepjangir commented 6 years ago

Hi @kzemek

Thanks for the noticing this thing, I need to call the send_notice/4 function each time whenever a user sends any message in one to one chat as well in muclight chat.

Thanks

sandeepjangir commented 6 years ago

Hi @kzemek @fenek

According to my study I think I should add ejabberd_hooks:add(user_send_packet, Host, ?MODULE, send_notice, 89) instead of ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, send_notice, 10),.

am I right according to my requirement ?

Regards Sandeep

sandeepjangir commented 6 years ago

Hi @fenek

I have changed the ejabberd hook and now I am getting these error logs in live mode.

[error] <0.1627.0>@ejabberd_hooks:run_fold1:264 {undef,[{mod_sendpush,send_notice,[ok,<<"abc.ngageapp.com">>,390423398193229313,179,{jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>},{jid,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>},{jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>},outgoing,{xmlel,<<"message">>,[{<<"type">>,<<"chat">>},{<<"id">>,<<"purpled7b349d">>},{<<"to">>,<<"918128184101@abc.ngageapp.com">>}],[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]},{xmlel,<<"body">>,[],[{xmlcdata,<<"heyy">>}]}]}],[]},{safely,apply,3,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/safely.erl"},{line,19}]},{ejabberd_hooks,hook_apply_function,5,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,278}]},{ejabberd_hooks,run_fold1,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,261}]},{ejabberd_hooks,run_fold,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,146}]},{mod_mam,archive_message,8,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/mod_mam.erl"},{line,690}]},{mod_mam,handle_package,6,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/mod_mam.erl"},{line,586}]},{mod_mam,user_send_packet,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/mod_mam.erl"},{line,284}]}]} running hook: {mam_archive_message,[<<"abc.ngageapp.com">>,390423398193229313,179,{jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>},{jid,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>},{jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>},outgoing,{xmlel,<<"message">>,[{<<"type">>,<<"chat">>},{<<"id">>,<<"purpled7b349d">>},{<<"to">>,<<"918128184101@abc.ngageapp.com">>}],[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]},{xmlel,<<"body">>,[],[{xmlcdata,<<"heyy">>}]}]}]}

This is my updated source code

%%%----------------------------------------------------------------------

%%% File    : mod_sendpush
%%% Author  : Sandeep Jangir
%%% Purpose : Forward offline messages to HTTP Push API
%%% Created : 16 Apr 2018 by Sandeep
%%%
%%%----------------------------------------------------------------------

-module(mod_sendpush).
-author('sandeep@techsbiz.com').

-behaviour(gen_mod).

-export([start/2,
         stop/1,
     send_notice/4]).

-define(PROCNAME, ?MODULE).

-include("mongoose.hrl").
-include("mongoose_logger.hrl").
-include("jlib.hrl").

start(Host, _Opts) ->
    inets:start(),
    ssl:start(),
    ?INFO_MSG("~n mod_sendpush in start() method : Host =  ~p and _Opts = ~p ~n ",[Host, _Opts]),
    %% ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, send_notice, 10),
    ejabberd_hooks:add(mam_archive_message, Host, ?MODULE, send_notice, 50),
ok.

stop(Host) ->
    %% ejabberd_hooks:delete(offline_message_hook, Host, ?MODULE, send_notice, 10),
    case gen_mod:get_module_opt(Host, ?MODULE, no_writer, false) of
        true ->
            ok;
        false ->
            ejabberd_hooks:delete(mam_archive_message, Host, ?MODULE, archive_message, 50)
    end,
    ?INFO_MSG("Stopping mod_sendpush", [] ),

ok.

send_notice(Acc, From, To, Packet) ->

    MessageBody = xml:get_path_s(Packet, [{elem, <<"body">>}, cdata]),

    if (MessageBody /= <<"">>) ->

        ?INFO_MSG("Sending  push......", [] ),
        PostUrl = "https://myapiurl",
        Type = xml:get_tag_attr_s(<<"type">>, Packet),
        MessageId = xml:get_tag_attr_s(<<"id">>, Packet),
        Body = xml:get_path_s(Packet, [{elem, <<"body">>}, cdata]),
        Chat_sent =  xml:get_tag_attr_s(list_to_binary("chat_sent"), Packet),
        Subject = xml:get_path_s(Packet, [{elem, list_to_binary("subject")}, cdata]),
        Xml_without_quots = re:replace(exml:to_binary(Packet),"\"","\\\"",[global,{return,list}]),

          Sep = "&",

        Post = [
            "from=", From#jid.luser,Sep,
            "to=", To#jid.luser,Sep,
            "body=", binary_to_list(Body),Sep,
            "type=", binary_to_list(Type),Sep,
            "chat_sent=", binary_to_list(Chat_sent),Sep,
            "subject=",binary_to_list(Subject),Sep,
            "message_id=", binary_to_list(MessageId),Sep,
            "xml=",Xml_without_quots,Sep,
            "App_id=6001"
        ],

        ?INFO_MSG("Sending post request to ~s with body \"~s\"", [PostUrl, Post]),
        httpc:request(post, {PostUrl, [], "application/x-www-form-urlencoded", list_to_binary(Post)},[],[]),
        ok;
      true ->
        ok
    end,

Acc.

%%% The following url encoding code is from the yaws project and retains it's original license.
%%% https://github.com/klacke/yaws/blob/master/LICENSE
%%% Copyright (c) 2006, Claes Wikstrom, klacke@hyber.org
%%% All rights reserved.
url_encode([H|T]) when is_list(H) ->
    [url_encode(H) | url_encode(T)];
url_encode([H|T]) ->
    if
        H >= $a, $z >= H ->
            [H|url_encode(T)];
        H >= $A, $Z >= H ->
            [H|url_encode(T)];
        H >= $0, $9 >= H ->
            [H|url_encode(T)];
        H == $_; H == $.; H == $-; H == $/; H == $: -> % FIXME: more..
            [H|url_encode(T)];
        true ->
            case integer_to_hex(H) of
                [X, Y] ->
                    [$%, X, Y | url_encode(T)];
                [X] ->
                    [$%, $0, X | url_encode(T)]
            end
     end;

url_encode([]) ->
    [].

integer_to_hex(I) ->
    case catch erlang:integer_to_list(I, 16) of
        {'EXIT', _} -> old_integer_to_hex(I);
        Int         -> Int
    end.

old_integer_to_hex(I) when I < 10 ->
    integer_to_list(I);
old_integer_to_hex(I) when I < 16 ->
    [I-10+$A];
old_integer_to_hex(I) when I >= 16 ->
    N = trunc(I/16),
    old_integer_to_hex(N) ++ old_integer_to_hex(I rem 16).
fenek commented 6 years ago

When you subscribe to a mam_archive_message hook, the callback head is completely different. Please check e.g. mod_mam_odbc_arch for reference. :)

sandeepjangir commented 6 years ago

@fenek

I have made some changes in my erl file but still I am getting these errors:

Changes that I have made:

start(Host, _Opts) ->
    inets:start(),
    ssl:start(),
    ?INFO_MSG("~n mod_sendpush in start() method : Host =  ~p and _Opts = ~p ~n ",[Host, _Opts]),
    %% ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, send_notice, 10),
    %% ejabberd_hooks:add(mam_archive_message, Host, ?MODULE, send_notice, 50),
    case gen_mod:get_module_opt(Host, ?MODULE, no_writer, false) of
        true ->
            ok;
        false ->
            ejabberd_hooks:add(mam_archive_message, Host, ?MODULE, send_notice, 50)
    end,
ok.

stop(Host) ->
    %% ejabberd_hooks:delete(offline_message_hook, Host, ?MODULE, send_notice, 10),
    case gen_mod:get_module_opt(Host, ?MODULE, no_writer, false) of
        true ->
            ok;
        false ->
            ejabberd_hooks:delete(mam_archive_message, Host, ?MODULE, send_notice, 50)
    end,
    ?INFO_MSG("Stopping mod_sendpush", [] ),

ok.

Error logs:

[error] <0.1623.0>@ejabberd_hooks:run_fold1:264 {undef,[{mod_sendpush,send_notice,[ok,<<"abc.ngageapp.com">>,390426747754117889,179,{jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>},{jid,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>},{jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>},outgoing,{xmlel,<<"message">>,[{<<"type">>,<<"chat">>},{<<"id">>,<<"purplec17578c1">>},{<<"to">>,<<"918128184101@abc.ngageapp.com">>}],[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]},{xmlel,<<"body">>,[],[{xmlcdata,<<"hii">>}]}]}],[]},{safely,apply,3,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/safely.erl"},{line,19}]},{ejabberd_hooks,hook_apply_function,5,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,278}]},{ejabberd_hooks,run_fold1,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,261}]},{ejabberd_hooks,run_fold,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/ejabberd_hooks.erl"},{line,146}]},{mod_mam,archive_message,8,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/mod_mam.erl"},{line,690}]},{mod_mam,handle_package,6,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/mod_mam.erl"},{line,586}]},{mod_mam,user_send_packet,4,[{file,"/root/MongooseIM/_build/prod/lib/mongooseim/src/mod_mam.erl"},{line,284}]}]}
running hook: {mam_archive_message,[<<"abc.ngageapp.com">>,390426747754117889,179,{jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>},{jid,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>,<<"918128184101">>,<<"abc.ngageapp.com">>,<<>>},{jid,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>,<<"sandeep">>,<<"abc.ngageapp.com">>,<<"Sandeeps-MacBook-Pro">>},outgoing,{xmlel,<<"message">>,[{<<"type">>,<<"chat">>},{<<"id">>,<<"purplec17578c1">>},{<<"to">>,<<"918128184101@abc.ngageapp.com">>}],[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]},{xmlel,<<"body">>,[],[{xmlcdata,<<"hii">>}]}]}]}
sandeepjangir commented 6 years ago

@fenek @kzemek any review on this ?

sandeepjangir commented 6 years ago

need help on urgent basis

kzemek commented 6 years ago

https://github.com/esl/MongooseIM/issues/1805#issuecomment-385437273 still stands - please check mod_mam_odbc_arch for reference on what arguments do you need to handle for mam_archive_message hook.

The error message tells you that Erlang did not find mod_sendpush:send_notice that takes 9 arguments. You have an implementation of send_notice that takes 4 arguments.

sandeepjangir commented 6 years ago

Thanks @kzemek and @fenek

issue has been solved.