javascriptnode.jsxmppgoogle-talknode-xmpp

Unable to connect to GTalk with node.js and node-xmpp


I am trying to connect to GTalk using node.js and node-xmpp. Instead of successfully connecting, node-xmpp returns a XML error response.

Preparation

$node -v
v0.10.24
$npm install node-stringprep
$npm install node-xmpp
$npm list
...
├─┬ node-xmpp@0.12.2
...

gtalk.js

var xmpp = require('node-xmpp');
var sys = require("sys");

var options = {
    jid: "mygoogleid@gmail.com",
    password: "mygooglepassword"
    //,host: "talk.google.com"
    //,port: 5222
};

var jabber = new xmpp.Client(options);

jabber.on('online', function() {
    console.log("Connected");
});

jabber.on('error', function(e) {
    sys.puts(e);
});

Error

$node gtalk.js
<stream:error xmlns:stream="http://etherx.jabber.org/streams"><invalid-xml xmlns="urn:ietf:params:xml:ns:xmpp-streams"/></stream:error>

Possible explanations

  1. ID/password is wrong (login at google website does works)
  2. node-xmpp needs host/port to connect to GTalk (tried talk.google.com/5222)
  3. talk.google.com@5222 is wrong (Google Doc Open Com says it's correct)
  4. GTalk only allows OAuth2 (Google Doc Open Com says SASL PLAIN is allowed for "legacy" devices)
  5. This is the same as StackOverflow#4349577 (does not have same typo)
  6. I am using node-xmpp wrong
  7. GTalk does not respond as expected
  8. node-xmpp is buggy/does not support GTalk

I am pretty sure to have 1-5 ruled out and I would be glad to hear other explanations or evidence for 6-8. Thanks!

Updates

1. XML Stream ("=>" outbound, "<=" inbound)

=> <stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0" to="gmail.com">
<= <stream:stream from="gmail.com" id="C2AA8A4648B596A1" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client"><stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-OAUTH2</mechanism><mechanism>X-GOOGLE-TOKEN</mechanism></mechanisms></stream:features>
=> <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
<= <proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
=> <stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0" to="gmail.com">
<= <stream:stream from="gmail.com" id="3D42C6DC5985A9E6" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
<= <stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-OAUTH2</mechanism><mechanism>X-GOOGLE-TOKEN</mechanism><mechanism>PLAIN</mechanism></mechanisms></stream:features>
=> <auth auth:service="oauth2" xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="X-OAUTH2">AGNvaW2iaXRzeUBnbWFpbC5jb12AdW5kZWZpbmVk</auth>
<= <stream:error><invalid-xml xmlns="urn:ietf:params:xml:ns:xmpp-streams"/></stream:error>

It seems node-xmpp tries to use OAUTH2 although I haven't provided any token whatsoever. It should use PLAIN instead.

2. node-xmpp oauth example doesn't work either

Created OAUTH2 token according to node-xmpp pull request #85

$node node_modules/node_xmpp/examples/echo_bot_oauth.js gmailid@gmail.com oauth2token
No usable SASL mechanism

3. Adding preferred:"PLAIN" fixes connection issue

changing options to

 var options = {
   jid: "mygoogleid@gmail.com",
   password: "mygooglepassword",
   preferred: "PLAIN"
 };

fixes the error and seems to authenticate successfully. This might be evidence for explanation #8 (bug within node-xmpp).


Solution

  • This is a bug in node-xmpp introduced in 0.10.9.