在SleekXMPP中接收“角色”和/或“归属”信息
抱歉问了个初学者的问题。我正在学习Python,现在在搞一个使用XMPP的机器人脚本。
我的机器人是基于SleekXMPP的MUC机器人示例做的:http://sleekxmpp.com/getting_started/muc.html
我的机器人和示例的不同之处在于,我的脚本创建了一个SQLite数据库,并在每次收到群消息时,解析XML以获取昵称和消息内容,并将其连同时间戳一起写入数据库。
以下是我机器人中记录XMPP频道消息输出的部分:
def groupchat_message(self, msg):
if msg['type'] in ('groupchat'):
raw = str(msg) # Save raw XML as a string in the database for debugging purposes
timestamp = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
fromuser = str(msg['from']) # Convert "from" attribute to string so it can be split
author = fromuser.split('/')[1] # Split "from" attribute to remove channel address leaving only nick behind
body = msg['body']
msginsert = [timestamp, author, body, raw] # Database input list to be handed to placeholders.
db.execute("INSERT INTO messages VALUES (?,?,?,?)", msginsert) # "?" placeholder is REQUIRED for automatic database sanitization.
dbconn.commit()
print("[",timestamp,"]",author,": ",body, sep='')
else:
print(msg)
这些打印语句只是为了调试,让我能在终端看到消息的流动,以确认脚本在运行。
在记录的信息中,我还想包括用户在XMPP频道中的角色或身份,这样就能区分出管理员和版主。这部分我有点搞不清楚。根据SleekXMPP的文档,我觉得应该能做到,但我不太明白怎么从消息的XML中提取角色或身份信息。
我该如何从消息的XML中获取发布该消息的用户的角色和/或身份信息呢?
作为参考,这是来自XMPP频道的消息原始XML输出:
<message to="username@example.com" from="channelname@channels.example.com/User Nick" id="1453" type="groupchat">
<body>This is the message body text</body>
<x xmlns="jabber:x:event">
<composing />
</x>
</message>
1 个回答
消息中并没有包含角色或归属信息,这些信息是聊天状态的一部分。
提醒一下,XMPP协议有三种不同的消息类型:<message>
,这是你之前提到的例子;<iq>
,用于获取或设置一些东西;还有<presence>
,表示某些东西的存在。角色和归属信息是在<presence>
消息中包含的。例如,当你的客户端收到的第一条<presence>
消息时,它会告诉你房间里已经有哪些人。你可以查看XEP-0045的示例21(多用户聊天)。每当某个人的昵称、角色或归属发生变化,或者他们离开房间时,你的客户端也会收到新的<presence>
消息。
你需要自己保存这些信息,因为SleekXMPP并不会为你处理。你可以创建一个字典,用来存储每个昵称对应的角色信息和归属信息。在角色或归属变化时,你要确保更新这些信息。然后你可以在消息处理程序中使用这些字典来记录他们的角色和归属。
所以大概是这样的:
def __init__(...):
self.roles = dict()
self.affiliations = dict()
self.add_event_handler(""groupchat_presence"", self.muc_presence)
...
def muc_presence(self, presence):
nick = presence['muc']['nick']
self.roles[nick] = presence['muc']['role']
self.affiliations[nick] = presence['muc']['affiliation']
这是一个大致的思路,你还需要做一些额外的工作,以便正确处理昵称变化和人离开房间的情况。