Schmavery / facebook-chat-api

Unofficial Facebook Chat API for Nodejs
MIT License
1.93k stars 596 forks source link

Wrong username/password after browserifying #345

Closed Dudelmoser closed 7 years ago

Dudelmoser commented 7 years ago

I used the fix shown in url to browserify the api. I only had to comment out one single line using the "net" npm module (I think it was checking whether a string is a valid IP) after that to make it work (or alternatively replace "net" with "net-browserify").

But when running my bundled script as an extension or with disabled security settings in Chrome (both allow CORS), I get a "wrong username/password" error. I logged the form data right before the post function and it seems fine. But when comparing the login request header to a normal facebook login in the Chrome networks tab, it seems like the origin, a cookie and the whole form data is missing.

Neither browserifying nor running the code throws any exceptions. I tried using the "browser-request" module instead but had some compatibility issues (getJar method is unknown etc.). Everything works perfectly fine when I run this api on nodejs and I'm pretty sure that my login data is correct (normal fb logins work too).

Has anyone successfully logged in with a browserified version yet? Node.js seems to be no real option on mobile phones, so it should be essential for many of us to run it e.g. inside a WebView with CORS enabled on Android.

Dudelmoser commented 7 years ago

By the way: I think a client version of this api should be top priority cause you can't really use it on a server (except for local ones) without risking a ban. I know that you don't get paid for it and I'm really thankful that you invest so much time in it. I just assume that it might be quite easy for someone familiar with the code. I was thinking about porting the api to Java, but I'm in my last semester and kinda lack the time to do it before I've finished my exams.

Schmavery commented 7 years ago

As far as I can tell there are a number of issues that have been called out relating to making this run in a browser. The main one that stands out to me is the issue with cross-origin requests that would need to be made to facebook. There may be a couple of workarounds for this but so far none has stood out as particularly compelling to me. I'm obviously 100% ready to be proven wrong here and as always we're happy to help anyone who wants to tackle this problem. As far as servers go, as long as your server's location doesn't change frequently, it seems to work okay without getting banned, as far as I've seen. Fun fact: This api was originally made before the official chatbot api was released to allow people to write chatbots that would run on messenger. One of the only reason we still try to keep it running now (as far as I'm concerned, @bsansouci probably disagrees) is that it supports a number of features (group chat) that the official chatbot api does not.

Schmavery commented 7 years ago

As far as people trying to port this, we're happy to guide you and help you to know what we know, but understand that creating an api like this is a moving target because the facebook backend will update unpredictable and it will require continued updates over time. This unfortunately kills any potential hope for real reliability for this api and, if you ask me, invalidates its use in an actual production quality app.

Dudelmoser commented 7 years ago

It might not be very compelling to install a chrome extension, but most people seem to have no problem installing an app on iOS/Android. So you could actually reach all iOS and Android users plus more than half of the PC users with pretty much the same code running either inside a chrome extension or inside an embedded browser (e.g. WebView on Android). My issue with the server approach is that facebook would have such an easy time blocking your service. I want to write an extended facebook client as a bachelor thesis, so I don't have to meet the "100% uptime" criteria of a commercial product. And it seems like you guys have kept this API alive for quite some time. This API has definitely more to offer than just group chat bots - especially on the privacy and extra feature side if you do it properly.

I would be really happy if you tried to browserify it once. Inserting that process/stderr workaround plus replacing the net.isIP line and browserifying the whole thing is a matter of minutes. I'm just having a hard time finding the issue causing "Wrong username/password" afterwards since no exception is thrown. I must admit that I'm usually programming in Java and not that familiar with potential bug sources in JS.

bsansouci commented 7 years ago

@Dudelmoser Hey! Awesome that you really want to work on this. Could you submit a PR with everything that you have and I'll look over it. Can you add a print here to print res.headers and res.body. As soon as I get time I'll look into it personally.

Dudelmoser commented 7 years ago

I have a working (but not finished) client but it relies on node as some sort of proxy. It connects to the node proxy with socket.io and passes the api method calls (including parameters) as JSON. I've browserified the api without any features apart from your reference login code (to make it easier to debug). I can upload it but it might be better if you do it yourself to avoid potential mistakes I did while browserifying.

The res.body is the facebook login form with a hint to enable cookies. As I mentionned before the login form data doesn't seem to get transferred either, so I assume it could be an issue with chrome extensions. Maybe they strip the http request headers of certain data by default - so far I added the permission "<all_urls>" and "cookies".

Dudelmoser commented 7 years ago

I'd rather tell you what I did to browserify the api cause I might be doing something wrong.

// workaround
var Stream = require('stream');
var streamWrite = function (chunk, encoding, callback) {
    if (Buffer.isBuffer(chunk)) {
        chunk = chunk.toString(encoding);
    }
    console.log(chunk);
    if (callback)
        callback();
    return true;
};

var st = new Stream();
st.write = streamWrite;
var st2 = new Stream();
st2.write = streamWrite;

//  Instead of 
// process.stdout = new Stream();
// process.stderr = new Stream();
// As of Node 6+ you can not set process.stdout
var login = require("facebook-chat-api");

// Create simple echo bot
document.getElementById("loginBtn").onclick = function() {
    login({email: document.getElementById("usr").value, password: document.getElementById("pwd").value}, function callback (err, api) {
        if(err) return console.error(err);
        console.log("Logged in!");
    });
};
kamdz commented 7 years ago

@Dudelmoser and how? have you did it or you gave up?

Dudelmoser commented 7 years ago

I actually gave up the chrome extension and switched to the common Node approach. I have 7 exams left, I'll continue my React based messenger mid February...

Schmavery commented 7 years ago

Haha good luck on your exams @Dudelmoser!

ravkr commented 7 years ago

should we close it?

Schmavery commented 7 years ago

I suppose. Can always be reopened if necessary.