在 SleekXMPP 中接收带有消息的“角色”和/或“从属关系”
Posted
技术标签:
【中文标题】在 SleekXMPP 中接收带有消息的“角色”和/或“从属关系”【英文标题】:Receiving "role" and/or "affiliation" with message in SleekXMPP 【发布时间】:2014-05-18 19:13:58 【问题描述】:对于这个业余问题,我们深表歉意。我只是在学习 Python,我正在使用 XMPP 摸索这个 XMPP 机器人脚本。
我有一个使用 SleekXMPP 的 MUC 机器人示例构建的机器人:http://sleekxmpp.com/getting_started/muc.html
我的机器人与示例的不同之处在于我的脚本创建了一个 SQLite 数据库,并在每个 group_message 事件上解析 XML 以检索昵称和消息正文文本,并将其写入带有时间戳的数据库。
这是我的机器人记录 XMPP 通道的 msg 输出的部分:
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 stanza docs 做到这一点,但我无法弄清楚如何从消息 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>
,表示事物的存在.角色/从属关系信息包含在存在节中。例如,在您的客户收到的第一个出席信息节中,通知它谁已经在房间里,请参阅Example 21 from XEP-0045 (Multi-User Chat)。每当某人的昵称、角色或隶属关系发生变化或当他们离开房间时,您的客户也会收到新的出席信息节。
您应该确保自己存储这些信息,因为 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']
这是一般的想法,您需要做更多的工作才能让它处理昵称更改和人们正确离开房间。
【讨论】:
昵称更改不是问题,因为此服务器上不允许更改。通过处理用户退出,您的意思是从字典中删除信息?我很确定我知道该怎么做。 是的。严格来说,没有必要删除它们(因为它们会在发送消息之前再次加入),但如果你不这样做,你会浪费内存。 太棒了,谢谢。我已经设置了角色和从属关系日志,并且它正在工作。你知道在 Sleek 中是否有一个离开事件触发器,我可以用它来删除字典条目,还是我必须手动设置它来检测离开消息? 在我给出的 muc_presence 回调示例中检查是否存在['type'] == 'unavailable' 可以检测到部件。以上是关于在 SleekXMPP 中接收带有消息的“角色”和/或“从属关系”的主要内容,如果未能解决你的问题,请参考以下文章
SleekXMPP:将出席 ['muc']['jid'] 获取到每条消息的消息处理程序
如何使用聊天客户端未接收到的 slimXMPP 发送一些数据?