Erlang 未调用Ejabberd中的自定义模块

Erlang 未调用Ejabberd中的自定义模块,erlang,xmpp,ejabberd,ejabberd-module,ejabberd-hooks,Erlang,Xmpp,Ejabberd,Ejabberd Module,Ejabberd Hooks,原创 我花了好几天的时间试图将一个开源的Ejabberd模块(mod_offline_http_post)从以前的版本修改到当前的版本(20.04)。例如,某些零件现在很重要,需要导出,如mod_选项和mod_依赖项。它们不是模块源代码的一部分。我添加了它们。我还是犯了个错误 .ejabberd modules/sources/mod_offline_http_post/src/mod_offline_http_post.erl %%模块的名称必须与文件名匹配 %%更新:info@ph-f、

原创

我花了好几天的时间试图将一个开源的Ejabberd模块(mod_offline_http_post)从以前的版本修改到当前的版本(20.04)。例如,某些零件现在很重要,需要导出,如mod_选项和mod_依赖项。它们不是模块源代码的一部分。我添加了它们。我还是犯了个错误

.ejabberd modules/sources/mod_offline_http_post/src/mod_offline_http_post.erl

%%模块的名称必须与文件名匹配
%%更新:info@ph-f、 nl
-模块(mod_脱机\u http_post)。
-作者(“dev@codepond.org").
-行为(gen_mod)。
-导出([开始/2,停止/1,依赖/2,修改选项/1,创建消息/1,创建消息/3])。
%%由?INFO_MSG宏所需
-包括(“logger.hrl”)。
-包括(“紧急停堆.hrl”)。
-包括(“xmpp.hrl”)。
开始(_主机,_选项)->
?信息消息(“mod_离线\u http_后加载”,[]),
inets:start(),
?信息消息(“HTTP客户端已启动”,[]),
ejabberd_钩子:添加(脱机消息钩子、主机、模块、创建消息,1)。
停止(\u主机)->
?信息消息(“停止脱机模式”、[]),
ejabberd_钩子:删除(脱机_消息_钩子,主机,模块,创建_消息,1)。
取决于(\u主机,\u选择)->
[].
mod_选项(_主机)->
[].
当(Packet#message.type==chat)和(Packet#message.body/=[])->时创建_消息({Action,Packet}=Acc)
[{text,{,Body}]=Packet#message.Body,
post#u offline#u message(数据包#message.from、数据包#message.to、正文、数据包#message.id),
行政协调会;
创建_消息(Acc)->
根据。
当(Packet#message.type==chat)和(Packet#message.body/=[])->时创建(从、_到、Packet)消息
Body=fxml:get_path_s(数据包,[{elem,list_to_binary(“Body”)},cdata]),
MessageId=fxml:get_tag_attr_s(list_to_binary(“id”),数据包),
发布脱机消息(_-From、_-To、Body、MessageId),
好啊
发布脱机消息(发件人、收件人、正文、消息ID)->
?信息消息(“从~p发布到~p Body~p ID~p~n”,[From,To,Body,MessageId]),
Token=gen_mod:get_module_opt(To#jid.lserver,?module,auth_Token,fun)->iolist_To_binary结尾,list_To_binary(“”),
postrl=gen_mod:get_module_opt(To#jid.lserver),module,post_url,fun(S)->iolist_To_binary(S)end,list_To_binary(“”),
ToUser=To#jid.luser,
FromUser=From#jid.luser,
Vhost=To#jid.lserver,
案例gen_mod:获取模块选项(至jid.lserver,?模块,机密,错误)
true->Data=string:join([“to=”,binary_to_list(ToUser),“&from=”,binary_to_list(FromUser),“&vhost=”,binary_to_list(vhost),“&messageId=”,binary_to_list(messageId)],”;
false->Data=string:join([“to=”,binary_to_list(ToUser),“&from=”,binary_to_list(FromUser),“&vhost=”,binary_to_list(vhost),“&body=”,binary_to_list(body),“&messageId=”,binary_to_list(messageId)],“”)
完,,
请求={binary_to_list(postrl),[{“授权”,binary_to_list(Token)}],“application/x-www-form-urlencoded”,Data},
httpc:请求(post、请求、[]、[]),
?信息信息(“发送请求后”,[])。
有效

太棒了。它正在工作。通知将发送给脱机用户。嗯,我的意思是,发送给离线用户的消息被转发到后端,而后端又向用户发送FCM通知

由于我花了3天的时间在这个问题上,几乎没有关于当前版本20.04的关于这个问题的信息,所以我将为遇到这个问题的人详细介绍解决方案

首先也是最重要的是,除了start/2和stop/1之外,如果您的自定义模块支持选项,请导出这3个函数:dependens/2(可能是一个指示依赖项的函数,即如果我没有错的话,您在那里列出所需的模块)、mod_opt_type/1(每个选项都应经过验证)和mod_options/2(其中列出了选项及其默认值)

第二,互联网上的许多定制模块都是为以前的版本制作的,而这些版本并不需要。然后,如果他们使用gen_mod:get_module_opt,他们会添加验证和默认值。你最终得到gen_mod:get_module_opt/4或gen_mod:get_module_opt/5。现在,因为你已经得到了每个选项的验证和默认值在mod_options/2和mod_opt类型/1中,mod:get_module_opt变为mod:get_module_opt/3。您应该只保留前3个参数

如果您通过RPM软件包安装Ejabberd,就像我的例子一样,您可能在编译服务器时没有启用LAGER。或者这样或这样的解释,至少对于自定义模块来说是这样。我的意思是,您可以看到软件包中嵌入的模块的日志,而不是自定义模块中的日志。要启用LAGER或您的信息(如果我没有使用正确的术语,请更正这些陈述),请在导出后立即执行此操作:

-ifndef(啤酒)。
-定义(LAGER,1)。
-endif.