Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XMPP persistent conference room presence

Tags:

xmpp

I have XMPP server (openfire) with a bunch of clients (spark) divided into few groups (departments). I am looking for the ability to keep them in conference rooms. I mean similar functionality that skype has; when the user closes window with group conversation, his client keeps tracing that room's activity and when new message appears, user auto joins that conference again. I have already found out there is no such ability in spark+openfire, though there is nice Group Chat Bookmarks feature with auto joining, however it does not prevent user from simply leaving the room and not being able to get noticed about further events. I'd like to ask if there is any XMPP client that has this feature implemented. I figured out I could set up my own bot with administrative privileges to sit on each room and probably make it to force kick/reconnect (for instance through openfire's administration via HTTP feature) the user when he's leaving the conference and he's not ending the session, so the auto join on connect would get him back. However I think it would be easier and more nice to simply change the client application, if there is an alternative.

UPDATE: I just found 'auto accept invite to group chats' option in spark, so if I reconfigure all clients without their knowledge and set up this bot to simply send invite if the person leaves the channel it should do the trick. Any other ideas?

UPDATE2:

Ok, guys, I have successfully tested "Spark->Preferences->Group chat->Automatically accept groupchat invites" option, it's working; my spark joins every conference I am invited to automatically. So I implemented that conference watching -> auto reinvite feature in JAXL 3.0 based bot. The only problem is that jaxl-sent invite does not work for me. Here's the source code:

<?php
###  JAXL message bot composed by ewilded
require 'JAXL-3.x/jaxl.php';
$jabber_conf=array('jid' => 'messagebot@localhost','host'=>'openfire','user'=>'messagebot','domain'=>'localhost','logLevel'=>4, 'strict'=>true, 'port'=>5222, 'pass'=>'somepass','log_level' => JAXL_INFO);
error_reporting(E_ALL);
$conference_rooms=array('[email protected]');
$client=null;

## Creating the object
$client = new JAXL($jabber_conf);
$client->require_xep(array(
      '0045', // MUC
      '0203', // Delayed Delivery
      '0199',  // XMPP Ping
      '0249'    // direct invite
));
## connect up callbacks
$client->add_cb('on_auth_success', function() use($client,$conference_rooms,$cron_interval) {
        echo "Auth success.\n";
    echo "My full jid: ".$client->full_jid->to_string()."\n";
        $client->set_status("Mesasge bot - available!");  // set your status
        $client->get_vcard();               // fetch your vcard
        $client->get_roster();              // fetch your roster list
        foreach($conference_rooms as $conference)
        {
            echo "Joining conference $conference.\n";
            $room_full_jid=new XMPPJid("$conference/messagebot");
            $client->xeps['0045']->join_room($room_full_jid);
       }
    });
$client->add_cb('on_chat_message', function($msg) use($client) {
            $to=$msg->from; 
          echo "Sending answer to: ".$to."\n";
            $client->send_chat_msg($to,"I am just simple bot written in PHP with JAXL XMPP library.");
        });
$client->add_cb('on_connect_error',function(){echo "Connection error :(\n";});
$client->add_cb('on_disconnect', function() {
     echo "Got disconnected.\n";
     _debug("got on_disconnect cb");
});

$client->add_cb('on_error_stanza',function($msg)
{    
    echo "Error stanza.";
    #print_r($msg);  
});
$client->add_cb('on_presence_stanza',function($msg) use($client)
{
    echo "Presence stanza.\n";
    ### joins and lefts are shown here, so here we simply send reinvite if we see that someone's left
    if(isset($msg->attrs['type'])&&$msg->attrs['type']=='unavailable')
    {
        if(isset($msg->childrens[0])&&isset($msg->childrens[0]->childrens[0])&&isset($msg->childrens[0]->childrens[0]->attrs['jid']))
        {
            echo "Sending invite.\n";
            $jid=$msg->childrens[0]->childrens[0]->attrs['jid'];
            $bare_jid=explode("/",$jid);
            $from_room=$msg->attrs['from'];
            $bare_from_room=explode("/",$from_room);
            echo $bare_jid[0]."\n";
            echo $bare_from_room[0]."\n";
            $client->xeps['0249']->invite($jid,$from_room); ### for some reason it does not work :(
            echo "Invite ($jid to $from_room) sent.\n";
        }
        else
        {
            echo "Ignoring.\n";
        }
    }
    echo "After presence stanza.\n";
});
$client->add_cb('on_normal_stanza',function()
{
    echo "Normal stanza.\n"; 
});
$client->add_cb('on_groupchat_message',function($msg) use ($client) {
echo "Groupchat event received.\n";
});

echo "Start called.\n";
$client->start();
?>

The conference room has "Allow occcupants to invite others" option on, both accounts (the one that my friend used to send me invite when it worked and the one that is used by messagebot) are members of the Tech group, none of them has administrative rights, so I am sure this is not settings/permissions related problem.

Now, when I leave the conference room, bot detects it and sends me invite, here's what it looks in its output: ... Presence stanza. Sending invite. ewilded@localhost [email protected] Invite (ewilded@localhost/Spark 2.6.3 to [email protected]/Ewil Ded) sent. After presence stanza. ... Unfortunately this invite does not take effect. I suppose I am doing something wrong with that xep call, or rather its parameters: $client->xeps['0249']->invite($jid,$from_room);

If anyone's got working invites in Jaxl, PLEASE help, this is the only thing left to do for this to work.

like image 275
ewilded Avatar asked Nov 21 '12 14:11

ewilded


1 Answers

Do you see invite packet being sent out in the logs?

For next level of debugging you might want to directly call $invite_pkt = $client->xeps['0249']->get_invite_pkt($to_bare_jid, $room_jid). Both $to_bare_jid and $room_jid must be passed as string. get_invite_pkt will return you the necessary stanza that needs to be send as per direct MUC invitation xmpp extension. If you see all is well with the returned stanza, simply send it by calling $client->send($invite_pkt).

Hopefully this should help you do better debugging and get through the problems.

like image 124
Abhinav Singh Avatar answered Dec 20 '22 21:12

Abhinav Singh