You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过IQ Stanza在Ejabberd中获取指定时间戳后两用户的消息?

在Ejabberd中通过IQ Stanza获取指定时间戳后的用户间消息

Ejabberd没有原生的IQ Stanza直接支持该需求,但可以基于内置的消息归档模块mod_mam,通过自定义扩展模块实现该功能。

实现步骤

1. 启用消息归档模块

首先确保mod_mam已在ejabberd配置文件(ejabberd.yml)中启用,它负责存储用户的聊天记录,是查询的基础:

modules:
  mod_mam:
    default: always
    assume_mam_usage: true

2. 编写自定义IQ处理模块

需要开发一个Erlang模块,监听自定义IQ命名空间,处理查询请求并返回结果。核心逻辑包括:

  • 解析请求中的两个用户JID、起始时间戳参数
  • 调用mod_mam的API查询符合条件的消息
  • 将结果封装为IQ响应返回

核心代码片段:

-module(mod_mam_custom_query).
-behaviour(gen_mod).

-export([start/2, stop/1, process_iq/1]).

start(Host, _Opts) ->
    ejabberd_hooks:add(iq_get, Host, ?MODULE, process_iq, 50),
    ok.

stop(Host) ->
    ejabberd_hooks:delete(iq_get, Host, ?MODULE, process_iq, 50),
    ok.

process_iq(#iq{type = get, xmlns = <<"urn:xmpp:mam:custom:query">>, from = From, sub_el = SubEl} = IQ) ->
    % 解析请求参数
    {xmlel, _, _, Params} = SubEl,
    User1Bin = proplists:get_value(<<"user1">>, Params),
    User2Bin = proplists:get_value(<<"user2">>, Params),
    StartTsBin = proplists:get_value(<<"start">>, Params),
    
    User1 = jid:from_binary(User1Bin),
    User2 = jid:from_binary(User2Bin),
    StartTs = binary_to_integer(StartTsBin),

    % 权限校验:仅允许消息双方或管理员查询
    case lists:member(From, [User1, User2]) orelse ejabberd_auth:is_admin(From) of
        false ->
            IQ#iq{type = error, sub_el = [ejabberd_errors:not_authorized()]};
        true ->
            % 调用mod_mam查询指定条件的消息
            Messages = mod_mam:lookup_messages(jid:server(From), #{
                start => StartTs,
                with => [User1, User2],
                direction => both
            }),
            % 构造响应XML
            ResponseEl = #xmlel{name = <<"result">>, xmlns = <<"urn:xmpp:mam:custom:query">>, children = format_messages(Messages)},
            IQ#iq{type = result, sub_el = [ResponseEl]}
    end;
process_iq(IQ) -> IQ.

% 将消息列表格式化为XML元素
format_messages(Messages) ->
    lists:map(fun(#{id := Id, from := From, to := To, body := Body, timestamp := Ts}) ->
        #xmlel{name = <<"message">>, children = [
            #xmlel{name = <<"id">>, children = [#xmlcdata{content = Id}]},
            #xmlel{name = <<"from">>, children = [#xmlcdata{content = jid:to_binary(From)}]},
            #xmlel{name = <<"to">>, children = [#xmlcdata{content = jid:to_binary(To)}]},
            #xmlel{name = <<"body">>, children = [#xmlcdata{content = Body}]},
            #xmlel{name = <<"timestamp">>, children = [#xmlcdata{content = integer_to_binary(Ts)}]}
        ]}
    end, Messages).

3. 客户端发送IQ请求示例

客户端需要发送符合自定义命名空间的IQ Stanza,示例如下:

<iq type="get" id="mam_custom_1" xmlns="jabber:client">
  <query xmlns="urn:xmpp:mam:custom:query">
    <user1>alice@example.com</user1>
    <user2>bob@example.com</user2>
    <start>1690000000</start>
  </query>
</iq>

4. 部署自定义模块

将编写好的模块编译后,放置到Ejabberd的模块目录,并在ejabberd.yml中添加模块配置:

modules:
  mod_mam_custom_query: {}

内容的提问来源于stack exchange,提问作者rangarajan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 14:54:19