XMPPPY managing chat room

Posted by Yaroslav Luzin on 29 Jun, 2019

This is a crosspost from our developer's blog. Here's the link to the original post -- @akhavr

If you have a jabber bot written using XMPPPY you might find interesting how to get jabber room's participants list and how to kick them.

When I started searching for it I was confused, because XMPPPY documentation is poor and I've found only pure XMPP stanzas that help to solve the problem.

How to get users list

After connection to JabberRoom, create a stanza callback:

stanza_callback = make_stanza_callback(obj, room)
bot.client.RegisterHandler('iq',stanza_callback)

and

def make_stanza_callback(self, obj, room):
    def stanza_callback(obj, room):
        def callback(conn, iq_node):
            node = str(iq_node)
            if 'http://jabber.org/protocol/disco#items' in node:
                #we've got an online users list
                regex = re.compile(r'name="([\w.]+)"')
                matches = regex.finditer(node)
                self.online_users = []
                for m in matches:
                    self.online_users.append(m.group(1))
            return
        return callback
    return stanza_callback(obj, room)

iq_node is server's response to our stanza and it contains users' nicknames which we try to extract using simple regex.

Now, what about sending query to get this stanza? Pretty simple:

def _request_users_list(self, jclient, room):
    # asking for list of online users
    # response will be handled by stanza_callback
    stanza = xmpp.Iq(to = room, typ = 'get')
    query = xmpp.Node('query')
    query.setNamespace('http://jabber.org/protocol/disco#items')
    stanza.addChild(node = query)
    jclient.send(stanza)

There are various ways to use online users list, e.g. I kick users with similar nicknames.

Kicking user

Kicking is as simple as changing user role to 'none', so there's also stanza creation:

def _kick_user(self, jclient, room, reason, fulljid=None, nick=None):
    item = {'role': 'none'}

    if fulljid:

        item['jid'] = fulljid
    elif nick:
        item['nick'] = nick
    else:
        raise Exception('You have to provide nickname of jid of user to kick him.')
    stanza = xmpp.Iq(to = room, typ = 'set')
    query = xmpp.Node('query')
    query.setNamespace(xmpp.NS_MUC_ADMIN)
    afl_role = query.addChild('item', item)
    afl_role.setTagData('reason', reason)
    stanza.addChild(node = query)
    jclient.send(stanza)

jclient is jabber client, room is room address You can use fulljid (e.g. aa@jabber.org/safas) or user nickname. User you want to kick must have lower affiliation (e.g. if you are admin and he is room creator you can't kick him) and you have to be room creator or admin.

Further reading:


   CODING   

 Share on: Twitter / Facebook / Google+ / Email