%%%---------------------------------------------------------------------- %%% File : mod_roster_log.erl %%% Author : Badlop %%% Purpose : Log and watch roster changes %%% Created : 24 May 2010 by Badlop %%% %%% %%% ejabberd, Copyright (C) 2002-2010 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as %%% published by the Free Software Foundation; either version 2 of the %%% License, or (at your option) any later version. %%% %%% This program is distributed in the hope that it will be useful, %%% but WITHOUT ANY WARRANTY; without even the implied warranty of %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU %%% General Public License for more details. %%% %%% You should have received a copy of the GNU General Public License %%% along with this program; if not, write to the Free Software %%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %%% This module logs any roster changes in ejabberd.cfg %%% If you configure the option 'watchers', it will also send messages: %%% {modules, [ %%% {mod_roster_log, [{watchers, ["admin1@example.org", "sadmin@localhost"]}]}, %%% -module(mod_roster_log). -behaviour(gen_mod). -export([start/2, stop/1, in_subscription/6, out_subscription/4 ]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_roster.hrl"). -include("web/ejabberd_http.hrl"). -include("web/ejabberd_web_admin.hrl"). start(Host, _Opts) -> ejabberd_hooks:add(roster_in_subscription, Host, ?MODULE, in_subscription, 50), ejabberd_hooks:add(roster_out_subscription, Host, ?MODULE, out_subscription, 50). stop(Host) -> ejabberd_hooks:delete(roster_in_subscription, Host, ?MODULE, in_subscription, 50), ejabberd_hooks:delete(roster_out_subscription, Host, ?MODULE, out_subscription, 50). in_subscription(_, User, Server, JID, Type, Reason) -> process_subscription(in, User, Server, JID, Type, Reason). out_subscription(User, Server, JID, Type) -> process_subscription(out, User, Server, JID, Type, []). process_subscription(Direction, User, Server, JID, Type, _Reason) -> LServer = jlib:nameprep(Server), FromType = case lists:member(LServer, ?MYHOSTS) of true -> local; false -> remote end, ToType = case lists:member(JID#jid.lserver, ?MYHOSTS) of true -> local; false -> remote end, DoMessage = case {FromType, Direction, ToType} of {local, out, local} -> true; {local, in, local} -> false; _ -> true end, {Arrow1, Arrow2} = case Direction of out -> {"==", "===>"}; in -> {"<===", "=="} end, case DoMessage of true -> Data = {User,Server, Arrow1,Type,Arrow2, JID#jid.luser,JID#jid.lserver}, {TimeString, TextString} = build_notifications(Data), ?INFO_MSG(TextString, []), send_notifications(Server, TimeString++TextString), ok; false -> ok end. %%% %%% Message to watchers %%% build_notifications({User,Server, Arrow1,Type,Arrow2, ToUser, ToServer}) -> TextString = io_lib:format( "~s@~s ~s ~p ~s ~s@~s", [User,Server, Arrow1,Type,Arrow2, ToUser, ToServer]), {"["++get_time_string()++"] ", TextString}. get_time_string() -> write_time(erlang:localtime()). %% Function copied from ejabberd_logger_h.erl and customized write_time({{Y,Mo,D},{H,Mi,S}}) -> io_lib:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Y, Mo, D, H, Mi, S]). %% Copied from mod_register.erl send_notifications(Host, BodyString) -> case gen_mod:get_module_opt(Host, ?MODULE, watchers, []) of [] -> ok; JIDs when is_list(JIDs) -> lists:foreach( fun(S) -> case jlib:string_to_jid(S) of error -> ok; JID -> ejabberd_router:route( jlib:make_jid("", Host, ""), JID, {xmlelement, "message", [{"type", "chat"}], [{xmlelement, "body", [], [{xmlcdata, BodyString}]}]}) end end, JIDs); _ -> ok end.