SI File Transfer, Entity Capabilities, iChat, and Your Jabber Bot

What do these things have in common? This is the only place on the entire internet where you can read useful information about all of these things.

I’ve toyed with jabber bots before, mostly using the various XMPP stacks available for Python. This time, I wanted to find something even more high level, and I think I found it in Blather - the example echo bot weighs in at 9 lines of code, including the 2 require statements. Trying to send it a file, however, results in this:

unable-to-receive

I spent a while figuring out what’s required of a jabber bot so that iChat Messages will allow its user to send a file. Researching XMPP file transfer might not be such a mystical odyssey if you were implementing everything from scratch, but if instead you’re trying to (ostensibly) save some time and write as little code as possible, the path isn’t terribly clear. In this case, I ended up learning a fair amount about XMPP. ~20 hours of fervent web searching and reading yielded ~3 lines of code.

I found one solitary post from somebody writing a Blather bot who had this same problem. He was informed that the bot needs to advertise the correct set of capabilities for file transfer, however that guy wasn’t sure what they were. Somebody else chimed in, but that response was broken and also incomplete – but it was enough to put me on the right track. The minimum set of capabilities needed to be a XEP-0096 compliant file transfer recipient  are:

    <feature var="http://jabber.org/protocol/ibb"/>
    <feature var="http://jabber.org/protocol/bytestreams"/>
    <feature var="http://jabber.org/protocol/si"/>
    <feature var="http://jabber.org/protocol/si/profile/file-transfer"/>

Here is a working XMPP bot that can receive files sent by another client, using the XEP 0096 spec. Running it looks something like this:

csbot@botboy[~/cs-bot]ruby xmpp_receiver.rb
Connected to talkman@talk.example.com/1376830693085. Sent capabilities:
<iq type="result" id="blather0001">
  <query xmlns="http://jabber.org/protocol/disco#info" node="http://dreness.com/csbot#cc5+HwPwVxjmjK9bPjmuvv/Ehh8=">
    <identity name="csbot" type="bot" category="client"/>
    <feature var="http://jabber.org/protocol/ibb"/>
    <feature var="http://jabber.org/protocol/bytestreams"/>
    <feature var="http://jabber.org/protocol/si"/>
    <feature var="http://jabber.org/protocol/si/profile/file-transfer"/>
  </query>
</iq>

Receiving file from dre@xomg.example.com/foci
<file xmlns="http://jabber.org/protocol/si/profile/file-transfer"
  xmlns:ichat="apple:profile:transfer-extensions"
  name="btc-watcher.py"
  size="5387"
  posixflags="000001ED"/>

 

About dre

Wandering *nix / mac geek, scouring the land for new and interesting things...
This entry was posted in bit bucket. Bookmark the permalink.

7 Responses to SI File Transfer, Entity Capabilities, iChat, and Your Jabber Bot

  1. dharris says:

    Thank you so much for this post. I’ve used it to create a working bot that accepts file transfers. It works great with Adium, but I can’t get it working with files sent via Apple Messages.app.

    In both cases (Adium and Messages), Blather throws this error:

    D, [2013-09-20T11:46:56.267777 #16760] DEBUG — : SENDING: (/var/lib/gems/1.9.1/gems/blather-0.8.7/lib/blather/client/client.rb:149:in `write’)

    Adium seems to ignore it and continues with the file transfer, but Messages gives up and fails. Do you have any advice?

    Thank you.

  2. dharris says:

    (edited by admin)

  3. dharris says:

    one more time . . without tags.
    iq type=”error” id=”iChat_0267418B” from=”support@knockinc.com/kerio-20″
    error type=”cancel”
    item-not-found xmlns=”urn:ietf:params:xml:ns:xmpp-stanzas”
    error
    /iq

    • dre says:

      Hi! Hmm… I don’t believe I’ve seen that error before. I don’t have time to mess with this again for several days, but there might be some stuff you can do; Blather allows you to forcibly disable either ibb or socks modes individually (allow_ibb and allow_s5b, in Blather::FileTransfer), so it may be possible to at least narrow the failure down.

      • dharris says:

        Thank you for the quick response. Toggling transfer.allow_ibb didn’t result in any new errors, but setting transfer.allow_s5b = false resulted in this:

        bad-request xmlns=”urn:ietf:params:xml:ns:xmpp-stanzas”
        no-valid-streams xmlns=”http://jabber.org/protocol/si”

  4. dharris says:

    I’m working this out at the blather google group:
    https://groups.google.com/forum/#!topic/xmpp-blather/LMl6pR9qHfA

    setting transfer.allow_private_ips = true resolved the transfer issue.

    • dre says:

      Excellent. I also have the problem with the transfer not starting until something is typed in the input field (even without sending; I’m guessing the sending of the ‘other user is typing’ stuff is enough to wake up the stream to push the xfer through); I’ll watch the google group thread for the resolution.

Leave a Reply