Schmavery / facebook-chat-api

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

wrong username/password error #867

Closed realrecordzLab closed 3 years ago

realrecordzLab commented 3 years ago

After two days of usage without problems, my node cli script that use this library has stopped working. I'm unable to login from the script and I always get wrong username/password message. I've tried to login from the browser and all is working fine, also tried to get a new ip but without success. Is there a fix I can use for this problem? The only way to make things work is to use an appstate.json file but now I've changed the password so the file will not work anymore.

I've saved my credentials insida a dedicated .env file

sebasbe91 commented 3 years ago

Same here :(

sebasbe91 commented 3 years ago

What I can see, they changed the way to send the password, new is encrypted on the field "encpass".

realrecordzLab commented 3 years ago

What I can see, they changed the way to send the password, new is encrypted on the field "encpass".

Where do you find that field? Please can you show a screen of this field?

realrecordzLab commented 3 years ago

@sebasbe91 I've done some debug and I've found the field encpass you've writed about in the headers, I think that to make the library working again the headers needs to be intercepted. I'm not sure how the field is generated, seems to be a base64 string combined uding : with a cipher and a key?

sebasbe91 commented 3 years ago

I was checking it deeper, it uses a Facebook library that encrypts it with a public key got from the form field. I think it necessary to replicate the same behavior.

realrecordzLab commented 3 years ago

I was checking it deeper, it uses a Facebook library that encrypts it with a public key got from the form field. I think it necessary to replicate the same behavior.

Is this library available on github? I want to try logging in using puppeteer or another headless browser, not sure if I will have success

sebasbe91 commented 3 years ago

I used dev tools in chrome to check it, needs further investigation.

realrecordzLab commented 3 years ago

I used dev tools in chrome to check it, needs further investigation.

let me know if you have any news about. The simplest solution I can think now is to copy the script you've found and then implement it inside the library to send the password crypted in the encpass field? or get cookies after login from chrome, but this will be more tricky

realrecordzLab commented 3 years ago

I've used puppeteer to login in messenger, I need to test also with facebook. This way seems working without problems. I'm able to get the needed cookies, I will try to implement it inside this library to replace the actual login method and to provide the needed informations for the correct creation of the appstate.json file.

tungnnt commented 3 years ago

I've used puppeteer to login in messenger, I need to test also with facebook. This way seems working without problems. I'm able to get the needed cookies, I will try to implement it inside this library to replace the actual login method and to provide the needed informations for the correct creation of the appstate.json file.

Can you show me how to get Facebook cookie as JSON format like appstate.json ?

realrecordzLab commented 3 years ago

I've used puppeteer to login in messenger, I need to test also with facebook. This way seems working without problems. I'm able to get the needed cookies, I will try to implement it inside this library to replace the actual login method and to provide the needed informations for the correct creation of the appstate.json file.

Can you show me how to get Facebook cookie as JSON format like appstate.json ?

The cookies that are created after the login with puppeteer are a bit different from the structure of the appstate.json file, I've opted to trying using a different userAgent into the options of the script and seems working. You can reference this issue for more details.

If you want to use puppeteer to get the cookies, you can use something like this:

const puppeteer = require('puppeteer');
const fs = require('fs');

( async () => {

(async () => {
    const browser = await puppeteer.launch({
        headless: false
    });

    const page = await browser.newPage();

    await page.goto('https://facebook.com/login, {
        waitUntil: ['load', 'networkidle2']
    });

    const cookieBanner = await page.$('[data-testid="cookie-policy-banner-accept"]');
    await cookieBanner.click();

    const emailField = await page.waitForSelector('[name="email"]', {timeout: 3000});
    await emailField.type(process.env.FB_EMAIL, {delay: 100});

    const passwordField = await page.waitForSelector('[name="pass"]', {timeout: 3000});
    await passwordField.type(process.env.FB_PASSWORD, {delay: 100});

    const submitButton = await page.waitForSelector('[name="login"]', {timeout: 3000});
    await submitButton.click();

    page.waitForNavigation().then( async (response) => {
       console.log(response.url(), response.headers(), response.method());
       // to get the correct cookies you need to pass the url to the cookies() method 
       // use await or .then() the promise return an object with all the needed info
       const cookies = await page.cookies(response.url());   
       // save your cookies to a file or use them in your code using fs.writeFileSync(...)
    });

})();
trangcongloc commented 3 years ago

The cookies that are created after the login with puppeteer are a bit different from the structure of the appstate.json file, I've opted to trying using a different userAgent into the options of the script and seems working. You can reference this issue for more details.

If you want to use puppeteer to get the cookies, you can use something like this:

const puppeteer = require('puppeteer');
const fs = require('fs');

( async () => {

(async () => {
    const browser = await puppeteer.launch({
        headless: false
    });

    const page = await browser.newPage();

    await page.goto('https://facebook.com/login, {
        waitUntil: ['load', 'networkidle2']
    });

    const cookieBanner = await page.$('[data-testid="cookie-policy-banner-accept"]');
    await cookieBanner.click();

    const emailField = await page.waitForSelector('[name="email"]', {timeout: 3000});
    await emailField.type(process.env.FB_EMAIL, {delay: 100});

    const passwordField = await page.waitForSelector('[name="pass"]', {timeout: 3000});
    await passwordField.type(process.env.FB_PASSWORD, {delay: 100});

    const submitButton = await page.waitForSelector('[name="login"]', {timeout: 3000});
    await submitButton.click();

    page.waitForNavigation().then( await (response) => {
       console.log(response.url(), response.headers(), response.method());
       // to get the correct cookies you need to pass the url to the cookies() method 
       // use await or .then() the promise return an object with all the needed info
       const cookies = await page.cookies(response.url());   
       // save your cookies to a file or use them in your code using fs.writeFileSync(...)
    });

})();

I'm using your code to get Cookie but the API showing this error

ERR! login Error: Cookie not in this host's domain. Cookie:www.facebook.com Request:www.messenger.com

I tried to get cookie from https://www.messenger.com/ and getting this error

ERR! login Error retrieving userID. This can be caused by a lot of things, including getting blocked by Facebook for logging in from an unknown location. Try logging in with a browser to verify.
{
  error: 'Error retrieving userID. This can be caused by a lot of things, including getting blocked by Facebook for logging in from an unknown location. Try logging in with a browser to verify.'
}

i double-check but my bot account didn't get any Checkpoint

realrecordzLab commented 3 years ago

@trangcongloc the library will create a different structure for the cookies that will be saved inside the appstate.json file. If you want to use puppeteer to get only the cookies, after the login you will need to format them to to reflect the appState expected structure otherwise the library will not work.

This is the required structure of the appstate.json file.

    {
        "key": "locale",
        "value": "en_US",
        "domain": "messenger.com",
        "path": "/",
        "secure": true,
        "hostOnly": false,
        "creation": "2021-02-23T12:07:23.715Z",
        "lastAccessed": "2021-02-23T12:07:26.469Z"
    }

It's completely different from the cookies that are retrived using puppeteer. the fields key in puppeteer is called name and the hostOnly field isn't present inside the cookies of puppeteer. There can be also other differences but I don't remember exactly

The wrong username/password error can be fixed by setting a different user-agent instead of the default one used from the library. Please refer to this issue for details.

vaqxai commented 3 years ago

The cookies that are created after the login with puppeteer are a bit different from the structure of the appstate.json file, I've opted to trying using a different userAgent into the options of the script and seems working. You can reference this issue for more details. If you want to use puppeteer to get the cookies, you can use something like this:

const puppeteer = require('puppeteer');
const fs = require('fs');

( async () => {

(async () => {
    const browser = await puppeteer.launch({
        headless: false
    });

    const page = await browser.newPage();

    await page.goto('https://facebook.com/login, {
        waitUntil: ['load', 'networkidle2']
    });

    const cookieBanner = await page.$('[data-testid="cookie-policy-banner-accept"]');
    await cookieBanner.click();

    const emailField = await page.waitForSelector('[name="email"]', {timeout: 3000});
    await emailField.type(process.env.FB_EMAIL, {delay: 100});

    const passwordField = await page.waitForSelector('[name="pass"]', {timeout: 3000});
    await passwordField.type(process.env.FB_PASSWORD, {delay: 100});

    const submitButton = await page.waitForSelector('[name="login"]', {timeout: 3000});
    await submitButton.click();

    page.waitForNavigation().then( await (response) => {
       console.log(response.url(), response.headers(), response.method());
       // to get the correct cookies you need to pass the url to the cookies() method 
       // use await or .then() the promise return an object with all the needed info
       const cookies = await page.cookies(response.url());   
       // save your cookies to a file or use them in your code using fs.writeFileSync(...)
    });

})();

I'm using your code to get Cookie but the API showing this error

ERR! login Error: Cookie not in this host's domain. Cookie:www.facebook.com Request:www.messenger.com

I tried to get cookie from https://www.messenger.com/ and getting this error

ERR! login Error retrieving userID. This can be caused by a lot of things, including getting blocked by Facebook for logging in from an unknown location. Try logging in with a browser to verify.
{
  error: 'Error retrieving userID. This can be caused by a lot of things, including getting blocked by Facebook for logging in from an unknown location. Try logging in with a browser to verify.'
}

i double-check but my bot account didn't get any Checkpoint

It doesn't work for me. I tried using it as TS and as JS and there's errors in both (unfortunately i'm too new to the programming paradigm that javascript uses so i have no idea how to fix this.

TS: image

JS: image

jjlabajo commented 3 years ago

Same problem. Any fix?

realrecordzLab commented 3 years ago

The cookies that are created after the login with puppeteer are a bit different from the structure of the appstate.json file, I've opted to trying using a different userAgent into the options of the script and seems working. You can reference this issue for more details. If you want to use puppeteer to get the cookies, you can use something like this:

const puppeteer = require('puppeteer');
const fs = require('fs');

( async () => {

(async () => {
    const browser = await puppeteer.launch({
        headless: false
    });

    const page = await browser.newPage();

    await page.goto('https://facebook.com/login, {
        waitUntil: ['load', 'networkidle2']
    });

    const cookieBanner = await page.$('[data-testid="cookie-policy-banner-accept"]');
    await cookieBanner.click();

    const emailField = await page.waitForSelector('[name="email"]', {timeout: 3000});
    await emailField.type(process.env.FB_EMAIL, {delay: 100});

    const passwordField = await page.waitForSelector('[name="pass"]', {timeout: 3000});
    await passwordField.type(process.env.FB_PASSWORD, {delay: 100});

    const submitButton = await page.waitForSelector('[name="login"]', {timeout: 3000});
    await submitButton.click();

    page.waitForNavigation().then( await (response) => {
       console.log(response.url(), response.headers(), response.method());
       // to get the correct cookies you need to pass the url to the cookies() method 
       // use await or .then() the promise return an object with all the needed info
       const cookies = await page.cookies(response.url());   
       // save your cookies to a file or use them in your code using fs.writeFileSync(...)
    });

})();

I'm using your code to get Cookie but the API showing this error

ERR! login Error: Cookie not in this host's domain. Cookie:www.facebook.com Request:www.messenger.com

I tried to get cookie from https://www.messenger.com/ and getting this error

ERR! login Error retrieving userID. This can be caused by a lot of things, including getting blocked by Facebook for logging in from an unknown location. Try logging in with a browser to verify.
{
  error: 'Error retrieving userID. This can be caused by a lot of things, including getting blocked by Facebook for logging in from an unknown location. Try logging in with a browser to verify.'
}

i double-check but my bot account didn't get any Checkpoint

It doesn't work for me. I tried using it as TS and as JS and there's errors in both (unfortunately i'm too new to the programming paradigm that javascript uses so i have no idea how to fix this.

TS: image

JS: image

You can't use await in that way. inside the then() you can use async. Change the code in this way

.then( async (response) => {  ... });

NB: I've fixed my typo inside the code I've posted

mobaradev commented 3 years ago

"ERR! login Error retrieving userID. This can be caused by a lot of things, including getting blocked by Facebook for logging in from an unknown location. Try logging in with a browser to verify. { error: 'Error retrieving userID. This can be caused by a lot of things, including getting blocked by Facebook for logging in from an unknown location. Try logging in with a browser to verify.' } "

Cookies are valid, but I cannot login

TuanNV95 commented 3 years ago

I also got this error when logging in with cookies, however I don't know how to fix it :( image

realrecordzLab commented 3 years ago

@mobaradev @TuanNV95 Have you tried to set a different user agent as suggested here?

TuanNV95 commented 3 years ago

@mobaradev @TuanNV95 Have you tried to set a different user agent as suggested here?

Yes, I tried it but I still get the same error result. I'm not sure, here's my code. image

realrecordzLab commented 3 years ago

@mobaradev @TuanNV95 Have you tried to set a different user agent as suggested here?

Yes, I tried it but I still get the same error result. I'm not sure, here's my code. image

You need to change the user agent of the facebook-chat-api script, not the one exposed from puppeteer. NB: I've not tested yet with the cookies retrived from puppeter so I don't know if cookies created with it are working with this library.

TuanNV95 commented 3 years ago

@mobaradev @TuanNV95 Have you tried to set a different user agent as suggested here?

Yes, I tried it but I still get the same error result. I'm not sure, here's my code. image

You need to change the user agent of the facebook-chat-api script, not the one exposed from puppeteer. NB: I've not tested yet with the cookies retrived from puppeter so I don't know if cookies created with it are working with this library.

Thank you, I made a mistake there, but after changing it, it still returns the same error. Maybe cookie retrieved from puppeteer don't really fit this library.


var options = {
    forceLogin: true,
    selfListen: true,
    listenEvents: true,
    updatePresence: true,
    autoMarkDelivery: true,
    autoMarkRead: true,
    userAgent: "Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Mobile Safari/537.36"
  };
 login({appState: JSON.parse(ss)}, options, (err, api) => {
     if(err) return console.error(err);
         console.log(err);
     console.log('ok!');
 });
AFalseHuman commented 3 years ago

Im also facing the same problem , I copied the one with puppeteer but when I run the js file nothing happens

hoangvu12 commented 3 years ago

@trangcongloc the library will create a different structure for the cookies that will be saved inside the appstate.json file. If you want to use puppeteer to get only the cookies, after the login you will need to format them to to reflect the appState expected structure otherwise the library will not work.

This is the required structure of the appstate.json file.

    {
        "key": "locale",
        "value": "en_US",
        "domain": "messenger.com",
        "path": "/",
        "secure": true,
        "hostOnly": false,
        "creation": "2021-02-23T12:07:23.715Z",
        "lastAccessed": "2021-02-23T12:07:26.469Z"
    }

It's completely different from the cookies that are retrived using puppeteer. the fields key in puppeteer is called name and the hostOnly field isn't present inside the cookies of puppeteer. There can be also other differences but I don't remember exactly

The wrong username/password error can be fixed by setting a different user-agent instead of the default one used from the library. Please refer to this issue for details.

Uh try this. Tell me if it works!

https://github.com/Schmavery/facebook-chat-api/issues/862#issuecomment-762436951

realrecordzLab commented 3 years ago

As I've said many times, the library works fine if into the options when a new instance is created you pass a different user agent. Maybe this code snippet will help you to understand what I mean.

const options = {
    userAgent: 'Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Mobile Safari/537.36',
    listenEvents: true
}
fb({email: process.env.FB_EMAIL, password: process.env.FB_PWD}, options, (err, api) => { ... });
hoangvu12 commented 3 years ago
const options = {
    userAgent: 'Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Mobile Safari/537.36',
    listenEvents: true
}
const options = {
  userAgent:
    "Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Mobile Safari/537.36",
  listenEvents: true,
};

login(loginData, options, (err, api) => {
  if (err) {
    switch (err.error) {
      case "login-approval":
        console.log("Enter code > ");
        rl.on("line", (line) => {
          err.continue(line);
          rl.close();
        });
        break;
      default:
        console.error(err);
    }
    return;
  }
  fs.writeFileSync("appstate.json", JSON.stringify(api.getAppState()));

  // Logged in!
});

image

This is what I've tried. Still got the error.

realrecordzLab commented 3 years ago
const options = {
    userAgent: 'Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Mobile Safari/537.36',
    listenEvents: true
}
const options = {
  userAgent:
    "Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Mobile Safari/537.36",
  listenEvents: true,
};

login(loginData, options, (err, api) => {
  if (err) {
    switch (err.error) {
      case "login-approval":
        console.log("Enter code > ");
        rl.on("line", (line) => {
          err.continue(line);
          rl.close();
        });
        break;
      default:
        console.error(err);
    }
    return;
  }
  fs.writeFileSync("appstate.json", JSON.stringify(api.getAppState()));

  // Logged in!
});

image

This is what I've tried. Still got the error.

The error is clear, you have the login approval turned on. Check the documentations to solve the problem.

hoangvu12 commented 3 years ago
const options = {
    userAgent: 'Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Mobile Safari/537.36',
    listenEvents: true
}
const options = {
  userAgent:
    "Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Mobile Safari/537.36",
  listenEvents: true,
};

login(loginData, options, (err, api) => {
  if (err) {
    switch (err.error) {
      case "login-approval":
        console.log("Enter code > ");
        rl.on("line", (line) => {
          err.continue(line);
          rl.close();
        });
        break;
      default:
        console.error(err);
    }
    return;
  }
  fs.writeFileSync("appstate.json", JSON.stringify(api.getAppState()));

  // Logged in!
});

image

This is what I've tried. Still got the error.

The error is clear, you have the login approval turned on. Check the documentations to solve the problem.

Well I solved this problem by remove the current 2fa method, then add new one and it just work.

CongTuHaoHoa commented 3 years ago

I have a solution here _https://youtu.be/y9_yd5a3scM_

Please tell me if it's works!