delete_old_messages/2, get_commands_spec/0, msg_to_el/4,
get_room_config/4, set_room_option/3, offline_message/1, export/1,
mod_options/1, remove_mam_for_user_with_peer/3, remove_mam_for_user/2,
- is_empty_for_user/2, is_empty_for_room/3, check_create_room/4]).
++ is_empty_for_user/2, is_empty_for_room/3, check_create_room/4,
+ process_iq/3, store_mam_message/7, make_id/0]).
-include("xmpp.hrl").
-include("logger.hrl").
ok
end,
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
- Mod:init(Host, Opts),
- init_cache(Mod, Host, Opts),
- register_iq_handlers(Host),
- ejabberd_hooks:add(sm_receive_packet, Host, ?MODULE,
- sm_receive_packet, 50),
- ejabberd_hooks:add(user_receive_packet, Host, ?MODULE,
- user_receive_packet, 88),
- ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
- user_send_packet, 88),
- ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
- user_send_packet_strip_tag, 500),
- ejabberd_hooks:add(offline_message_hook, Host, ?MODULE,
- offline_message, 50),
- ejabberd_hooks:add(muc_filter_message, Host, ?MODULE,
- muc_filter_message, 50),
- ejabberd_hooks:add(muc_process_iq, Host, ?MODULE,
- muc_process_iq, 50),
- ejabberd_hooks:add(disco_sm_features, Host, ?MODULE,
- disco_sm_features, 50),
- ejabberd_hooks:add(remove_user, Host, ?MODULE,
- remove_user, 50),
- ejabberd_hooks:add(remove_room, Host, ?MODULE,
- remove_room, 50),
- ejabberd_hooks:add(get_room_config, Host, ?MODULE,
- get_room_config, 50),
- ejabberd_hooks:add(set_room_option, Host, ?MODULE,
- set_room_option, 50),
- ejabberd_hooks:add(store_mam_message, Host, ?MODULE,
- store_mam_message, 100),
- case gen_mod:get_opt(assume_mam_usage, Opts) of
- true ->
- ejabberd_hooks:add(message_is_archived, Host, ?MODULE,
- message_is_archived, 50);
- false ->
- ok
- end,
- ejabberd_commands:register_commands(get_commands_spec()),
- ok.
+ case Mod:init(Host, Opts) of
+ ok ->
+ init_cache(Mod, Host, Opts),
+ register_iq_handlers(Host),
+ ejabberd_hooks:add(sm_receive_packet, Host, ?MODULE,
+ sm_receive_packet, 50),
+ ejabberd_hooks:add(user_receive_packet, Host, ?MODULE,
+ user_receive_packet, 88),
+ ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
+ user_send_packet, 88),
+ ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
+ user_send_packet_strip_tag, 500),
+ ejabberd_hooks:add(offline_message_hook, Host, ?MODULE,
+ offline_message, 50),
+ ejabberd_hooks:add(muc_filter_message, Host, ?MODULE,
+ muc_filter_message, 50),
+ ejabberd_hooks:add(muc_process_iq, Host, ?MODULE,
+ muc_process_iq, 50),
+ ejabberd_hooks:add(disco_sm_features, Host, ?MODULE,
+ disco_sm_features, 50),
+ ejabberd_hooks:add(remove_user, Host, ?MODULE,
+ remove_user, 50),
+ ejabberd_hooks:add(get_room_config, Host, ?MODULE,
+ get_room_config, 50),
+ ejabberd_hooks:add(set_room_option, Host, ?MODULE,
+ set_room_option, 50),
++ ejabberd_hooks:add(store_mam_message, Host, ?MODULE,
++ store_mam_message, 100),
+ case gen_mod:get_opt(assume_mam_usage, Opts) of
+ true ->
+ ejabberd_hooks:add(message_is_archived, Host, ?MODULE,
+ message_is_archived, 50);
+ false ->
+ ok
+ end,
+ case gen_mod:get_opt(clear_archive_on_room_destroy, Opts) of
+ true ->
+ ejabberd_hooks:add(remove_room, Host, ?MODULE,
+ remove_room, 50);
+ false ->
+ ejabberd_hooks:add(check_create_room, Host, ?MODULE,
+ check_create_room, 50)
+ end,
- ejabberd_commands:register_commands(get_commands_spec());
++ ejabberd_commands:register_commands(get_commands_spec()),
++ ok;
+ Err ->
+ Err
+ end.
-
-
-
use_cache(Mod, Host) ->
case erlang:function_exported(Mod, use_cache, 2) of
true -> Mod:use_cache(Host);
process_iq(LServer, #iq{from = #jid{luser = LUser}, lang = Lang,
sub_els = [SubEl]} = IQ, MsgType) ->
- case MsgType of
- chat ->
- maybe_activate_mam(LUser, LServer);
- _ ->
- ok
- end,
- case SubEl of
- #mam_query{rsm = #rsm_set{index = I}} when is_integer(I) ->
- Txt = <<"Unsupported <index/> element">>,
- xmpp:make_error(IQ, xmpp:err_feature_not_implemented(Txt, Lang));
- #mam_query{rsm = RSM, xmlns = NS} ->
- case parse_query(SubEl, Lang) of
- {ok, Query} ->
- NewRSM = limit_max(RSM, NS),
- select_and_send(LServer, Query, NewRSM, IQ, MsgType);
- {error, Err} ->
- xmpp:make_error(IQ, Err)
- end
+ Ret = case MsgType of
+ chat ->
+ maybe_activate_mam(LUser, LServer);
- {groupchat, _Role, _MUCState} ->
++ _ ->
+ ok
+ end,
+ case Ret of
+ ok ->
+ case SubEl of
+ #mam_query{rsm = #rsm_set{index = I}} when is_integer(I) ->
+ Txt = <<"Unsupported <index/> element">>,
+ xmpp:make_error(IQ, xmpp:err_feature_not_implemented(Txt, Lang));
+ #mam_query{rsm = RSM, xmlns = NS} ->
+ case parse_query(SubEl, Lang) of
+ {ok, Query} ->
+ NewRSM = limit_max(RSM, NS),
+ select_and_send(LServer, Query, NewRSM, IQ, MsgType);
+ {error, Err} ->
+ xmpp:make_error(IQ, Err)
+ end
+ end;
+ {error, _} ->
+ Txt = <<"Database failure">>,
+ xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
end.
-spec should_archive(message(), binary()) -> boolean().
-spec store_msg(message(), binary(), binary(), jid(), send | recv)
-> ok | pass | any().
store_msg(Pkt, LUser, LServer, Peer, Dir) ->
- Prefs = get_prefs(LUser, LServer),
- case {should_archive_peer(LUser, LServer, Prefs, Peer), Pkt} of
- {true, #message{meta = #{sm_copy := true}}} ->
- ok; % Already stored.
- {true, _} ->
- case ejabberd_hooks:run_fold(store_mam_message, LServer, Pkt,
- [LUser, LServer, Peer, <<"">>, chat, Dir]) of
- #message{} -> ok;
- _ -> pass
+ case get_prefs(LUser, LServer) of
+ {ok, Prefs} ->
+ case {should_archive_peer(LUser, LServer, Prefs, Peer), Pkt} of
+ {true, #message{meta = #{sm_copy := true}}} ->
+ ok; % Already stored.
+ {true, _} ->
+ case ejabberd_hooks:run_fold(store_mam_message, LServer, Pkt,
- [LUser, LServer, Peer, chat, Dir]) of
- drop ->
- pass;
- Pkt1 ->
- US = {LUser, LServer},
- ID = get_stanza_id(Pkt1),
- El = xmpp:encode(Pkt1),
- Mod = gen_mod:db_mod(LServer, ?MODULE),
- Mod:store(El, LServer, US, chat, Peer, <<"">>, Dir, ID)
++ [LUser, LServer, Peer, <<"">>, chat, Dir]) of
++ #message{} -> ok;
++ _ -> pass
+ end;
+ {false, _} ->
+ pass
end;
- {false, _} ->
+ {error, _} ->
pass
end.
end.
select_and_send(LServer, Query, RSM, #iq{from = From, to = To} = IQ, MsgType) ->
- {Msgs, IsComplete, Count} =
- case MsgType of
- chat ->
- select(LServer, From, From, Query, RSM, MsgType);
- _ ->
- select(LServer, From, To, Query, RSM, MsgType)
- end,
- SortedMsgs = lists:keysort(2, Msgs),
- send(SortedMsgs, Count, IsComplete, IQ).
+ Ret = case MsgType of
+ chat ->
+ select(LServer, From, From, Query, RSM, MsgType);
- {groupchat, _Role, _MUCState} ->
++ _ ->
+ select(LServer, From, To, Query, RSM, MsgType)
+ end,
+ case Ret of
+ {Msgs, IsComplete, Count} ->
+ SortedMsgs = lists:keysort(2, Msgs),
+ send(SortedMsgs, Count, IsComplete, IQ);
+ {error, _} ->
+ Txt = <<"Database failure">>,
+ Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang),
+ xmpp:make_error(IQ, Err)
+ end.
select(_LServer, JidRequestor, JidArchive, Query, RSM,
{groupchat, _Role, #state{config = #config{mam = false},