ahivert / tgtg-python

Unofficial client for TooGoodToGo API
GNU General Public License v3.0
372 stars 71 forks source link

Datadom captcha #205

Closed BigKamil5 closed 1 year ago

BigKamil5 commented 1 year ago

Hello,

I am facing similar issue to the https://github.com/ahivert/tgtg-python/issues/193 The problem is in fact that Too Good Too Go added Datadome as an anti bot system.

Whatever I do:

All the time I am facing the same 403 error with a html page as a response ... something geo-captcha something. The interesting fact is that Datadome can somehow detect my machine from which I am running script with my account credentials and block it, while the same account works without any problems on my phone.

<html>

<head>
    <title>apptoogoodtogo.com</title>
    <style>
      #cmsg {
        animation: A 1.5s;
      }

      @keyframes A {
        0% {
          opacity: 0;
        }

        99% {
          opacity: 0;
        }

        100% {
          opacity: 1;
        }
      }
    </style>
</head>

<body style="margin:0">
<p id="cmsg">Please enable JS and disable any ad blocker</p>
<script data-cfasync="false">
var dd={'cid':(some ids which i am afriad to provide)==','hsh':(some ids which i am afriad to provide),'t':'bv','r':'b','s':(some ids which i am afriad to provide),'e':(some ids which i am afriad to provide),'host':'geo.captcha-delivery.com'}
</script>
<script data-cfasync="false" src="https://ct.captcha-delivery.com/c.js"></script>
</body>

</html>

So yeah... The question is, does anyone have any idea how to bypass Datadome? Or is it even possible in any way?

leolehenaff commented 1 year ago

I finally find something that works. I use rotating mobile proxies that change IP adress every 5 minutes. Since I use that, I do not have problems.

Patanouque commented 1 year ago

Hi @leolehenaff , can you share your workaround with mobile proxies ? I tried with the "proxies" argument in the TgtgClient class but it doesn't seem to be working, let alone bypass datadome

filol commented 1 year ago

@BigKamil5 I have the same problem. I have just an idea why it's working on your phone and not your script. When you make the request from the app you have somes cookies, and one is called datadome :) Almost sure that doing many request from the same account without this cooies doesn't help us. Btw in my script i'm rotating the ip from a big pool but i also have the 403, strange ... I will try to find a way. @leolehenaff Strange that only rotating the ip is working. Why services are you using ?

Ismaw34 commented 1 year ago

Could this be integrated somehow? https://github.com/truongvinht/tgtg-checker/commit/12109f3ade1f674765ebd8e4326a56851371a8c6

hbui3 commented 1 year ago

for me (as a workaround) I first implemented the simple change from Dielee (https://github.com/Dielee/tgtg-python/commit/6548e9642f53fceb2d2f2dd408889d0d3312954b) Afterwards, I still got the 403 Error, but in the content of the response there is a URL which leads to a page where you can solve the captcha. If you reauthenticate afterwards, it starts working. Simple (bad) code example:

def _refresh_token(self):
    if (
        self.last_time_token_refreshed
        and (datetime.datetime.now() - self.last_time_token_refreshed).seconds
        <= self.access_token_lifetime
    ):
        return

    response = self.session.post(
        self._get_url(REFRESH_ENDPOINT),
        json={"refresh_token": self.refresh_token},
        headers=self._headers,
        proxies=self.proxies,
        timeout=self.timeout,
    )
    if response.status_code == HTTPStatus.OK:
        self.access_token = response.json()["access_token"]
        self.refresh_token = response.json()["refresh_token"]
        self.last_time_token_refreshed = datetime.datetime.now()
        # ___________ this is new
    elif response.status_code == 403:
        data = json.loads(response.content)
        url = data["url"]
        print(url)
        webbrowser.open(url)
        input() #checkpoint to wait for manual captcha completion ( I press enter in the console to continue the script)
        self._refresh_token()
        # __________
    else:
        raise TgtgAPIError(response.status_code, response.content)
tkuehne commented 1 year ago

Thanks @hbui3,

this helps somehow. 🎉 Does it also ask you to solve the captcha on every run then?

MauerHaus commented 1 year ago

I had to modify the code of @hbui3 a little bit in my case, because the response from the website was not in JSON. However, at the moment you have to press a button for each request, although after the first time the captcha remains valid for a while. So after solving the captcha once, you can send your requests normally for a certain period of time. So you can comment out the input.

       elif response.status_code == 403:
            url = response.url
            print(url)
            webbrowser.open(url)
            input()  # checkpoint to wait for manual captcha completion ( I press enter in the console to continue the script)
            self._refresh_token()
            # __________
hbui3 commented 1 year ago

I have a script running constantly on my server and I only had to solve the captcha once so far. I am initializing the client once at the start of my script and then have a loop running with client.get_items every 60 secs (+ random secs). Then you shouldn't need to press a button for each request, since it only asks for captcha at the initial login. @MauerHaus

MauerHaus commented 1 year ago

Thanks for the tips I'm currently still writing my script for the reason that is just a little annoying with the captcha. @hbui3

brouckaertd commented 1 year ago

Hi,

I've been testing the code and it seems that everything woks, as long as you don't start a new client... I'm starting a client every 5 minutes (only between 6 AM - 10 PM)

This is causing the 403 error.

I've been able to fix this by reading the 'set cookie' variable in the header and send it as a 'cookie' variable in my header.

Reading cookie from response: self.cookie_datadome = response.headers["Set-Cookie"]

Adding to my header for new request

if self.cookie_datadome:
            headers["Cookie"] = self.cookie_datadome

Tested a few times and worked like a charm.

wtluke commented 1 year ago

@brouckaertd Looks promising. Are you putting this in init.py? Would be helpful if you could share the code if you're happy to

BigKamil5 commented 1 year ago

I had to modify the code of @hbui3 a little bit in my case, because the response from the website was not in JSON. However, at the moment you have to press a button for each request, although after the first time the captcha remains valid for a while. So after solving the captcha once, you can send your requests normally for a certain period of time. So you can comment out the input.

       elif response.status_code == 403:
            url = response.url
            print(url)
            webbrowser.open(url)
            input()  # checkpoint to wait for manual captcha completion ( I press enter in the console to continue the script)
            self._refresh_token()
            # __________

Can you guys actually solve this captcha? For me loader is just spinning endlessly and I can't login after (still getting 403) image

hbui3 commented 1 year ago

I had to modify the code of @hbui3 a little bit in my case, because the response from the website was not in JSON. However, at the moment you have to press a button for each request, although after the first time the captcha remains valid for a while. So after solving the captcha once, you can send your requests normally for a certain period of time. So you can comment out the input.

       elif response.status_code == 403:
            url = response.url
            print(url)
            webbrowser.open(url)
            input()  # checkpoint to wait for manual captcha completion ( I press enter in the console to continue the script)
            self._refresh_token()
            # __________

Can you guys actually solve this captcha? For me loader is just spinning endlessly and I can't login after (still getting 403) image

That is normal. You have can close the window and Hit enter in the Terminal and it should work

brouckaertd commented 1 year ago

@brouckaertd Looks promising. Are you putting this in init.py? Would be helpful if you could share the code if you're happy to

Yes indeed, I've modified the init.py locally.

I introduced a new variable 'cookie_datadome', which is stored in my db and used to create a new client.

    def __init__( .... ,
            access_token_lifetime=DEFAULT_ACCESS_TOKEN_LIFETIME,
            device_type="ANDROID",
            cookie_datadome=None
        ):

            self.cookie_datadome = cookie_datadome

    def _headers(self):
           ....
            if self.cookie_datadome:
                headers["Cookie"] = self.cookie_datadome

            return headers

    def _refresh_token(self):
    ...
    if response.status_code == HTTPStatus.OK:
        ...
        self.cookie_datadome = response.headers["Set-Cookie"]
    else:
        raise TgtgAPIError(response.status_code, response.content)

    def start_polling(self, polling_id):
    ...
        elif response.status_code == HTTPStatus.OK:
            ...
            self.cookie_datadome = response.headers["Set-Cookie"]
            return
        else:
            if response.status_code == HTTPStatus.TOO_MANY_REQUESTS:
                ...
brouckaertd commented 1 year ago

I had to modify the code of @hbui3 a little bit in my case, because the response from the website was not in JSON. However, at the moment you have to press a button for each request, although after the first time the captcha remains valid for a while. So after solving the captcha once, you can send your requests normally for a certain period of time. So you can comment out the input.

       elif response.status_code == 403:
            url = response.url
            print(url)
            webbrowser.open(url)
            input()  # checkpoint to wait for manual captcha completion ( I press enter in the console to continue the script)
            self._refresh_token()
            # __________

Can you guys actually solve this captcha? For me loader is just spinning endlessly and I can't login after (still getting 403) image

I had the same issue, unable to fetch data after completing the captcha. That's why I started using the cookie.

MaxWinterstein commented 1 year ago

I tried to get my project that is based on this work here back on track, and here is what I came across:

Using all that knowledge I simply subclassed TgtgClient and added the cookie handling as well as the web browser part to solve the captcha.

class MyTgtgClient(TgtgClient):
    cookie_datadome = None

    def __init__(self, cookie_datadome=None, *args, **kwargs):
        TgtgClient.__init__(self, *args, **kwargs)
        self.cookie_datadome = cookie_datadome

    @property
    def _headers(self):
        headers = {
            "accept": "application/json",
            "Accept-Encoding": "gzip",
            "accept-language": self.language,
            "content-type": "application/json; charset=utf-8",
            "user-agent": self.user_agent,
        }
        if self.cookie_datadome:
            headers["Cookie"] = self.cookie_datadome
        if self.access_token:
            headers["authorization"] = f"Bearer {self.access_token}"
        return headers

    def _refresh_token(self):
        if (
            self.last_time_token_refreshed
            and (datetime.now() - self.last_time_token_refreshed).seconds <= self.access_token_lifetime
        ):
            return

        response = self.session.post(
            self._get_url(REFRESH_ENDPOINT),
            json={"refresh_token": self.refresh_token},
            headers=self._headers,
            proxies=self.proxies,
            timeout=self.timeout,
        )
        if response.status_code == HTTPStatus.OK:
            self.access_token = response.json()["access_token"]
            self.refresh_token = response.json()["refresh_token"]
            self.last_time_token_refreshed = datetime.now()
            self.cookie_datadome = response.headers["Set-Cookie"]
            pass
            # ___________ this is new
        elif response.status_code == 403:
            data = json.loads(response.content)
            url = data["url"]
            print(url)
            webbrowser.open(url)
            sleep(10)
            self._refresh_token()
            # __________
        else:
            raise TgtgAPIError(response.status_code, response.content)

    def start_polling(self, polling_id):
        for _ in range(MAX_POLLING_TRIES):
            response = self.session.post(
                self._get_url(AUTH_POLLING_ENDPOINT),
                headers=self._headers,
                json={
                    "device_type": self.device_type,
                    "email": self.email,
                    "request_polling_id": polling_id,
                },
                proxies=self.proxies,
                timeout=self.timeout,
            )
            if response.status_code == HTTPStatus.ACCEPTED:
                logger.warning(
                    f"Check your mailbox ({self.email}) on desktop to continue... "
                    "(Mailbox on mobile won't work, if you have tgtg app installed)"
                )
                time.sleep(POLLING_WAIT_TIME)
                continue
            elif response.status_code == HTTPStatus.OK:
                logger.info("Logged in")
                login_response = response.json()
                self.access_token = login_response["access_token"]
                self.refresh_token = login_response["refresh_token"]
                self.last_time_token_refreshed = datetime.now()
                self.user_id = login_response["startup_data"]["user"]["user_id"]
                self.cookie_datadome = response.headers["Set-Cookie"]
                return
            else:
                if response.status_code == HTTPStatus.TOO_MANY_REQUESTS:
                    raise TgtgAPIError(response.status_code, "Too many requests. Try again later.")
                else:
                    raise TgtgLoginError(response.status_code, response.content)

        raise TgtgPollingError(
            f"Max retries ({MAX_POLLING_TRIES * POLLING_WAIT_TIME} seconds) reached. Try again."
        )

Full code including all imports can be seen here:
https://github.com/MaxWinterstein/toogoodtogo-ha-mqtt-bridge/pull/117/files

Note: usage of datetime import is mixed, code is thrown together while watching tv 📺

Edit: Worth to mention, in my case tokens are stored in a json file as well as the datadome cookie

To sum things up, I guess only the code part that adds the cookie handling is really needed. In all my around 30 runs I never needed to solve a captcha when starting fresh without any existing token by just initializing a MyTgtgClient with just email, language, timeout and user_agent.

wtluke commented 1 year ago

@brouckaertd Looks promising. Are you putting this in init.py? Would be helpful if you could share the code if you're happy to

Yes indeed, I've modified the init.py locally. [ ... ]

Thanks very much. Unfortunately it hasn't helped/worked. Will have to wait for someone to offer a PR - my knowledge isn't good enough to work it out!

MaxWinterstein commented 1 year ago

@brouckaertd Looks promising. Are you putting this in init.py? Would be helpful if you could share the code if you're happy to

Yes indeed, I've modified the init.py locally. [ ... ]

Thanks very much. Unfortunately it hasn't helped/worked. Will have to wait for someone to offer a PR - my knowledge isn't good enough to work it out!

You might want to have a look at this commit: https://github.com/MaxWinterstein/toogoodtogo-ha-mqtt-bridge/commit/a8e36c677f8eddc4d1c5d8e52c1d4b6c16faf8ba

I simply subclassed TgtgClient and made all changes needed.

Just add https://github.com/MaxWinterstein/toogoodtogo-ha-mqtt-bridge/blob/main/toogoodtogo_ha_mqtt_bridge/mytgtgclient.py to your code, add some import like

from mytgtgclient import MyTgtgClient

and replace TgtgClient with MyTgtgClient in your code.

Rx2s1987 commented 1 year ago

@brouckaertd Looks promising. Are you putting this in init.py? Would be helpful if you could share the code if you're happy to

Yes indeed, I've modified the init.py locally. [ ... ]

Thanks very much. Unfortunately it hasn't helped/worked. Will have to wait for someone to offer a PR - my knowledge isn't good enough to work it out!

You might want to have a look at this commit: MaxWinterstein/toogoodtogo-ha-mqtt-bridge@a8e36c6

I simply subclassed TgtgClient and made all changes needed.

Just add https://github.com/MaxWinterstein/toogoodtogo-ha-mqtt-bridge/blob/main/toogoodtogo_ha_mqtt_bridge/mytgtgclient.py to your code, add some import like

from mytgtgclient import MyTgtgClient

and replace TgtgClient with MyTgtgClient in your code.

Hi and thank you for your help. I am a bit confused what i have to do, that tgtg is work again. What i have to write in the init,py ? If i copy the code from your link i got only errors.

python3 items.py Traceback (most recent call last): File "items.py", line 1, in from tgtg import TgtgClient File "/usr/local/lib/python3.8/dist-packages/tgtg/init.py", line 5, in from tgtg import ( ImportError: cannot import name 'AUTH_POLLING_ENDPOINT' from partially initialized module 'tgtg' (most likely due to a circular import) (/usr/local/lib/python3.8/dist-packages/tgtg/init.py)

Can you send me pls a init.py file which will be work ?

Thank you!

wtluke commented 1 year ago

You might want to have a look at this commit: MaxWinterstein/toogoodtogo-ha-mqtt-bridge@a8e36c6

I simply subclassed TgtgClient and made all changes needed.

Just add https://github.com/MaxWinterstein/toogoodtogo-ha-mqtt-bridge/blob/main/toogoodtogo_ha_mqtt_bridge/mytgtgclient.py to your code, add some import like

Cheers Max. Unfortunately, no joy for me. Same old tgtg.exceptions.TgtgAPIError: (403, b'{"url": issue. Very odd and frustrating but perhaps they've banned my IP or Mac address or something smart.

brouckaertd commented 1 year ago

You might want to have a look at this commit: MaxWinterstein/toogoodtogo-ha-mqtt-bridge@a8e36c6 I simply subclassed TgtgClient and made all changes needed. Just add https://github.com/MaxWinterstein/toogoodtogo-ha-mqtt-bridge/blob/main/toogoodtogo_ha_mqtt_bridge/mytgtgclient.py to your code, add some import like

Cheers Max. Unfortunately, no joy for me. Same old tgtg.exceptions.TgtgAPIError: (403, b'{"url": issue. Very odd and frustrating but perhaps they've banned my IP or Mac address or something smart.

Did you do a fresh login? Make sure you aren't sending a token / cookie while logging in.

The token can be invalid which is causing the error?

wtluke commented 1 year ago

You might want to have a look at this commit: MaxWinterstein/toogoodtogo-ha-mqtt-bridge@a8e36c6 I simply subclassed TgtgClient and made all changes needed. Just add https://github.com/MaxWinterstein/toogoodtogo-ha-mqtt-bridge/blob/main/toogoodtogo_ha_mqtt_bridge/mytgtgclient.py to your code, add some import like

Cheers Max. Unfortunately, no joy for me. Same old tgtg.exceptions.TgtgAPIError: (403, b'{"url": issue. Very odd and frustrating but perhaps they've banned my IP or Mac address or something smart.

Did you do a fresh login? Make sure you aren't sending a token / cookie while logging in.

The token can be invalid which is causing the error?

Maybe it's my misunderstanding. Turns out it does work if I do this:

client = MyTgtgClient(email='xxx')

But that requires the email auth workflow each time. I was hoping to do that once, get the credentials and use them in subsequent calls as per the docs.

credentials = client.get_credentials() client = MyTgtgClient(access_token=credentials['access_token'], refresh_token=credentials['refresh_token'], user_id=credentials['user_id'])

Seems that isn't possible

brouckaertd commented 1 year ago

You might want to have a look at this commit: MaxWinterstein/toogoodtogo-ha-mqtt-bridge@a8e36c6 I simply subclassed TgtgClient and made all changes needed. Just add https://github.com/MaxWinterstein/toogoodtogo-ha-mqtt-bridge/blob/main/toogoodtogo_ha_mqtt_bridge/mytgtgclient.py to your code, add some import like

Cheers Max. Unfortunately, no joy for me. Same old tgtg.exceptions.TgtgAPIError: (403, b'{"url": issue. Very odd and frustrating but perhaps they've banned my IP or Mac address or something smart.

Did you do a fresh login? Make sure you aren't sending a token / cookie while logging in. The token can be invalid which is causing the error?

Maybe it's my misunderstanding. Turns out it does work if I do this:

client = MyTgtgClient(email='xxx')

But that requires the email auth workflow each time. I was hoping to do that once, get the credentials and use them in subsequent calls as per the docs.

credentials = client.get_credentials() client = MyTgtgClient(access_token=credentials['access_token'], refresh_token=credentials['refresh_token'], user_id=credentials['user_id'])

Seems that isn't possible

The last instance of MyTgtgClient is possible with the new information that you received from your initial login (token, cookie, ...). One remark, I'm passing my cookie around, just like the access_token, so every request after my initial login is using the cookie.

MaxWinterstein commented 1 year ago

I created a PR #209 - hopefully this fixes it for everyone.

Again, thx to @brouckaertd whose code i shamelessly steal.

ahivert commented 1 year ago

New version 0.14.0 have been published on pypi. This one should fix issue encountered here

Rx2s1987 commented 1 year ago

New version 0.14.0 have been published on pypi. This one should fix issue encountered here

Works fine. Thanks to all for your work!! :)

azcn2503 commented 1 year ago

Hello!

I have started experiencing this issue today.

I am running the 0.14.0, and can browse the TooGoodToGo app from two iPhones on the same network. I suspect I am just out of luck.

brouckaertd commented 1 year ago

Hello!

I have started experiencing this issue today.

I am running the 0.14.0, and can browse the TooGoodToGo app from two iPhones on the same network. I suspect I am just out of luck.

What happens when you authenticate again? This means, you will get a new token, new cookie, ... And you need to open the login link on a device which doesn't have tgtg installed

azcn2503 commented 1 year ago

What happens when you authenticate again? This means, you will get a new token, new cookie, ... And you need to open the login link on a device which doesn't have tgtg installed

It seems I am not able to get that far. After I run:

tgtgClient.get_credentials()

I get the error:

Traceback (most recent call last):
  File "/home/aaron/Documents/tgtg_get_tokens.py", line 13, in <module>
    tgtgClient.get_credentials()
  File "/home/aaron/.local/lib/python3.10/site-packages/tgtg/__init__.py", line 87, in get_credentials
    self.login()
  File "/home/aaron/.local/lib/python3.10/site-packages/tgtg/__init__.py", line 178, in login
    raise TgtgLoginError(response.status_code, response.content)
tgtg.exceptions.TgtgLoginError: (403, b'{"url":"https://geo.captcha-delivery.com/captcha/?initialCid=snip"}')
Alfagek commented 1 year ago

I have the same problem with the captcha and 403 error, with this: https://github.com/Chouffy/home_assistant_tgtg

If i get a new captcha i do get the again this error

Aimane-Anass commented 11 months ago

Even when I resolve the captcha, the functions wouldn't work. Any solution on how to get a datadom token ?

JaimeleflanBabebibobu commented 6 months ago

I'm having the same issue, I'm starting to suspect my IP is just banned (I've been doing 10 requests per minute for the past 4 hours)

mail = "my_email@here.com"
client = TgtgClient(email=mail)
print(client.get_credentials())

produces this output :

Using version 24.2.13
Traceback (most recent call last):
  File ".\new_account.py", line 6, in <module>
    print(client.get_credentials())
  File "C:\Users\user\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\tgtg\__init__.py", line 92, in get_credentials
    self.login()
  File "C:\Users\user\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\tgtg\__init__.py", line 190, in login
    raise TgtgLoginError(response.status_code, response.content)
tgtg.exceptions.TgtgLoginError: (403, b'{"url":"https://geo.captcha-delivery.com/captcha/?initialCid=AHrlqAAAAAMAH5WyMzpe-kQA8vz_LA==&cid=L57x20Fy9RzADIYNAnUUsnddpz8Xcm0VhcQWfB02PRBrMTLCVMCAzy_n2QKtX9Z3UO4rfHKordnoY7CdXDxMwaxj6tOkP5XKepn1_nvPEIkBxf2CeqZMajdlZnaHoesA&referer=https%3A%2F%2Fapptoogoodtogo.com%2Fapi%2Fauth%2Fv3%2FauthByEmail&hash=1D42C2CA6131C526E09F294FE96F94&t=fe&s=35587&e=24e6625ee4edd40f04df338ac2b447f2c309c7d22251bc9d4190570a3ef84738"}')

I tried to open the url provided in the reponse. I get to a page where I'm asked to solve a captcha. When I do, nothing visible happens, but I see a new request being sent to

https://geo.captcha-delivery.com/captcha/check?cid=L57x20Fy9RzADIYNAnUUst1eWfWGn5OIk6fwpEIisU1eg5CUYDfV0dvPdyTXm8mR50FXLxLX9LPtHtCl99nHhXN9P2W7CDuSPm6eDgvDcuNiS~khrIZ4XbQfhOaDGz79&
icid=AHrlqAAAAAMAH5WyMzpe-kQA8vz_LA%3D%3D&
ccid=&
userEnv=d421d5cab5d82f35ded58389a2c1bf40be20b8f28740d9133ede7f7a32ad5c9c&
ddCaptchaChallenge=48d7c61bde8099b6800ecc0f355d4ee2&
ddCaptchaEncodedPayload=BIG_PAYLOAD_HERE&
ddCaptchaEnv=d405fb33692e8dd622fbd4476f913c2565878fb6319ce4dfeb830770ab2adb0db9f43fd9b794705b191f12b608349a0253ffdf8788a9585de0e6995547155a8b969704d326efefcf2df8886e7e1d69ee&
ddCaptchaAudioChallenge=5f447162a618c7752c7e8507a9cbceff&
hash=1D42C2CA6131C526E09F294FE96F94&
ua=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F122.0.0.0%20Safari%2F537.36&
referer=https%3A%2F%2Fapptoogoodtogo.com%2Fapi%2Fauth%2Fv3%2FauthByEmail&
parent_url=https%3A%2F%2Fgeo.captcha-delivery.com%2Fcaptcha%2F%3FinitialCid%3DAHrlqAAAAAMAH5WyMzpe-kQA8vz_LA%3D%3D%26cid%3DL57x20Fy9RzADIYNAnUUsnddpz8Xcm0VhcQWfB02PRBrMTLCVMCAzy_n2QKtX9Z3UO4rfHKordnoY7CdXDxMwaxj6tOkP5XKepn1_nvPEIkBxf2CeqZMajdlZnaHoesA%26referer%3Dhttps%253A%252F%252Fapptoogoodtogo.com%252Fapi%252Fauth%252Fv3%252FauthByEmail%26hash%3D1D42C2CA6131C526E09F294FE96F94%26t%3Dfe%26s%3D35587%26e%3D24e6625ee4edd40f04df338ac2b447f2c309c7d22251bc9d4190570a3ef84738&
x-forwarded-for=&
captchaChallenge=30349981&
s=35587&
ir=

The response of this request is this :

{
    "cookie": "datadome=L57x20Fy9RzADIYNAnUUsnHpBp7WmPJSm51sHQ_wI6iDBuwbqlVTsRo8Ty_m8~RhvUQAmvIoE7OnTajoBNB39733h88~UYXx0i_2_PM2em1TaJ~vNK1L5Qu~44NMrXYX; Max-Age=5184000; Domain=.apptoogoodtogo.com; Path=/; Secure; SameSite=Lax"
}

I already tried to use this cookie on next login, the python code now looks like this :

mail = "my_email@here.com"
cookie = "datadome=L57x20Fy9RzADIYNAnUUsnHpBp7WmPJSm51sHQ_wI6iDBuwbqlVTsRo8Ty_m8~RhvUQAmvIoE7OnTajoBNB39733h88~UYXx0i_2_PM2em1TaJ~vNK1L5Qu~44NMrXYX; Max-Age=5184000; Domain=.apptoogoodtogo.com; Path=/; Secure; SameSite=Lax"
client = TgtgClient(email=mail, cookie = cookie)
print(client.get_credentials())

but I have the same output (error with a new geo.captcha-delivery.com url, when I go there I can solve the captcha to get a new datadome cookie, but then I'm stuck again)

Any help will be greatly appreciated 😄