如何在 Ejabberd 的自定义模块中加载模块?
How to load a module inside a custom module in Ejabberd?
我正在创建一个自定义模块,它使用 mod_shared_roster 模块中的一些导出函数。这是代码。
-module(mod_shared_roster_extra).
-author('https://github.com/eric-mendoza').
-behaviour(gen_mod).
-include("logger.hrl").
-include("translate.hrl").
-export([start/2, stop/1, reload/3, mod_options/1,
get_commands_spec/0, depends/2, mod_doc/0]).
% Commands API
-export([
% Shared roster
srg_display_group_add/4, srg_display_group_del/4, srg_set_opts/4
]).
-include("ejabberd_commands.hrl").
-include("mod_roster.hrl").
-include("mod_privacy.hrl").
-include("ejabberd_sm.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("mod_shared_roster.hrl").
%%%
%%% gen_mod
%%%
start(_Host, _Opts) ->
ejabberd_commands:register_commands(get_commands_spec()).
stop(Host) ->
case gen_mod:is_loaded_elsewhere(Host, ?MODULE) of
false ->
ejabberd_commands:unregister_commands(get_commands_spec());
true ->
ok
end.
reload(_Host, _NewOpts, _OldOpts) ->
ok.
depends(_Host, _Opts) ->
[{mod_shared_roster, hard}].
%%%
%%% Register commands
%%%
get_commands_spec() ->
[
#ejabberd_commands{name = srg_display_group_add, tags = [shared_roster_group],
desc = "Add group id to the Shared Roster Group display list",
module = ?MODULE, function = srg_display_group_add,
args = [{displaygroup, binary}, {displaygrouphost, binary}, {group, binary}, {grouphost, binary}],
args_example = [<<"group1">>, <<"myserver.com">>, <<"group3">>, <<"myserver.com">>],
args_desc = ["Group to be added in display list", "Group server name", "Group to modify display list identifier", "Group server name"],
result = {res, rescode}},
#ejabberd_commands{name = srg_display_group_del, tags = [shared_roster_group],
desc = "Delete group id from the Shared Roster Group",
module = ?MODULE, function = srg_display_group_del,
args = [{displaygroup, binary}, {displaygrouphost, binary}, {group, binary}, {grouphost, binary}],
args_example = [<<"group1">>, <<"myserver.com">>, <<"group3">>, <<"myserver.com">>],
args_desc = ["Group to be removed from display list", "Group server name", "Group to modify display list identifier", "Group server name"],
result = {res, rescode}},
#ejabberd_commands{name = srg_set_opts, tags = [shared_roster_group],
desc = "Update Shared Roster Group options (name and description)",
module = ?MODULE, function = srg_set_opts,
args = [{name, binary}, {description, binary}, {group, binary}, {grouphost, binary}],
args_example = [<<"Group Test Name">>, <<"Group used for testing.">>, <<"group3">>, <<"myserver.com">>],
args_desc = ["Shared roster group name", "Shared Roster Group description", "Group identifier", "Group server name"],
result = {res, rescode}}
].
%%%
%%% Shared Roster Groups
%%%
to_list([]) -> [];
to_list([H|T]) -> [to_list(H)|to_list(T)];
to_list(E) when is_atom(E) -> atom_to_list(E);
to_list(E) -> binary_to_list(E).
srg_display_group_add(NewGroup, NewGroupHost, Group, GroupHost) ->
?DEBUG("Adding group to display list.", []),
Opts = mod_shared_roster:get_group_opts(Group, GroupHost),
mod_shared_roster:set_group_opts(GroupHost, Group, Opts),
ok.
srg_display_group_del(DeleteGroup, DeleteGroupHost, Group, GroupHost) ->
?DEBUG("Removing group from display list.", []),
Opts = mod_shared_roster:get_group_opts(Group, GroupHost),
%% mod_shared_roster:set_group_opts(GroupHost, Group, Opts),
ok.
srg_set_opts(Label1, Description1, Group, GroupHost) ->
?DEBUG("Setting group options -> Label: ~p, Description: ~p~n", [Label1, Description1]),
Opts = mod_shared_roster:get_group_opts(Group, GroupHost),
Label = if Label1 == <<"">> -> [];
true -> [{label, Label1}]
end,
Description = if Description1 == <<"">> -> [];
true -> [{description, Description1}]
end,
Displayed1 = get_opt(Opts, displayed_groups, []),
Displayed = if Displayed1 == [] -> [];
true -> [{displayed_groups, Displayed1}]
end,
?DEBUG("Options: ~p~n", [Label ++ Description ++ Displayed]),
mod_shared_roster:set_group_opts(GroupHost, Group, Label ++ Description ++ Displayed),
ok.
mod_options(_) -> [].
get_opt(Opts, Opt, Default) ->
case lists:keysearch(Opt, 1, Opts) of
{value, {_, Val}} -> Val;
false -> Default
end.
mod_doc() ->
#{desc =>
?T("This module provides additional administrative commands for shared rosters.")}.
模块安装正确,但是当我调用使用 mod_shared_roster:get_group_opts
的方法 srg_set_opts
时,出现以下错误:
error: {module_not_loaded, mod_shared_roster, <<"srg_group10">>}
我看过其他模块作为指南,我注意到的唯一区别是那些模块依赖项包含在同一目录中。但是,我怎么能用自定义模块实现呢?我对 Erlang 没有经验,所以它可能只是一个简单的导入。
我正在使用通过 docker-ejabberd, and used Ejabberd module docs for Docker 安装的 ejabberd 20.04 来安装模块。
Opts = mod_shared_roster:get_group_opts(Group, GroupHost),
我认为该函数的参数是 Host,然后是 Group,但您以相反的顺序提供它们。
我正在创建一个自定义模块,它使用 mod_shared_roster 模块中的一些导出函数。这是代码。
-module(mod_shared_roster_extra).
-author('https://github.com/eric-mendoza').
-behaviour(gen_mod).
-include("logger.hrl").
-include("translate.hrl").
-export([start/2, stop/1, reload/3, mod_options/1,
get_commands_spec/0, depends/2, mod_doc/0]).
% Commands API
-export([
% Shared roster
srg_display_group_add/4, srg_display_group_del/4, srg_set_opts/4
]).
-include("ejabberd_commands.hrl").
-include("mod_roster.hrl").
-include("mod_privacy.hrl").
-include("ejabberd_sm.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("mod_shared_roster.hrl").
%%%
%%% gen_mod
%%%
start(_Host, _Opts) ->
ejabberd_commands:register_commands(get_commands_spec()).
stop(Host) ->
case gen_mod:is_loaded_elsewhere(Host, ?MODULE) of
false ->
ejabberd_commands:unregister_commands(get_commands_spec());
true ->
ok
end.
reload(_Host, _NewOpts, _OldOpts) ->
ok.
depends(_Host, _Opts) ->
[{mod_shared_roster, hard}].
%%%
%%% Register commands
%%%
get_commands_spec() ->
[
#ejabberd_commands{name = srg_display_group_add, tags = [shared_roster_group],
desc = "Add group id to the Shared Roster Group display list",
module = ?MODULE, function = srg_display_group_add,
args = [{displaygroup, binary}, {displaygrouphost, binary}, {group, binary}, {grouphost, binary}],
args_example = [<<"group1">>, <<"myserver.com">>, <<"group3">>, <<"myserver.com">>],
args_desc = ["Group to be added in display list", "Group server name", "Group to modify display list identifier", "Group server name"],
result = {res, rescode}},
#ejabberd_commands{name = srg_display_group_del, tags = [shared_roster_group],
desc = "Delete group id from the Shared Roster Group",
module = ?MODULE, function = srg_display_group_del,
args = [{displaygroup, binary}, {displaygrouphost, binary}, {group, binary}, {grouphost, binary}],
args_example = [<<"group1">>, <<"myserver.com">>, <<"group3">>, <<"myserver.com">>],
args_desc = ["Group to be removed from display list", "Group server name", "Group to modify display list identifier", "Group server name"],
result = {res, rescode}},
#ejabberd_commands{name = srg_set_opts, tags = [shared_roster_group],
desc = "Update Shared Roster Group options (name and description)",
module = ?MODULE, function = srg_set_opts,
args = [{name, binary}, {description, binary}, {group, binary}, {grouphost, binary}],
args_example = [<<"Group Test Name">>, <<"Group used for testing.">>, <<"group3">>, <<"myserver.com">>],
args_desc = ["Shared roster group name", "Shared Roster Group description", "Group identifier", "Group server name"],
result = {res, rescode}}
].
%%%
%%% Shared Roster Groups
%%%
to_list([]) -> [];
to_list([H|T]) -> [to_list(H)|to_list(T)];
to_list(E) when is_atom(E) -> atom_to_list(E);
to_list(E) -> binary_to_list(E).
srg_display_group_add(NewGroup, NewGroupHost, Group, GroupHost) ->
?DEBUG("Adding group to display list.", []),
Opts = mod_shared_roster:get_group_opts(Group, GroupHost),
mod_shared_roster:set_group_opts(GroupHost, Group, Opts),
ok.
srg_display_group_del(DeleteGroup, DeleteGroupHost, Group, GroupHost) ->
?DEBUG("Removing group from display list.", []),
Opts = mod_shared_roster:get_group_opts(Group, GroupHost),
%% mod_shared_roster:set_group_opts(GroupHost, Group, Opts),
ok.
srg_set_opts(Label1, Description1, Group, GroupHost) ->
?DEBUG("Setting group options -> Label: ~p, Description: ~p~n", [Label1, Description1]),
Opts = mod_shared_roster:get_group_opts(Group, GroupHost),
Label = if Label1 == <<"">> -> [];
true -> [{label, Label1}]
end,
Description = if Description1 == <<"">> -> [];
true -> [{description, Description1}]
end,
Displayed1 = get_opt(Opts, displayed_groups, []),
Displayed = if Displayed1 == [] -> [];
true -> [{displayed_groups, Displayed1}]
end,
?DEBUG("Options: ~p~n", [Label ++ Description ++ Displayed]),
mod_shared_roster:set_group_opts(GroupHost, Group, Label ++ Description ++ Displayed),
ok.
mod_options(_) -> [].
get_opt(Opts, Opt, Default) ->
case lists:keysearch(Opt, 1, Opts) of
{value, {_, Val}} -> Val;
false -> Default
end.
mod_doc() ->
#{desc =>
?T("This module provides additional administrative commands for shared rosters.")}.
模块安装正确,但是当我调用使用 mod_shared_roster:get_group_opts
的方法 srg_set_opts
时,出现以下错误:
error: {module_not_loaded, mod_shared_roster, <<"srg_group10">>}
我看过其他模块作为指南,我注意到的唯一区别是那些模块依赖项包含在同一目录中。但是,我怎么能用自定义模块实现呢?我对 Erlang 没有经验,所以它可能只是一个简单的导入。
我正在使用通过 docker-ejabberd, and used Ejabberd module docs for Docker 安装的 ejabberd 20.04 来安装模块。
Opts = mod_shared_roster:get_group_opts(Group, GroupHost),
我认为该函数的参数是 Host,然后是 Group,但您以相反的顺序提供它们。