在SleekXMPP中接收带有消息的“角色”和/或“从属关系”

时间:2014-05-18 19:13:58

标签: python xmpp bots

为业余问题道歉。我只是在学习Python,而且我正在使用XMPP在这个XMPP bot脚本中摸索。

我使用SleekXMPP的MUC bot示例构建了一个机器人: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 个答案:

答案 0 :(得分: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']

这是一般性的想法,你需要做更多的工作来使它处理昵称的变化和人们正确地离开房间。