MUC Invite message is not sent to all user resources on Openfire - xmpp

I am having problems getting Openfire to send an invite message to all user resources associated with a user jid. I am using Openfire(3.9.3) and Strophe(1.1.3).
The users jid has 2 resources logged in on openfire (e.g. userA#chat.mychatserver.com/e1ef0b84, userA#chat.mychatserver.com/fa51aad7).
I have sent a MUC invite message to a user(i.e. userA) in order to join a room.
<?xml version="1.0"?>
<message xmlns:stream="http://etherx.jabber.org/streams"
xmlns="jabber:client" from="chatRoom#se.dev.openfire" to="userA#dev.openfire"
version="1.0">
<x xmlns="http://jabber.org/protocol/muc#user">
<invite from="userB#dev.openfire"/>
</x>
<x xmlns="jabber:x:conference" jid="chatRoom#dev.openfire"/>
</message>
I expected the invited to be sent to both resources (e.g. userA#chat.mychatserver.com/e1ef0b84, userA#chat.mychatserver.com/fa51aad7), however it only appears to be sent to the last logged in resources. For example if I logged in my phone as userA and then logged into my laptop as userA, the invite would only be sent to the laptop user.
Openfire seems to correctly route normal xmpp message to both user resources, I had expected muc invites to be handled in the same way.
Does anyone know whether this is at all possible?
Thanks,
Steve

Group invite is also treated as a normal message and it should get routed to all connected resources.
However for routing a message to all connected resources, Openfire has following logic:
Select session with highest presence priority, if no session qualifies, message is stored in offline store, If more than 1 sessions found with same priority, then Openfire becomes more smart ;) i.e. check the value of "route.all-resources" property.
If "route.all-resources" is true then message is routed to all those selected sessions, If value is false, then it sorts the sessions on the basis of show value (chat, available, away, xa) and again sorts the result on last active time and finally picks the 1st result and routes the message to that session.

Pay attention: according to XEP-0045 the XML to invite userA from userB is in the following form:
<message
from='userB#dev.openfire'
to='chatRoom#se.dev.openfire'>
<x xmlns='http://jabber.org/protocol/muc#user'>
<invite to='userA#dev.openfire'>
<reason>
Hey UserA, this is the place for all good witches!
</reason>
</invite>
</x>
</message>
then the XMPP server (Openfire in this case) must provide to send the XML:
<message
from='chatRoom#se.dev.openfire'
to='userA#dev.openfire'>
<x xmlns='http://jabber.org/protocol/muc#user'>
<invite from='userB#dev.openfire'>
<reason>
Hey UserA, this is the place for all good witches!
</reason>
</invite>
<password>xyz</password>
</x>
</message>
PS: another way is the direct invitation (not mediated by the room as in the XEP-0045), see http://xmpp.org/extensions/xep-0249.html

Related

How to implement "last seen at" functionality (like whatsapp) in XMPP?

I am working on a chat application and want to add "last seen at" functionality. I am trying to implement it by using presence stanzas but getting one issue, please check at below link
Not getting unavailable presence of User A when User B is also unavailable
Is there any other way to implement last seen at functionality
please suggest
The first Google result for "xmpp last seen" is XEP-0012: Last Activity, which is a protocol extension that can be used to find out when a user was online last time.
You send a request like this:
<iq from='romeo#montague.net/orchard'
id='last1'
to='juliet#capulet.com'
type='get'>
<query xmlns='jabber:iq:last'/>
</iq>
And get a response like this:
<iq from='juliet#capulet.com'
id='last1'
to='romeo#montague.net/orchard'
type='result'>
<query xmlns='jabber:iq:last' seconds='903'/>
</iq>
Which means that the contact was last online 903 seconds ago. Subtract this from the current time to get the "last seen" timestamp.
Last seen and Last Activity are two different scenarios.
Last Activity is when user gone offline last time, but last seen is when user goes in background from the application in that case user will be available if application is not killed.You have to create new plugin on server side for last seen.
The #legoscia solution will return the last activity time, which is your last logout time(not the last time when user was online), plz check this https://github.com/processone/ejabberd/issues/2265
If the user has at least one connected or available resource when the server receives the request, the response MUST (subject to local security policies) contain an empty element whose 'seconds' attribute is set to a value of '0'.
One solution is to kill the session every time the app goes in background and reconnect when the app is in foreground

Ejabberd: Get myself message on one - one chat

I have a web chat application, when user 1 login by one account in many browsers with difference resource and send a message to user 2.
Ex:
user 1 login in chrome with jid: user1#localhost/chrome
user 1 login in chrome whit jid: user1#localhost/firefox
User 1 in chrome send chat message for user2 with content "hello".
I got a problem here, ejabberd server just send "hello" to user2, but I want server also send a copy of "hello" for all user 1 in chrome and firefox.
How can I do it?
Yes, ejabberd support carbon message. My solution is: after sending a message, I send a copy of message for my self by setting "to" is my barejid and replace "type" is "copy" (my custom type):
<message to='me#192.168.2.90' type='copy' id='5ea1f7d8-1961-c9dc-b599-55a89438491b' xmlns='jabber:client'>
<body>hello</body>
<x >
<to>other#192.168.2.90</to>
</x>

Xmpp chat invisible presence

I'm building a bot that monitor friends presences but doesn't need to be visible.
I have tried to set presence using priority, show, type with all knowns values but without success.
Is possibile to be invisibile and just receive presence notifications?
Thanks!
See XEP-0126: Invisibility, section 3.1:
<iq from='bilbo#tolkien.lit/shire' type='set' id='inv1'>
<query xmlns='jabber:iq:privacy'>
<list name='invisible'>
<item action='deny' order='1'>
<presence-out/>
</item>
</list>
</query>
</iq>
Have a look at the rfc. Presence has a subscription status. If your bot is subscribed to receive presence from your users but your users are not, they are not going to be notified of the bot's presence.
In other words, your bot should send:
<presence to="user#example.com" type="subscribe" />
followed by the user's authorization,
<presence to="bot#example.com" type="subscribed" />
Now the bot will receive presence from the user, but not the opposite.
To set status for become invisible, you must send a presence with type "invisible".
<presence type="invisible"/>
And here is the code (in ios):
XMPPPresence *presence = [XMPPPresence presenceWithType:#"invisible"];
[[self xmppStream] sendElement:presence];
I use this code to set my status as "invisible".
For more details, please read the documentation on http://xmpp.org/extensions/xep-0018.html#sect-id86210
Last I knew from Facebook, it's not possible to implement invisibility via XMPP commands: https://developers.facebook.com/bugs/315067461919373. See also https://developers.facebook.com/docs/chat/ under Limitations.

How to Give everyone read and write access to a pubsub feed

I want to give everyone who subscribes to a node the ability to both read and write to that node.
Joe created the node "test5" in the code below. When Mark tries to post, I get an error.
I am using XMPPFramework for iphone. I receive the following error IQ. It appears that openfire is telling me that I can't publish an item b/c I don't have access? What is the default access model, open?
Doesn't that mean that anyone can subscribe to the node "test5", and anyone can publish items to it?
The JID of the fake user who originally created node "tes5" is "mark#joes-macbook-air.local"
Could the unauthorized message posting be b/c mark is not the owner of node titled "test5"?
What if I want mark to be able to post to this feed as well?
<iq xmlns="jabber:client" type="error" from="pubsub.joes-macbook-air.local" to="joe#joes-macbook-air.local/838f75ba"><pubsub xmlns="http://jabber.org/protocol/pubsub">
<publish node="test5"><item><body>Helpl me</body></item></publish>
</pubsub><error code="403" type="auth">
<forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
Update: I made the subscriber a "publisher". This is done by altering the publish_model of the node.
This depends on the node configurations in your pubsub service. Particularly the access mode of your node. In the XEP-0060 the access models section gives a good explanation on the different access methods. (1) The one you need in your case will be the "Open" which is defined as "Any entity may subscribe to the node (i.e., without the necessity for subscription approval) and any entity may retrieve items from the node (i.e., without being subscribed); this SHOULD be the default access model for generic pubsub services."
I hope this gives a clear answer to your question.

PEP handling with tigase server

Originally I was using an openfire backend for my web-based chat client. But since its pep did not work with clustering, I had to migrate to tigase.
Chat works fine with tigase, I haven't gotten to the clustering part but am still stuck with getting my old services up.
Note: I'm using strophe in my web app.
I am now trying to figure out how to get pep working with tigase. for pep with openfire, I just use the pep plugin with strophe and subscribe to another user's pep stream like such
myObj.connection.pep.subscribe(jid, node ,
function( iq ){ console.log(' > on_pep_subscription to '+jid+' node '+node+' SUCCESS');console.log(iq)},
function( iq ){ console.log(' > on_pep_subscription to '+jid+' node '+node+' FAIL');console.log(iq)},
function (msg){/*handle callback here*/}
to publish i use these:
myObj.connection.pep.publish('http://jabber.org/protocol/mood', newMood,
function( iq ){
console.log('- on_pep_publish to node "http://jabber.org/protocol/mood" SUCCESS'); console.log(iq);},
function( iq ){
console.log('- on_pep_publish to node "http://jabber.org/protocol/mood" FAIL');
console.log(iq); alert('failed to publish mood pls try again');});
This used to work fine with openfire but one big difference is that with tigase I don't get a callback success subscription. when I publish users on my roster automatically get my stream (which is good). But the problem is that I can't specify a handler for this event using strophe.
If i have 2 users cef and miko and my domain is mydomain. when i publish a mood with miko I get the following on cef:
<body xmpp:version="1.0" xmlns:xmpp="urn:xmpp:xbosh" secure="true" xmlns:stream="http://etherx.jabber.org/streams" xmlns="http://jabber.org/protocol/httpbind" ack="2545114322" from="mydomain">
<message id="2939:sendIQ" to="cef#mydomain" type="headline" from="miko#mydomain/tigase-15">
<event xmlns="http://jabber.org/protocol/pubsub#event">
<items node="http://jabber.org/protocol/mood">
<item>
<status>sad</status>
</item>
</items>
</event>
</message>
</body>
I've tried creating a handler on my own just like I would with the roster.
myObj.connection.addHandler(function(m){console.info('IQ WAAHAHAHAH');console.log(m);},null,"iq");
myObj.connection.addHandler(function(m){console.info('MESSAGE WAAHAHAHAH');console.log(m);},null,"message");
myObj.connection.addHandler(function(m){console.info('PRESENCE WAAHAHAHAH');console.log(m);},null,"presence");
for this particular event none of my handlers are able to handle them but with firebug and google's inspect I see an entry in the network with the said stanzas.
but It doesn't seem to work.
Does anyone have any idea?