Ejabberd - undef module not found when using hook

143 views Asked by At

I'm learning to use Hooks to build an Ejabberd module. This is the tutorial I'm referring. Following is my code:-

-module(mod_sunshine).

-behavior(gen_mod).

-include("ejabberd.hrl").
-include("logger.hrl").

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

start(_Host, _Opts) ->
    ?INFO_MSG("mod_sunshine starting", []),
    ejabberd_hooks:add(user_receive_packet, _Host, ?MODULE, receive_packet, 50),
    ok.

stop(_Host) ->
    ?INFO_MSG("mod_sunshine stopping", []),
    ejabberd_hooks:delete(user_receive_packet, _Host, ?MODULE, receive_packet, 50),
    ok.

receive_packet({_JID, From, To} = Packet) ->
    ?INFO_MSG("receive_packet JID: ~p From: ~p To: ~p Packet: ~p~n",[_JID, From, To, Packet]), 
    ok.

I'm receiving and logging the received packet(using user_receive_packet Hook) and but it throws an error. Following is the error:-

** Reason = {error,function_clause,[{mod_sunshine,receive_packet,[{file,"src/mod_sunshine.erl"},{line,20}],[{{iq,<<"purplead8c6fd0">>,result,<<"en">>,{jid,<<"praful1">>,<<"localhost">>,<<>>,<<"praful1">>,<<"localhost">>,<<>>},{jid,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>},[],#{ip => {0,0,0,0,0,0,0,1}}},#{socket => {socket_state,gen_tcp,#Port<0.16027>,<0.479.0>},socket_monitor => #Ref<0.0.1.726>,stream_direction => in,caps_resources => {1,{{<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>},{caps,<<"http://pidgin.im/">>,<<"DdnydQG7RGhP9E3k9Sf+b+bF0zo=">>,<<"sha-1">>,[]},nil,nil}},tls_enabled => false,auth_module => ejabberd_auth_mnesia,mgmt_stanzas_out => 0,server => <<"localhost">>,sockmod => ejabberd_socket,privacy_list => {userlist,none,[],false},mgmt_resend => false,stream_id => <<"8641864023627389616">>,stream_authenticated => true,mgmt_ack_timeout => 60000,mgmt_queue_type => ram,mgmt_stanzas_req => 0,stream_timeout => infinity,stream_state => established,stream_compressed => false,shaper => c2s_shaper,sid => {{1495,527854,1},<0.480.0>},stream_version => {1,0},user => <<"praful1">>,mgmt_timeout => 300,ip => {{0,0,0,0,0,0,0,1},50783},stream_header_sent => true,csi_state => active,mgmt_state => inactive,conn => c2s,mod => ejabberd_c2s,stream_encrypted => false,pres_f => {1,{{<<"praful1">>,<<"localhost">>,<<>>},nil,nil}},tls_required => false,csi_queue => {0,#{}},jid => {jid,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>},stream_restarted => true,pres_timestamp => {1495,527854,960838},xmlns => <<"jabber:client">>,mgmt_max_queue => 1000,tls_options => [compression_none],owner => <0.480.0>,resource => <<"Prafuls-MacBook-Pro">>,access => c2s,zlib => false,pres_last => {presence,<<>>,available,<<"en">>,{jid,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>,<<"praful1">>,<<"localhost">>,<<"Prafuls-...">>},...},...}}]},...]}
** Arguments = [{{iq,<<"purplead8c6fd0">>,result,<<"en">>,{jid,<<"praful1">>,<<"localhost">>,<<>>,<<"praful1">>,<<"localhost">>,<<>>},{jid,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>},[],#{ip => {0,0,0,0,0,0,0,1}}},#{socket => {socket_state,gen_tcp,#Port<0.16027>,<0.479.0>},socket_monitor => #Ref<0.0.1.726>,stream_direction => in,caps_resources => {1,{{<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>},{caps,<<"http://pidgin.im/">>,<<"DdnydQG7RGhP9E3k9Sf+b+bF0zo=">>,<<"sha-1">>,[]},nil,nil}},tls_enabled => false,auth_module => ejabberd_auth_mnesia,mgmt_stanzas_out => 0,server => <<"localhost">>,sockmod => ejabberd_socket,privacy_list => {userlist,none,[],false},mgmt_resend => false,stream_id => <<"8641864023627389616">>,stream_authenticated => true,mgmt_ack_timeout => 60000,mgmt_queue_type => ram,mgmt_stanzas_req => 0,stream_timeout => infinity,stream_state => established,stream_compressed => false,shaper => c2s_shaper,sid => {{1495,527854,1},<0.480.0>},stream_version => {1,0},user => <<"praful1">>,mgmt_timeout => 300,ip => {{0,0,0,0,0,0,0,1},50783},stream_header_sent => true,csi_state => active,mgmt_state => inactive,conn => c2s,mod => ejabberd_c2s,stream_encrypted => false,pres_f => {1,{{<<"praful1">>,<<"localhost">>,<<>>},nil,nil}},tls_required => false,csi_queue => {0,#{}},jid => {jid,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>},stream_restarted => true,pres_timestamp => {1495,527854,960838},xmlns => <<"jabber:client">>,mgmt_max_queue => 1000,tls_options => [compression_none],owner => <0.480.0>,resource => <<"Prafuls-MacBook-Pro">>,access => c2s,zlib => false,pres_last => {presence,<<>>,available,<<"en">>,{jid,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>},{jid,<<"praful1">>,<<"localhost">>,<<>>,<<"praful1">>,<<"lo...">>,...},...},...}}]

Where exactly am I wrong?

UPDATE

Upon looking at the hook written in one of the ejabberd module, it clearly shows that the hook function will have only 1 parameter. Hence, I updated my code as follow:-

-module(mod_sunshine).

-behavior(gen_mod).

-include("ejabberd.hrl").
-include("logger.hrl").
-include("xmpp.hrl").

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

start(_Host, _Opts) ->
    ?INFO_MSG("mod_sunshine starting", []),
    ejabberd_hooks:add(user_receive_packet, _Host, ?MODULE, user_receive_packet, 50),
    ok.

stop(_Host) ->
    ?INFO_MSG("mod_sunshine stopping", []),
    ejabberd_hooks:delete(user_receive_packet, _Host, ?MODULE, user_receive_packet, 50),
    ok.

-spec user_receive_packet({stanza(), ejabberd_c2s:state()}) -> {stanza(), ejabberd_c2s:state()}.
user_receive_packet({Packet, C2SState}) ->
    ?INFO_MSG("INSIDEEEEEEEE", []),
    ok.

But the moment I receive a packet, it throws an error :-

13:59:28.118 [error] Hook user_receive_packet crashed when running mod_carboncopy:user_receive_packet/1:
** Reason = {error,function_clause,[{mod_carboncopy,user_receive_packet,[{file,"src/mod_carboncopy.erl"},{line,159}],[ok]},{ejabberd_hooks,safe_apply,[{file,"src/ejabberd_hooks.erl"},{line,380}],4},{ejabberd_hooks,run_fold1,[{file,"src/ejabberd_hooks.erl"},{line,364}],4},{ejabberd_c2s,process_info,[{file,"src/ejabberd_c2s.erl"},{line,231}],2},{ejabberd_hooks,safe_apply,[{file,"src/ejabberd_hooks.erl"},{line,380}],4},{ejabberd_hooks,run_fold1,[{file,"src/ejabberd_hooks.erl"},{line,364}],4},{xmpp_stream_in,handle_info,[{file,"src/xmpp_stream_in.erl"},{line,373}],2},{p1_server,handle_msg,[{file,"src/p1_server.erl"},{line,696}],8}]}
** Arguments = [ok]
13:59:28.119 [error] Hook c2s_handle_info crashed when running ejabberd_c2s:process_info/2:
** Reason = {error,{badmatch,ok},[{ejabberd_c2s,process_info,[{file,"src/ejabberd_c2s.erl"},{line,231}],2},{ejabberd_hooks,safe_apply,[{file,"src/ejabberd_hooks.erl"},{line,380}],4},{ejabberd_hooks,run_fold1,[{file,"src/ejabberd_hooks.erl"},{line,364}],4},{xmpp_stream_in,handle_info,[{file,"src/xmpp_stream_in.erl"},{line,373}],2},{p1_server,handle_msg,[{file,"src/p1_server.erl"},{line,696}],8},{proc_lib,init_p_do_apply,[{file,"proc_lib.erl"},{line,247}],3}]}
** Arguments = [#{socket => {socket_state,gen_tcp,#Port<0.15488>,<0.467.0>},stream_authenticated => true,tls_enabled => false,auth_module => ejabberd_auth_mnesia,mgmt_stanzas_out => 0,server => <<"localhost">>,sockmod => ejabberd_socket,privacy_list => {userlist,none,[],false},mgmt_resend => false,stream_id => <<"11245006342381720927">>,stream_encrypted => false,stream_state => established,mgmt_ack_timeout => 60000,mgmt_queue_type => ram,mgmt_stanzas_req => 0,stream_direction => in,stream_restarted => true,sid => {{1495,614568,1},<0.468.0>},user => <<"praful1">>,mgmt_timeout => 300,ip => {{0,0,0,0,0,0,0,1},52732},socket_monitor => #Ref<0.0.2.683>,csi_state => active,mgmt_state => inactive,conn => c2s,stream_timeout => infinity,mod => ejabberd_c2s,stream_compressed => false,pres_f => {1,{{<<"praful1">>,<<"localhost">>,<<>>},nil,nil}},tls_required => false,csi_queue => {0,#{}},jid => {jid,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>},stream_header_sent => true,shaper => c2s_shaper,xmlns => <<"jabber:client">>,mgmt_max_queue => 1000,tls_options => [compression_none],owner => <0.468.0>,resource => <<"Prafuls-MacBook-Pro">>,access => c2s,zlib => false,mgmt_max_timeout => 300,pres_a => {0,nil},lang => <<"en">>,mgmt_stanzas_in => 0,lserver => <<"localhost">>,tls_verify => false,pres_t => {1,{{<<"praful1">>,<<"localhost">>,<<>>},nil,nil}},stream_version => {1,0}},{route,{iq,<<"purple3d24e94d">>,result,<<"en">>,{jid,<<>>,<<"localhost">>,<<>>,<<>>,<<"localhost">>,<<>>},{jid,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>,<<"praful1">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>},[{disco_items,<<>>,[{disco_item,{jid,<<>>,<<"conference.localhost">>,<<>>,<<>>,<<"conference.localhost">>,<<>>},<<>>,<<>>},{disco_item,{jid,<<>>,<<"echo.localhost">>,<<>>,<<>>,<<"echo.localhost">>,<<>>},<<>>,<<>>},{disco_item,{jid,<<>>,<<"irc.localhost">>,<<>>,<<>>,<<"irc.localhost">>,<<>>},<<>>,<<>>},{disco_item,{jid,<<>>,<<"pubsub.localhost">>,<<>>,<<>>,<<"pubsub.localhost">>,<<>>},<<>>,<<>>},{disco_item,{jid,<<>>,<<"localhost">>,<<>>,<<>>,<<"localhost">>,<<>>},<<"Announcements">>,<<"announce">>},{disco_item,{jid,<<>>,<<"localhost">>,<<>>,<<>>,<<"localhost">>,<<>>},<<"Configuration">>,<<"config">>},{disco_item,{jid,<<>>,<<"localhost">>,<<>>,<<>>,<<"localhost">>,<<>>},<<"User Management">>,<<"user">>},{disco_item,{jid,<<>>,<<"localhost">>,<<>>,<<>>,<<"localhost">>,<<>>},<<"Online Users">>,<<"online users">>},{disco_item,{jid,<<>>,<<"localhost">>,<<>>,<<>>,<<"localhost">>,<<>>},<<"All Users">>,<<"all users">>},{disco_item,{jid,<<>>,<<"localhost">>,<<>>,<<>>,<<"localhost">>,<<>>},<<"Outgoing s2s Connections">>,<<"outgoing s2s">>},{disco_item,{jid,<<>>,<<"localhost">>,<<>>,<<>>,<<"localhost">>,<<>>},<<"Running Nodes">>,<<"running nodes">>},{disco_item,{jid,<<>>,<<"localhost">>,<<>>,<<>>,<<"localhost">>,<<>>},<<"Stopped Nodes">>,<<"stopped nodes">>}],undefined}],#{ip => {0,0,0,0,0,0,0,1}}}}]

Kindly provide your valuable inputs.

1

There are 1 answers

2
Pouriya On BEST ANSWER

It seems that tutorial did not update for newer version of Ejabberd and i think you are using ejabberd >= 16.12.
according to the Code, Ejabberd passed Packet, ClientState, ClientJid, FromJid and ToJid to your function.
In newer versions, Packet is #iq{}, #presence{} or #message{} record. Read this include file of xmpp lib for more info.