powered by Jive Software

No custom smileys in MUC when smack client present

We have an openfire that hosts a number of MUCs. Most of our human clents are based on libpurple. I have also written a little service robot using the smack library.

I noticed something strange. We could send custom smileys through the chat room, and the images would get transmitted to all (human) clients, without them having to have the custom smiley in advance. This stops working as soon as any smack based client is in the chat. It’s almost as if openfire realizes that there’s an incapable client in the room, so it doesn’t even try to relay those image files.

Can anybody explain why this is the case?


I have a feeling that when I make my initial connection I can set some feature in the ServiceDiscoveryManager that would fx this problem. I just can’t figure out what it is.


ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);





I also looked at http://xmpp.org/registrar/namespaces.html to see if there was some capability that says “My xhtml can accept images” …

I guess the first step would be to look at the raw stanzas that libpurple sends and find out how they include the smilieys in the text.

What it sends perfectly matches XEP-0231 … specifically example 1 in section 2.2. It’s an XHML-IM message with an image whose source is a content ID (cid).

I think there’s some kind of negotiation between the Openfire MUC and the smack client, and I think it has something to do with some capability negotiation. I just can’t figure out what.

I am not sure, but it’s more likely that the negotiation is done between smack and libpurple with the help of Service Discovery. IIRC smack does not support urn:xmpp:bob and therefore libpurple stops sending stanzas that make use of it. Openfire (or any other XMPP server) just acts as middleman and doesn’t care about the content of the stanzas.

Ahhh. I do see that my client requests the images, so I set up a listener on the smack side to listen for those messages:

connection.addPacketListener( bobListener, new IQTypeFilter( IQ.Type.GET ) );

connection.addPacketListener( bobListener, new IQTypeFilter( IQ.Type.SET ) );

connection.addPacketListener( bobListener, new IQTypeFilter( IQ.Type.ERROR ) );

connection.addPacketListener( bobListener, new IQTypeFilter( IQ.Type.RESULT ) );

where bobListner for now just listens for those gets. I thought I could get away with implementing a really simple version of bob, but I don’t even see the requests. I therefore assumed that openfire’s MUC was not forwarding them to me. Perhaps it’s not as simple as I thought.

I did a bunch more testing, using the above … and when I send an image, other clients see the iq request for the urn:xmpp:bob of the image but smack does NOT.

Somehow, I still think that the MUC in openfire is filtering them. I don’t know how, but I’m trying to prove it.

OK. I’m on the path of the answer here. Check this out.

I’m in a muc using pidgin. There is also a smack client in the chatroom. I try to send a picture of a chicken by typing the word “chicken”, and what pidgin sends to the muc is this:

<message type=‘groupchat’ id=‘purple408cd26f’ to=‘xxx@conference.chat.xxx.com’>



Now, in the same room, I kick out all of the smack based clients. I again type the word chicken, exactly as before, but this time pidgin sends:

<message type=‘groupchat’ id=‘purple408cd273’ to=‘xxx@conference.chat.xxx.com’>


<**html** **xmlns**='**http://jabber.org/protocol/xhtml-im**'>

    <**body** **xmlns**='**http://www.w3.org/1999/xhtml**'>


        <**img** **alt**='chicken' **src**='cid:sha1+0e1ba91075cd60c6ad54807af38c3fa4dabd9c02@bob.xmpp.org'/>





What seems to be happening is that my pidgin recognizes that there’s a non-pidgin client in the muc, so it doesn’t even attempt to send the XHTML message.

In examinign this, I notice something. The smack based clients report their presence as:

<presence id=‘AWHQf-5’ to=‘cepasp@chat.xxx.com/leavenworth’ from=‘xxx@conference.chat.xxx.com/Wendell’>

<**x** **xmlns**='**http://jabber.org/protocol/muc#user**'>

    <**item** **jid**='imservice2@chat.xxx.com/Wendell' **affiliation**='none' **role**='participant'/>



However, the presence from a pidgin client looks like this:

<presence to=‘cepasp@chat.xxx.com/leavenworth’ from=‘xxx@conference.chat.xxx.com/nelliott’>


<**c** **xmlns**='**http://jabber.org/protocol/caps**' **node**='http://pidgin.im/' **hash**='sha-1' **ver**='I22W7CegORwdbnu0ZiQwGpxr0Go='/>

<**x** **xmlns**='**vcard-temp:x:update**'>



<**x** **xmlns**='**http://jabber.org/protocol/muc#user**'>

    <**item** **jid**='nelliott@chat.xxx.com/e002b5dc' **affiliation**='none' **role**='participant'/>



I think the key is the caps. My theory is that pidgin looks at the muc, looks at who’s there, and notes what their cilent is. Then, if it sees a pidgin client it sends images but if it sees a non-pidgin client it doesn’t. General XHTML messages (without images) work in all cases. It’s the sending of that’s the problem. Consider this message, with an XHTML-IM body. This is what my pidgin client sends even with smack clients on the muc. To cause it to produce this message I sent it in bold. ‘chicken’ should have been an like above, but pidgin chose to not send it that way because of the presence of the smack client:

<message type=‘groupchat’ id=‘purple408cd420’ to=‘liban_chat@conference.chat.libaninc.com’>


<**html** **xmlns**='**http://jabber.org/protocol/xhtml-im**'>

    <**body** **xmlns**='**http://www.w3.org/1999/xhtml**'>


    <**span** **style**='font-weight: bold;'>TEST TEST chicken TEST TEST</**span**>





I have attempted to fix this by using the flow fork of smack and smackx. I modify my connection as follows:

Presence pres = new Presence( Presence.Type.available );

        CapsExtension caps = new CapsExtension( "[http://pidgin.im/](http://pidgin.im/)", "I22W7CegORwdbnu0ZiQwGpxr0Go=", "sha-1");

pres.addExtension( caps );

connection.sendPacket( pres );

in other words, I’m trying to fake being a pidgin client to see how that changes thigns. It doesn’t help (yet) because I think I have it wrong. I don’t really know how to construct that verification string. I also don’t know if my smack client needs to keep sending those presence messages over and over, or if it’s sufficient to do it just once on startup.

Hello, running 3.8.1 and pidgin 2.10.7, i’ve noticed that custom smileys are not sent inside the xmpp packets.

I’ve checked the IQ messages sent when pidgin connects, and the reply service discovery looks like this