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

能否自定义ejabberd中<presence>的<show/>元素状态选项?

自定义ejabberd中的<presence><show/>元素:可行方案与注意事项

当然可以自定义ejabberd里的<show/>元素值,但要兼顾XMPP协议的兼容性和服务器的扩展逻辑,下面是具体的实现思路和步骤:

一、核心思路:覆盖ejabberd的默认presence验证

ejabberd默认会遵循RFC3921的规则校验<show/>的值,所以我们需要通过自定义模块来拦截并修改presence数据包的处理逻辑,允许我们需要的自定义值,同时移除不需要的chat状态。

1. 编写自定义ejabberd模块

你可以写一个Erlang模块,通过ejabberd的hook机制拦截presence stanza,校验并修改<show/>元素的值。以下是一个简化的示例:

-module(custom_presence_show).
-behaviour(ejabberd_gen_mod).

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

start(_Host, _Opts) ->
    % 注册filter_packet hook,拦截所有数据包
    ejabberd_hooks:add(filter_packet, global, ?MODULE, filter_packet, 50),
    ok.

stop(_Host) ->
    ejabberd_hooks:delete(filter_packet, global, ?MODULE, filter_packet, 50),
    ok.

filter_packet({From, To, XML} = Packet) ->
    case XML of
        #xmlel{name = <<"presence">>, children = Children} ->
            NewChildren = lists:map(fun
                (#xmlel{name = <<"show">>, children = [ShowText]}) ->
                    % 定义允许的状态值:移除chat,添加working、vacation
                    AllowedShows = [<<"away">>, <<"dnd">>, <<"xa">>, <<"working">>, <<"vacation">>],
                    ShowBin = xml:get_tag_cdata(ShowText),
                    case lists:member(ShowBin, AllowedShows) of
                        true -> #xmlel{name = <<"show">>, children = [ShowText]};
                        false -> 
                            % 对于不允许的值,可以替换为默认状态,或者直接丢弃该元素
                            #xmlel{name = <<"show">>, children = [#xmlcdata{content = <<"away">>}]}
                    end;
                (Child) -> Child
            end, Children),
            {From, To, #xmlel{name = <<"presence">>, children = NewChildren}};
        _ -> Packet
    end.

2. 部署并启用模块

  • 将上述代码编译成.beam文件,放到ejabberd的模块目录(通常是/usr/lib/ejabberd/ebin/或自定义路径)。
  • 在ejabberd的配置文件ejabberd.yml中添加模块启用配置:
modules:
  # ...其他模块...
  custom_presence_show: {}
  • 重启ejabberd服务使配置生效。

二、客户端适配要点

自定义的<show/>值需要客户端支持才能正确显示:

  • 如果使用的是开源客户端(比如Conversations、Pidgin),可能需要修改客户端代码,添加对自定义状态值的UI映射(比如对应图标、显示文本)。
  • 如果是自研客户端,可以直接在状态选择器中加入自定义选项,并将选中值作为<show/>的内容发送给服务器。

三、兼容性与最佳实践

  • 跨客户端兼容性:部分标准XMPP客户端可能会忽略不认识的<show/>值,或者将其显示为默认的"away"状态,所以如果需要广泛兼容,建议考虑通过XMPP扩展(比如自定义IQ或扩展字段)来实现额外状态,而非直接修改标准的<show/>元素。
  • 服务器状态存储:如果需要服务器端持久化或广播这些自定义状态,确保ejabberd的presence存储逻辑能正确处理这些值(默认情况下,ejabberd会存储完整的presence stanza,所以只要你的模块允许通过,就能正常存储)。
  • 协议规范考量:虽然RFC3921定义了固定的<show/>值,但XMPP的设计允许扩展,只要你的服务和客户端能协同工作,自定义是完全可行的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:03:55