Search code examples
xmppejabberdstrophe

Strophe.js - How to get a group of rosters with its members?


When using this Strophe command:

var iq = $iq({type: 'get'}).c('query', {xmlns: 'jabber:iq:roster'}); 
connection.sendIQ(iq)

I get this as the success callback:

<iq xmlns="jabber:client" xml:lang="pt-br" to="user01@localhost/100164477219111523302818" from="user01@localhost" type="result" id="82480785-c170-48d1-a180-bcadbff957d2:sendIQ">
  <query xmlns="jabber:iq:roster">
    <item subscription="both" jid="user02@localhost">
      <group>Roster01</group>
      <group>Roster02</group>
    </item>
    <item subscription="both" jid="admin@localhost">
      <group>Roster01</group>
      <group>Roster02</group>
    </item>
    <item subscription="both" jid="[email protected]">
      <group>Roster02</group>
    </item>
    <item subscription="both" jid="[email protected]">
      <group>Roster01</group>
    </item>
  </query>
</iq>

What I want is to know is if there's some way to get this callback grouped by the groups and its members. If there's not, how can I do it with Javascript. Examples:

  • Roster 01 has admin, user02 and grupo01
  • Roster 02 has admin, user02 and grupo02

I'm using ejabberd as the XMPP server and Ionic 3 with Strophe as the client.


Solution

  • I suggest to use strophejs-plugin-roster which get things easier:

    // connect Strophe
    connection = new Strophe.Connection(url);
    connection.connect(my_jid, my_pwd, onConnect);
    
    ...
    
    function onConnect(status) {
        if (status == Strophe.Status.CONNECTED) {
            ...
    
            // pass connection to roster plugin
            connection.roster.init(connection);
        }
    }
    

    Here is a function to getRoster via plugin, result is a JS array containing objects (instead of XML...):

    function getRoster() {
        connection.roster.get(function (roster) {
            console.log('   >roster:', roster);
            for (var i in roster) {
                console.log('   >buddy '+i+':');
                console.log('       >'+roster[i].name+" ("+roster[i].jid+' -->'+roster[i].subscription);
                console.log('       >', roster[i].groups);
            }
            // get buddies belonging to group1 and group2 (see below)
            console.log('   >roster-group1:', getRosterGroup(roster, 'group1'));
            console.log('   >roster-group2:', getRosterGroup(roster, 'group2'));
        });
    }
    

    The function below filter buddies by group:

    function getRosterGroup(roster, group) {
        var reduced = roster.reduce(function(filtered, item) {
            if (item.groups.indexOf(group)!==-1) {
                filtered.push(item);
            }
            return filtered;
        }, []);
        return reduced;
    }
    

    Here is a working Plunker: http://plnkr.co/edit/XloJABSGHZvLTp3Js2KI?p=preview