Support multiple windows for a single user - XMPP chat using strophe.js - xmpp

I have a chat client that can be incorporated into multiple hosts, the chat client is independent.
User A logs in at two places - say chrome and firefox
So User A sends Message User B, User B receives the message, chat message is displayed at both sides.
Now User A has logged in at the window in the separate browser also, I want to push the message and display the message here also
Just like if you open a Gmail chat window at multiple browsers, then the sent message is pushed at both the ends.

XMPP protocol define JID as following:
JIDs consist of three main parts:
The node identifier (optional) The domain identifier (required) The
resource identifier (optional) JIDs are encoded UTF-8. A grammar will
be presented first, followed by specific clarifying and further
restricting remarks.
or in s simpler language you JID is built from:
Username#YourDomain.com/Resource
one user can have many resources,
for example:
prashantsahni#domain.com/phone
prashantsahni#domain.com/firefox
prashantsahni#domain.com/chrome
just set up the right resource for the user each time and let the XMPP Server to take care of the rest.
and you can look at this post to see how to do it with strophe
tou can read more about it in here:
https://xmpp.org/extensions/xep-0029.html

I am using message carbon.
There is a plugin provided by strophe. - strophe carbon

I have implemented using message carbons. The XEP is given here. For this to work you will need to check if the server supports this XEP. Most servers, Ejabberd, MongooseIM, Openfire, etc., supports the extension. The server will forward the message carbon to each resource. Once you have enabled message carbons in your server, all you need is to take care of the stanza which is being forwarded to you from each resource for a JID.
Lets say the JID for user A and user B is userA#domain.com and userB#domain.com, and you login to both chrome and firefox using the full JIDs below:
userA#domain.com/chrome
userA#domain.com/firefox
Now when you start sending message to user B from chrome, the message will be sent to your XMPP server which then also forwards the same message to your firefox browser. Lets say if the original message stanza sent from chrome is as follows:
<message xmlns='jabber:client'
from='userA#domain.com/chrome'
to='userB#domain.com'
type='chat'>
<body>What man art thou that, thus bescreen'd in night, so stumblest on my counsel?</body>
<thread>0e3141cd80894871a68e6fe6b1ec56fa</thread>
</message>
You should receive the forwarded stanza in your firefox as follows:
<message xmlns='jabber:client'
from='userA#domain.com'
to='userA#domain.com/firefox'
type='chat'>
<received xmlns='urn:xmpp:carbons:2'>
<forwarded xmlns='urn:xmpp:forward:0'>
<message xmlns='jabber:client'
from='userA#domain.com/chrome'
to='userB#domain.com'
type='chat'>
<body>What man art thou that, thus bescreen'd in night, so stumblest on my counsel?</body>
<thread>0e3141cd80894871a68e6fe6b1ec56fa</thread>
</message>
</forwarded>
</received>
</message>
You need to extract original message from the forwarded stanza. Also note that you can use each browser tab as a separate resource. You might also want to configure the maximum number of resources the server can handle at a time for a user.

Related

XMPP: How to send custom message between clients?

I want to send custom protocol between Xmpp clients, the server is Openfire.
For example, If client A want to establish a P2P call with client B, then A can send something like < iq > < call />< /iq > to B.
As far as I know, if A want to send B the custom < iq />, then the server needs to create a new plugin to handle this < iq /> packet. Is there anyway to implement this idea without the server change?
This depends on the server, but usually if you have an IQ stanza that is correctly addressed (from, id and complete FullJID of the destination) then the server should forward that stanza to the user just fine. The most important bit - it has to be FullJID (with resource) of your contact.
(copied from comment after indication that this worked for OP)

Blocking user using privacy list in ejabberd returns "not-well-formed"

I want to block other user in ejabberd on basis of jid. I am trying to send iq stanza through send_stanza_c2s command. Like :-
send_stanza_c2s admin localhost Smack "<iq from='admin#localhost/Smack' type='set' id='msg1'><query xmlns="jabber:iq:privacy"><list name="blocked"><item type="jid" value="jack10#localhost" action="deny" order="3"/><message/></item></list></query></iq>"
But it is giving me error.
Error: {4,<<"not well-formed (invalid token)">>}
Please help me with this.
Also guide me on if blocking user is achievable only through privacy lists (XEP-0016).
The IQ request stanza you send to the server is not well formed, I.e. invalid. If you used Smack's API for privacy lists then you should report this as bug.

Missing metadata in friend request for offline users

We are trying to customize the friend request in XMPP (Ejabberd) so that we can send additional metadata in friend request as shown below(shows the request as logged in ejabberd.log file). The issue is when the friend is offline, XMPP does not send the additional metadata (jidValue, profileImageURL etc.) when the friend request is eventually delivered to end user when they come online. But if the friend is online, when the request is sent, all the additional metadata is indeed delivered. Does anybody know why for offline users, the additional metadata is not sent and how it can possibly be resolved?
Here is the log file content:
2015-12-06 18:07:35.127 [debug]
<0.1763.0>#ejabberd_receiver:process_data:349 Received XML on stream =
<<"https://jabber.chatter.io/profiles/chatapp_profile56646b3323232.232323232.png\"
age=\"0\" gender=\"\" message=\"\">">>
packet
{xmlel,<<"presence">>,[{<<"type">>,<<"subscribe">>},{<<"to">>,<<"17032345678jinglebells#chat.chatter.io">>},{<<"jidValue">>,<<"1408123467abcd#chat.chatter.io/MCRJ">>},{<<"profileImageURL">>,<<"https://jabber.chatter.io/profiles/chatapp_profile56646b3323232.232323232.png">>},{<<"age">>,<<"0">>},{<<"gender">>,<<>>},{<<"message">>,<<>>}],[{xmlel,<<"x">>,[{<<"xmlns">>,<<"vcard-temp:x:update">>}],[{xmlel,<<"photo">>,[],[]}]}]}
When the friend is not online the friend request is not stored as is: Presence are not store for offline delivery. Instead, ejabberd looks for pending request and generate a new one when the user connects.
I created a ticket to support the feature on ejabberd Github: https://github.com/processone/ejabberd/issues/870
Note that your packet is wrong, as you seem to put your extension on attribute for convenience. They should be on custom subtag, with custom xmlns. What you do is not valid anyway. Customization should look similar the the x xmlns vcard content.
The attribute you add are not expected by XMPP in the jabber:client namespace.
I had the following XML send from my iOS client code to the other user who was offline
<presence type="subscribe" to="918054824047thj#chat.domain.io">
<profile xmlns="custom:data">
<profileImageURL>https://jabber.domain.io/profiles/slocamo_profile5667ec5aea78e2.08175827.png</profileImageURL>
<age>0</age>
<gender/>
<message/>
<jidValue>918054824047jitu#chat.domain.io/jitu</jidValue>
</profile>
<x xmlns="vcard-temp:x:update"><photo/></x>
</presence>
but when the user come's online he only receives the following XML
<presence xmlns="jabber:client" from="918054824047thj#chat.domain.io" to="918054824047jitu#chat.domain.io" type="subscribe">
<status/>
</presence>
let me know how to fix this

Facebook Chat (XMPP) XEP 0080 support

I have being checking out using a prototype test program the capabilities of the XMPP Facebook Chat, X-FACEBOOK. It worked great using a geoloc message XEP 0080 with Gmail servers, but when i try to send the same XML structure through the X-FACEBOOK, it trims the message and removes the GeoLoc node.
I wanted to ask if someone knows if its possible to send XEP 0080 messages in X-FACEBOOK and if so what structure should I use so the Facebook Chat XMPP Server won't trim the GeoLoc info.
Sent XMPP geoloc message:
<message to="-100002578491827#chat.facebook.com" from="4yony4#chat.facebook.com/19256ca9_4C5CC12947646" type="chat" xml:lang="en">
<event xmlns="http://jabber.org/protocol/pubsub#event">
<items node="http://jabber.org/protocol/geoloc">
<item id="">
<geoloc xmlns="http://jabber.org/protocol/geoloc">
<lat>40.488137</lat>
<lon>-3.397623</lon>
<timestamp>2012-07-27 09:09:50 GMT</timestamp>
<msgType>0</msgType>
</geoloc>
</item>
</items>
</event>
<body>
</body>
Received message by client:
<message xmlns="jabber:client" from="-1177157556#chat.facebook.com" to="" type="chat">
<active xmlns="http://jabber.org/protocol/chatstates"/>
<body></body>
</message>
Any solution or opinion will be greatly appreciated.
Well, changed the XML to resemble the one you posted, without the pub sub, and still the same problem, the message received in the recipient lacks all the namespaces under the GeoLoc node, which I think is a result of the Server not supporting that format. I can try and use the IQ subscriber option, thing is that I prefer to find a solution on which I can directly send the info to a user.
If there is a possibility, even a small one in which i may be able to send information regarding GeoLoc from User A to User B in Facebook Server it may be of great help, if not well i guess i will have to accept it.
Thx for the help BTW.
When I was testing facebook XMPP connection, it did not support almost any extensions and blocked any custom tags on server. It was able to send basic presences, basic messages, vcards and that was about all it could do.
Pubsub events should be sent to services. Modern XMPP servers also support PEP extension and you can send pubsub to servers itself. In other cases, use message with target user as Robin have advised.
I do not think facebook has any server with pubsub. Also i think it still filters any unsupported namespaces. Feel free to prove me I am wrong, it is more than year since I last tested it.
These are not the same message.
The received message is simply an indicator of the users chat state, as defined in XEP-0085 and has no direct relationship to the message you sent. That doesn't mean that the first didn't potentially trigger the second, whatever library you are using may have sent the chatstate as well when you sent the message. This type of message is commonly used in chat clients to indicate that someone you are chatting with is typing a message.
The problem is probably that the message you are sending is in fact a PEP message. This is meant to be sent by the PEP service in the server, not from a client. I don't know if Facebook supports PEP or not, but I would guess that it is being filtered out due to your incorrect usage of a known namespace. PEP or Pubsub are the recommended ways of publishing geolocation information, but to utilize those you have to send an IQ packet to the service, not a message to the other client.
Try this instead (Not saying it will work, but at least the pubsub stuff is stripped):
<message to="-100002578491827#chat.facebook.com" from="4yony4#chat.facebook.com/19256ca9_4C5CC12947646" type="chat" xml:lang="en">
<geoloc xmlns="http://jabber.org/protocol/geoloc">
<lat>40.488137</lat>
<lon>-3.397623</lon>
<timestamp>2012-07-27 09:09:50 GMT</timestamp>
<msgType>0</msgType>
</geoloc>
<body>
</body>
</message>
I want to second Pihhan. It seems like the Facebook XMPP servers restructure messages to contain only the message body, date, and timestamp. I think they do that to keep it identical to their comment graph objects.
It is annoying, but I suspect it is deliberate. After all, their Graph is the main issue, not XMPP.

strophe.js - messages are not delivered on chrome

I'm creating custom xmpp chat application with use of Strophe.js. The communication between browser and desktop client (Adium) works perfectly. I can send messages via browser to Adium and from Adium to the browser. There is yet the problem with browser-browser communication at some point as messages are sent but not delivered. It seems it's just Google Chrome problem.
What's interesting is the fact that <presence> stanzas are sent and delivered fine. We use ejabberd as the server daemon.
This is the presence stanza I'm sending from one account:
<presence type="away" xmlns="jabber:client">
<show>away</show>
<status/>
</presence>
and what I receive on the other:
<presence xmlns="jabber:client" from="test1#domain.com/3917283126133167196759537" to="test2#domain.com/1563391996133167110798391" type="away">
<show>away</show>
<status/>
</presence>
also the message stanza I send:
<message from="test1#domain.com/267172122813316722921543" to="test2#domain.com" type="chat" id="4915" xmlns="jabber:client">
<active xmlns="http://jabber.org/protocol/chatstates" />
<body>Testing...</body>
</message>
and nothing is received on Chrome...
EDIT:
The problem was with escaping some characters. Chrome did not let them unescaped due to security issues.
The type="away" in your initial presence is not valid. Omit the 'type' attribute for available presence. Set type="unavailable" when you are going offline.
Because your presence is invalid you are not marked as available, and you will not receive any messages addressed to your bare JID.
Update: To clear any confusion about what I mean by the above (see comments)...
The 'type' attribute on this stanza is invalid:
<presence type="away" xmlns="jabber:client">
<show>away</show>
<status/>
</presence>
It is otherwise fine. There are two types of presence a client may send, available and unavailable. Standard available presence has no 'type' attribute. Unavailable presence has type="unavailable". The actual status of the user (away, etc.) is signaled via the <show/> and <status/> elements, not the 'type' attribute.
To make it the above stanza a valid available presence, just remove type="away":
<presence xmlns="jabber:client">
<show>away</show>
<status/>
</presence>