如何在 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,{group,{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,desc = "Delete group id from the Shared Roster Group",function = srg_display_group_del,args_desc = ["Group to be removed from display list",#ejabberd_commands{name = srg_set_opts,desc = "Update Shared Roster Group options (name and description)",function = srg_set_opts,args = [{name,{description,args_example = [<<"Group Test Name">>,<<"Group used for testing.">>,args_desc = ["Shared roster group name","Shared Roster Group description","Group identifier",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,Opts),ok.

srg_display_group_del(DeleteGroup,DeleteGroupHost,GroupHost) ->
  ?DEBUG("Removing group from display list.",%%  mod_shared_roster:set_group_opts(GroupHost,ok.

srg_set_opts(Label1,Description1,GroupHost) ->
  ?DEBUG("Setting group options -> Label: ~p,Description: ~p~n",[Label1,Description1]),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]),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.")}.

模块安装正确,但是当我调用使用 srg_set_opts方法 mod_shared_roster:get_group_opts 时,我收到以下错误

error: {module_not_loaded,mod_shared_roster,<<"srg_group10">>}

我看过其他模块作为指南,我注意到的唯一区别是这些模块依赖项包含在同一目录中。但是,我怎么能用自定义模块来实现呢?我对 Erlang 没有经验,所以它可能只是一个简单的导入。


我正在使用通过 docker-ejabberd 安装的 ejabberd 20.04,并使用 Ejabberd module docs for Docker 安装模块。

解决方法

Opts = mod_shared_roster:get_group_opts(Group,GroupHost),

我认为该函数的参数是 Host 和 Group,但您以相反的顺序提供它们。