Ejabberd 18.04自定义模块:如何读取消息中的extra标签内容
读取Ejabberd消息中自定义extra标签内容的解决方案
针对你在Ejabberd 18.04中读取自定义<extra xmlns="ocp:extra">标签内容的需求,你可以借助Ejabberd内置的xml模块API来实现,结合你参考的mod_offline_http_post模块逻辑,具体步骤如下:
1. 获取消息的子元素列表
首先从message packet中提取所有额外的XML子元素(也就是你日志里看到的包含<x>和<extra>的列表)。在Erlang的message记录结构中,这个列表对应第10个元素,你可以用element/2函数直接获取:
SubEls = element(10, Packet),
2. 定位目标extra元素
使用xml:get_subtag_with_ns/2函数,通过标签名和命名空间精准匹配你需要的<extra>元素,这个API会自动帮你过滤掉其他同名但命名空间不同的元素:
ExtraEl = xml:get_subtag_with_ns(SubEls, <<"extra">>, <<"ocp:extra">>),
3. 提取标签内的文本内容
拿到目标元素后,用xml:get_cdata/1函数提取其中的CDATA文本内容,这会直接返回你需要的<extra type="image" ...></extra>二进制字符串:
case ExtraEl of undefined -> % 处理没有找到extra标签的情况,比如设为空字符串 ExtraContent = <<"">>; _ -> ExtraContent = xml:get_cdata(ExtraEl) end
完整示例(结合mod_offline_http_post逻辑)
把这段逻辑整合到离线消息处理函数中,构造包含extra内容的POST数据:
handle_offline_message(From, To, Packet, _Server) -> % 获取消息主体内容 Body = xml:get_path_s(Packet, [{elem, <<"body">>}, cdata]), % 获取子元素列表 SubEls = element(10, Packet), % 提取extra标签内容 ExtraContent = case xml:get_subtag_with_ns(SubEls, <<"extra">>, <<"ocp:extra">>) of undefined -> <<"">>; El -> xml:get_cdata(El) end, % 构造要发送到webhook的JSON数据 PostData = jsx:encode([ {<<"from">>, jid:to_binary(From)}, {<<"to">>, jid:to_binary(To)}, {<<"body">>, Body}, {<<"extra">>, ExtraContent} ]), % 发送POST请求(参考原模块的HTTP请求逻辑) case httpc:request(post, {"你的webhook地址", [], "application/json", PostData}, [], []) of {ok, _} -> ok; {error, Reason} -> error_logger:error_msg("Failed to send to webhook: ~p", [Reason]), ok end, ok.
注意事项
- 确保你的模块中导入了
xml模块,或者直接使用完整的函数名(如xml:get_subtag_with_ns/2) - 处理
ExtraEl为undefined的情况,避免因消息中没有extra标签导致代码崩溃 - 这些API在Ejabberd 18.04版本中是原生支持的,无需额外依赖
内容的提问来源于stack exchange,提问作者dichen
相关产品推荐
相关产品推荐

