tulir / fbchat-asyncio

Facebook Messenger library for Python/Asyncio
https://pypi.org/project/fbchat-asyncio/
BSD 3-Clause "New" or "Revised" License
39 stars 11 forks source link

Logging in with cookies does not work. #14

Open szymonszl opened 4 years ago

szymonszl commented 4 years ago

Description of the problem

Trying to pass a set of cookies to the Client fails with two exceptions, one describing the fail to load them and another one from aiohttp related to it. It seems to be a problem with loading a cookie jar from the dict. The client logs in correctly, but it needs to log in every time instead of reusing sessions which increases the chance of getting blocked by facebook.

Code to reproduce

#!/usr/bin/env python3
import fbchat
import json
import asyncio

with open('bote/config.json') as fd:
    config = json.load(fd)
    email = config['login']
    password = config['password']
cookie_file = 'cookies.json'

loop = asyncio.get_event_loop()
loop.set_debug(True)

async def start():
    with open(cookie_file, 'r') as fd:
        cookies = json.load(fd)
    client = fbchat.Client(loop=loop)
    await client.start(email, password, session_cookies=cookies)
    with open(cookie_file, 'w') as fd:
        cookies = client.get_session()
        json.dump(cookies, fd)
    client.listen()
loop.run_until_complete(start())
loop.run_forever()

Traceback

Failed loading session
Traceback (most recent call last):
  File "/home/szymek/.local/lib/python3.8/site-packages/fbchat/_client.py", line 184, in set_session
    self._state = await _state.State.from_cookies(session_cookies, loop=self.loop,
  File "/home/szymek/.local/lib/python3.8/site-packages/fbchat/_state.py", line 216, in from_cookies
    return await cls.from_session(session=session)
  File "/home/szymek/.local/lib/python3.8/site-packages/fbchat/_state.py", line 179, in from_session
    user_id = get_user_id(session)
  File "/home/szymek/.local/lib/python3.8/site-packages/fbchat/_state.py", line 21, in get_user_id
    return str(rtn.value)
AttributeError: 'dict' object has no attribute 'value'
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7fa4660b3940>
source_traceback: Object created at (most recent call last):
  File "./test2.py", line 41, in <module>
    loop.run_until_complete(start())
  File "/usr/lib/python3.8/asyncio/base_events.py", line 595, in run_until_complete
    self.run_forever()
  File "/usr/lib/python3.8/asyncio/base_events.py", line 563, in run_forever
    self._run_once()
  File "/usr/lib/python3.8/asyncio/base_events.py", line 1836, in _run_once
    handle._run()
  File "/usr/lib/python3.8/asyncio/events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
  File "./test2.py", line 33, in start
    await client.start(email, password, session_cookies=cookies)
  File "/home/szymek/.local/lib/python3.8/site-packages/fbchat/_client.py", line 100, in start
    or not await self.set_session(session_cookies)
  File "/home/szymek/.local/lib/python3.8/site-packages/fbchat/_client.py", line 184, in set_session
    self._state = await _state.State.from_cookies(session_cookies, loop=self.loop,
  File "/home/szymek/.local/lib/python3.8/site-packages/fbchat/_state.py", line 214, in from_cookies
    session = session_factory(loop, user_agent)
  File "/home/szymek/.local/lib/python3.8/site-packages/fbchat/_state.py", line 29, in session_factory
    return aiohttp.ClientSession(loop=loop or asyncio.get_event_loop(), headers={

Environment information

Python 3.8.0 (default, Oct 23 2019, 18:51:26) 
[GCC 9.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import fbchat
>>> fbchat.__version__ # downloaded with pip
'0.3.0'
tulir commented 4 years ago

The cookie stuff is a bit hacky (relying on private aiohttp fields), so maybe try pickle instead of json for storing the cookies.

PythonNut commented 4 years ago

I can confirm logging in with cookies seems to work fine if you pickle the session_cookies.

syspic commented 4 years ago

I keep getting null/None as the cookies when I client.get_session()

Also how do you use the pickel thing?