ading2210 / poe-api

[UNMAINTAINED] A reverse engineered Python API wrapper for Quora's Poe, which provides free access to ChatGPT, GPT-4, and Claude.
https://pypi.org/project/poe-api
GNU General Public License v3.0
2.5k stars 315 forks source link

cannot get gql_POST, status code 400 #181

Closed brianler closed 1 year ago

brianler commented 1 year ago
          This looks good to me, but I just have one question. How did you find the `WpuLMiXEKKE98j56k` string? Was it just hardcoded in the client JS somewhere? If so, wouldn't it be really easy for Quora to break this library simply by changing that string again?

Originally posted by @ading2210 in https://github.com/ading2210/poe-api/issues/39#issuecomment-1509475143

Testing has found that self.gql_headers["poe-formkey"] can change, sometimes it is a 32-character string: ce7201131f80b20558f1a290a4690a4c, and sometimes it is a 33-character string: ce7201131f80b20558f1a290a4690a4c0. And it seems that the algorithm for generating the "poe-tag-id" in the headers has changed, resulting in the following problem.

WARNING:root:Server returned a status code of 400 while downloading https://poe.com/api/gql_POST. Retrying (2/10)...
WARNING:root:Server returned a status code of 400 while downloading https://poe.com/api/gql_POST. Retrying (3/10)...
WARNING:root:Server returned a status code of 400 while downloading https://poe.com/api/gql_POST. Retrying (4/10)...
WARNING:root:Server returned a status code of 400 while downloading https://poe.com/api/gql_POST. Retrying (5/10)...
WARNING:root:Server returned a status code of 400 while downloading https://poe.com/api/gql_POST. Retrying (6/10)...
WARNING:root:Server returned a status code of 400 while downloading https://poe.com/api/gql_POST. Retrying (7/10)...
WARNING:root:Server returned a status code of 400 while downloading https://poe.com/api/gql_POST. Retrying (8/10)...
WARNING:root:Server returned a status code of 400 while downloading https://poe.com/api/gql_POST. Retrying (9/10)...
WARNING:root:Server returned a status code of 400 while downloading https://poe.com/api/gql_POST. Retrying (10/10)...
Traceback (most recent call last):
  File "C:\Users\alfred\e\Python\server\main 3.11.py", line 54, in <module>
    ai = poe.Client(token)
  File "C:\Users\alfred\AppData\Local\Programs\Python\Python311\Lib\site-packages\poe.py", line 79, in __init__
    self.subscribe()
  File "C:\Users\alfred\AppData\Local\Programs\Python\Python311\Lib\site-packages\poe.py", line 160, in subscribe
    result = self.send_query("SubscriptionsMutation", {
  File "C:\Users\alfred\AppData\Local\Programs\Python\Python311\Lib\site-packages\poe.py", line 147, in send_query
    r = request_with_retries(self.session.post, self.gql_url, json=payload, headers=self.gql_headers)
  File "C:\Users\alfred\AppData\Local\Programs\Python\Python311\Lib\site-packages\poe.py", line 37, in request_with_retries
      raise RuntimeError(f"Failed to download {url} too many times.")
RuntimeError: Failed to download https://poe.com/api/gql_POST too many times.
noseon commented 1 year ago

def extract_formkey(self, html): script_regex = r'' script_text = re.search(script_regex, html).group(1) key_regex = r'var .="([0-9a-f]+)",' key_text = re.search(key_regex, script_text).group(1) cipher_regex = r'.[(\d+)]=.[(\d+)]' cipher_pairs = re.findall(cipher_regex, script_text)

what could have happened and that id changed name or location

ZikaiSun commented 1 year ago

I'm new to revert engineering. Just some clues that may or may not help:

image image image

On line 1974, the string is "Jb1hi3fg1MxZpzYfy", which appears to be used in generating the "poe-tag-id" header.

Changing this only do not make it work. Since the error presented by the program shifted, I guess there may be additional changes elsewhere. I suspect there might be another change occurring when requesting /api/setting.json.

image

I'm not sure weather the "If-None-Match:" has changed or not....

Looking forward to be rescued...

xieqing520 commented 1 year ago

I'm new to revert engineering. Just some clues that may or may not help:

image image image On line 1974, the string is "Jb1hi3fg1MxZpzYfy", which appears to be used in generating the "poe-tag-id" header.

Changing this only do not make it work. Since the error presented by the program shifted, I guess there may be additional changes elsewhere. I suspect there might be another change occurring when requesting /api/setting.json.

image

I'm not sure weather the "If-None-Match:" has changed or not....

Looking forward to be rescued...

you are right, it work

brianler commented 1 year ago

Cool, the problem has been solved, here's the solution.

Modify the ...\site-packages\poe.py file.

# -----Original
script_regex = r'<script>if\(.+\)throw new Error;(.+)</script>'
script_text = re.search(script_regex, html).group(1)
# -----Modified
# script_regex = r'<script>if\(.+\)throw new Error;(.+)</script>'
# script_text = re.search(script_regex, html).group(1)
script_text = html

# -----Original
self.formkey = self.extract_formkey(r.text)
# -----Modified
self.formkey = self.extract_formkey(r.text)[:32]

# -----Original
base_string = payload + self.gql_headers["poe-formkey"][:32] + "WpuLMiXEKKE98j56k"
# -----Modified
base_string = payload + self.gql_headers["poe-formkey"][:32] + "Jb1hi3fg1MxZpzYfy"