如何从 ejabberd/xmpp 获取最新的房间主题?

How to get latest room subject from ejabberd/xmpp?

我更改了 'Subject' 聊天室,但我没有得到这个最新的主题名称。我正在使用 'disco#info' 获取房间信息。作为回应,我得到的房间标题是在创建房间时最初设置的,而不是最新的房间主题。如何获取最新的房间主题?

在XMPP MUC协议中,主题和标题是两个不同的东西。标题通过配置表单设置,可以在服务发现中显示。主题是一个动态主题,当他加入房间时发送给参与者。主题不会在 disco#info 查询中发回。只有名称和 room_description 在发现信息中发回。

必须自定义 Erlang 模块 mod_muc_room.erl

iq_disco_info_extras 中是否有这些变化:

  1. 创建了一个新函数 get_subject,它从 StateData 获取房间主题。
  2. iq_disco_info_extras 中添加了一个新参数来获取房间主题并调用函数 RoomSubject = get_subject(StateData)
  3. 添加了一个新的 RFIELD 作为 ?RFIELD(<<"Room subject">>, <<"muc#roominfo_subject">>, RoomSubject),
  4. 编译了模块 mod_muc_room.erl,更新了 mod_muc_room.beam 文件。

Tada...简直小菜一碟!

现在正在 roominfo 中获取主题名称。

万一有人还在寻找这个,这里有一个快速的方法,可以从类似 ejabberd 的东西中做到这一点 plugin/module:

{ok,Room_PID} = mod_muc:find_online_room(<<"my_muc_room_name">>, <<"conference.my.server.com">>),    
{ok,Room_State} = p1_fsm:sync_send_all_state_event(Room_PID, get_state),    
Room_Subject_List = Room_State#state.subject,    
Room_Subject = hd(Room_Subject_List),    
Subject = Room_Subject#text.data,    
io:format("~ts~n", [Subject]).

如果您从通过 "ejabberdctl debug" 提出的 erlang shell 尝试此操作,那么您还需要引入 "state" 和 [= 的记录定义27=]。为此,创建一个名为 "my_record_includes.hrl" 的文本文件,内容如下(当然,您必须根据您的 ejabberd 安装调整文件路径)。

-include("/opt/ejabberd-19.05/lib/xmpp-1.3.4/include/jid.hrl").
-include("/opt/ejabberd-19.05/lib/xmpp-1.3.4/include/xmpp_codec.hrl").
-include("/opt/ejabberd-19.05/lib/ejabberd-19.05/include/mod_muc_room.hrl").

创建 "my_record_includes.hrl" 后,使用 shell "rr" 命令像这样导入它:

> rr("my_record_includes.hrl").

[activity,address,addresses,adhoc_actions,adhoc_command,
 adhoc_note,avatar_data,avatar_info,avatar_meta,
 avatar_pointer,bind,block,block_item,block_list,bob_data,
 bookmark_conference,bookmark_storage,bookmark_url,
 bytestreams,caps,carbons_disable,carbons_enable,
 carbons_private,carbons_received,carbons_sent,chatstate,
 compress,compress_failure,compressed|...]

如果您在 erlang 中执行此操作 shell,请确保在尝试执行代码以获取房间状态和主题之前导入这些记录定义!

另外,从 muc room 进程本身执行的回调中执行此操作时要小心。对 p1_fsm:sync_send_all_state_event( ) 的调用向房间进程发送一条消息,如果您将其发送到您自己的进程并阻塞,该消息将会超时。从另一个进程查询房间状态!