XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/gpt4free

quora (poe) [gpt-4/3.5] api unpatch

c38e367e
t.me/xtekky <98614666+xtekky@users.noreply.github.com>
提交于

代码差异

4 个文件 +119 -98
Modified quora/__init__.py +50 -31
@@ -8,9 +8,25 @@ from pathlib import Path
8 8 from random import choice, choices, randint
9 9 from string import ascii_letters, digits
10 10 from urllib import parse
11 from os import urandom
12 from hashlib import md5
13 from json import dumps
11 from os import urandom
12 from hashlib import md5
13 from json import dumps
14
15 def extract_formkey(html):
16 script_regex = r'<script>if\(.+\)throw new Error;(.+)</script>'
17 script_text = search(script_regex, html).group(1)
18 key_regex = r'var .="([0-9a-f]+)",'
19 key_text = search(key_regex, script_text).group(1)
20 cipher_regex = r'.\[(\d+)\]=.\[(\d+)\]'
21 cipher_pairs = findall(cipher_regex, script_text)
22
23 formkey_list = [""] * len(cipher_pairs)
24 for pair in cipher_pairs:
25 formkey_index, key_index = map(int, pair)
26 formkey_list[formkey_index] = key_text[key_index]
27 formkey = "".join(formkey_list)
28
29 return formkey
14 30
15 31 class PoeResponse:
16 32
@@ -79,7 +95,8 @@ class Model:
79 95
80 96 client = Session()
81 97 client.cookies['p-b'] = token
82
98
99 formkey = extract_formkey(client.get('https://poe.com').text)
83 100 settings = client.get('https://poe.com/api/settings').json()
84 101
85 102 client.headers = {
@@ -87,7 +104,7 @@ class Model:
87 104 "origin" : "https://poe.com",
88 105 "referer" : "https://poe.com/",
89 106 "content-type" : "application/json",
90 "poe-formkey" : settings['formkey'],
107 "poe-formkey" : formkey,
91 108 "poe-tchannel" : settings['tchannelData']['channel'],
92 109 "user-agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
93 110 "connection" : "keep-alive",
@@ -102,8 +119,8 @@ class Model:
102 119 "accept-encoding" : "gzip, deflate, br",
103 120 "accept-language" : "en-GB,en-US;q=0.9,en;q=0.8",
104 121 }
105
106 response = client.post("https://poe.com/api/gql_POST", json = {
122
123 payload = dumps(separators=(',', ':'), obj = {
107 124 'queryName': 'CreateBotMain_poeBotCreate_Mutation',
108 125 'variables': {
109 126 'model' : models[model],
@@ -124,6 +141,11 @@ class Model:
124 141 'query': 'mutation CreateBotMain_poeBotCreate_Mutation(\n $model: String!\n $handle: String!\n $prompt: String!\n $isPromptPublic: Boolean!\n $introduction: String!\n $description: String!\n $profilePictureUrl: String\n $apiUrl: String\n $apiKey: String\n $isApiBot: Boolean\n $hasLinkification: Boolean\n $hasMarkdownRendering: Boolean\n $hasSuggestedReplies: Boolean\n $isPrivateBot: Boolean\n) {\n poeBotCreate(model: $model, handle: $handle, promptPlaintext: $prompt, isPromptPublic: $isPromptPublic, introduction: $introduction, description: $description, profilePicture: $profilePictureUrl, apiUrl: $apiUrl, apiKey: $apiKey, isApiBot: $isApiBot, hasLinkification: $hasLinkification, hasMarkdownRendering: $hasMarkdownRendering, hasSuggestedReplies: $hasSuggestedReplies, isPrivateBot: $isPrivateBot) {\n status\n bot {\n id\n ...BotHeader_bot\n }\n }\n}\n\nfragment BotHeader_bot on Bot {\n displayName\n messageLimit {\n dailyLimit\n }\n ...BotImage_bot\n ...BotLink_bot\n ...IdAnnotation_node\n ...botHelpers_useViewerCanAccessPrivateBot\n ...botHelpers_useDeletion_bot\n}\n\nfragment BotImage_bot on Bot {\n displayName\n ...botHelpers_useDeletion_bot\n ...BotImage_useProfileImage_bot\n}\n\nfragment BotImage_useProfileImage_bot on Bot {\n image {\n __typename\n ... on LocalBotImage {\n localName\n }\n ... on UrlBotImage {\n url\n }\n }\n ...botHelpers_useDeletion_bot\n}\n\nfragment BotLink_bot on Bot {\n displayName\n}\n\nfragment IdAnnotation_node on Node {\n __isNode: __typename\n id\n}\n\nfragment botHelpers_useDeletion_bot on Bot {\n deletionState\n}\n\nfragment botHelpers_useViewerCanAccessPrivateBot on Bot {\n isPrivateBot\n viewerIsCreator\n}\n',
125 142 })
126 143
144 base_string = payload + client.headers["poe-formkey"] + 'WpuLMiXEKKE98j56k'
145 client.headers["poe-tag-id"] = md5(base_string.encode()).hexdigest()
146
147 response = client.post("https://poe.com/api/gql_POST", data = payload)
148
127 149 if not 'success' in response.text:
128 150 raise Exception('''
129 151 Bot creation Failed
@@ -136,15 +158,14 @@ class Model:
136 158
137 159 class Account:
138 160 def create(proxy: None or str = None, logging: bool = False, enable_bot_creation: bool = False):
139
140 161 client = Session()
141 162 client.proxies = {
142 163 'http': f'http://{proxy}',
143 164 'https': f'http://{proxy}'} if proxy else None
144
165
145 166 mail = Mail(client.proxies)
146 167 mail_token = None
147 mail_address = mail.get_mail()
168 _, mail_address = mail.get_mail()
148 169
149 170 if logging: print('email', mail_address)
150 171
@@ -167,12 +188,9 @@ class Account:
167 188 "upgrade-insecure-requests": "1",
168 189 }
169 190
170 init = client.get('https://poe.com/login')
171 next_data = loads(search(r'json">(.+?)</script>', init.text).group(1))
191 client.headers["poe-formkey"] = extract_formkey(client.get('https://poe.com/login').text)
192 client.headers["poe-tchannel"] = client.get('https://poe.com/api/settings').json()['tchannelData']['channel']
172 193
173 client.headers["poe-formkey"] = next_data['props']['formkey']
174 client.headers["poe-tchannel"] = client.get('https://poe.com/api/settings').json()['tchannelData']['channel']
175
176 194 payload = dumps(separators = (',', ':'), obj = {
177 195 'queryName': 'MainSignupLoginSection_sendVerificationCodeMutation_Mutation',
178 196 'variables': {
@@ -189,18 +207,18 @@ class Account:
189 207 response = client.post('https://poe.com/api/gql_POST', data=payload)
190 208 if 'Bad Request' in response.text:
191 209 if logging: print('bad request, retrying...' , response.json())
192 Account.create(proxy = proxy, logging = logging)
210 quit()
193 211
194 212 if logging: print('send_code' ,response.json())
195 213
196 214 while True:
197 215 sleep(1)
198 inbox = mail.fetch_inbox()
199
200 for _ in inbox:
201 content = mail.get_message(_["id"])
202 mail_token = findall(r';">(\d{6,7})</div>', content['html'][0])[0]
203
216 messages = mail.fetch_inbox()
217
218 if len(messages["messages"]) > 0:
219 email_content = mail.get_message_content(messages["messages"][0]["_id"])
220 mail_token = findall(r';">(\d{6,7})</div>', email_content)[0]
221
204 222 if mail_token:
205 223 break
206 224
@@ -215,7 +233,7 @@ class Account:
215 233 },
216 234 "query": "mutation SignupOrLoginWithCodeSection_signupWithVerificationCodeMutation_Mutation(\n $verificationCode: String!\n $emailAddress: String\n $phoneNumber: String\n) {\n signupWithVerificationCode(verificationCode: $verificationCode, emailAddress: $emailAddress, phoneNumber: $phoneNumber) {\n status\n errorMessage\n }\n}\n"
217 235 })
218
236
219 237 base_string = payload + client.headers["poe-formkey"] + 'WpuLMiXEKKE98j56k'
220 238 client.headers["poe-tag-id"] = md5(base_string.encode()).hexdigest()
221 239
@@ -223,23 +241,24 @@ class Account:
223 241 if logging: print('verify_code', response.json())
224 242
225 243 token = parse.unquote(client.cookies.get_dict()['p-b'])
226
244
227 245 with open(Path(__file__).resolve().parent / 'cookies.txt', 'a') as f:
228 246 f.write(f'{token}\n')
229 247
230 248 if enable_bot_creation:
231
232 payload = {
249
250 payload = dumps(separators = (',', ':'), obj={
233 251 "queryName": "UserProfileConfigurePreviewModal_markMultiplayerNuxCompleted_Mutation",
234 252 "variables": {},
235 253 "query": "mutation UserProfileConfigurePreviewModal_markMultiplayerNuxCompleted_Mutation {\n markMultiplayerNuxCompleted {\n viewer {\n hasCompletedMultiplayerNux\n id\n }\n }\n}\n"
236 }
254 })
237 255
238 base_string = dumps(payload, separators = (',', ':')) + client.headers["poe-formkey"] + 'WpuLMiXEKKE98j56k'
256 base_string = payload + client.headers["poe-formkey"] + 'WpuLMiXEKKE98j56k'
239 257 client.headers["poe-tag-id"] = md5(base_string.encode()).hexdigest()
240
241 client.post("https://poe.com/api/gql_POST", json = payload)
242
258
259 resp = client.post("https://poe.com/api/gql_POST", data = payload)
260 if logging: print(resp.json())
261
243 262 return token
244 263
245 264 def get():
Modified quora/api.py +38 -14
@@ -7,10 +7,12 @@ import time
7 7 import queue
8 8 import threading
9 9 import traceback
10 import hashlib
10 11 import websocket
11 12 from pathlib import Path
12 13 from urllib.parse import urlparse
13 14
15
14 16 parent_path = Path(__file__).resolve().parent
15 17 queries_path = parent_path / "graphql"
16 18 queries = {}
@@ -75,12 +77,15 @@ class Client:
75 77 "Referrer": "https://poe.com/",
76 78 "Origin": "https://poe.com",
77 79 }
78 self.ws_domain = f"tch{random.randint(1, 1e6)}"
79
80 80 self.session.headers.update(self.headers)
81
82 self.setup_connection()
83 self.connect_ws()
84
85 def setup_connection(self):
86 self.ws_domain = f"tch{random.randint(1, 1e6)}"
81 87 self.next_data = self.get_next_data(overwrite_vars=True)
82 88 self.channel = self.get_channel_data()
83 self.connect_ws()
84 89 self.bots = self.get_bots(download_next_data=False)
85 90 self.bot_names = self.get_bot_names()
86 91
@@ -91,6 +96,22 @@ class Client:
91 96 self.gql_headers = {**self.gql_headers, **self.headers}
92 97 self.subscribe()
93 98
99 def extract_formkey(self, html):
100 script_regex = r'<script>if\(.+\)throw new Error;(.+)</script>'
101 script_text = re.search(script_regex, html).group(1)
102 key_regex = r'var .="([0-9a-f]+)",'
103 key_text = re.search(key_regex, script_text).group(1)
104 cipher_regex = r'.\[(\d+)\]=.\[(\d+)\]'
105 cipher_pairs = re.findall(cipher_regex, script_text)
106
107 formkey_list = [""] * len(cipher_pairs)
108 for pair in cipher_pairs:
109 formkey_index, key_index = map(int, pair)
110 formkey_list[formkey_index] = key_text[key_index]
111 formkey = "".join(formkey_list)
112
113 return formkey
114
94 115 def get_next_data(self, overwrite_vars=False):
95 116 logger.info("Downloading next_data...")
96 117
@@ -100,7 +121,7 @@ class Client:
100 121 next_data = json.loads(json_text)
101 122
102 123 if overwrite_vars:
103 self.formkey = next_data["props"]["formkey"]
124 self.formkey = self.extract_formkey(r.text)
104 125 self.viewer = next_data["props"]["pageProps"]["payload"]["viewer"]
105 126
106 127 return next_data
@@ -145,7 +166,6 @@ class Client:
145 166 r = request_with_retries(self.session.get, self.settings_url)
146 167 data = r.json()
147 168
148 self.formkey = data["formkey"]
149 169 return data["tchannelData"]
150 170
151 171 def get_websocket_url(self, channel=None):
@@ -157,19 +177,20 @@ class Client:
157 177 def send_query(self, query_name, variables):
158 178 for i in range(20):
159 179 json_data = generate_payload(query_name, variables)
160 payload = json.dumps(json_data, separators=(',', ':'))
161
162 base_string = payload + self.gql_headers['poe-formkey'] + 'WpuLMiXEKKE98j56k'
163
164 from hashlib import md5
165 headers = self.gql_headers |{
180 payload = json.dumps(json_data, separators=(",", ":"))
181
182 base_string = payload + \
183 self.gql_headers["poe-formkey"] + "WpuLMiXEKKE98j56k"
184
185 headers = {
166 186 "content-type": "application/json",
167 "poe-tag-id": md5(base_string.encode()).hexdigest()
187 "poe-tag-id": hashlib.md5(base_string.encode()).hexdigest()
168 188 }
169
189 headers = {**self.gql_headers, **headers}
190
170 191 r = request_with_retries(
171 192 self.session.post, self.gql_url, data=payload, headers=headers)
172
193
173 194 data = r.json()
174 195 if data["data"] == None:
175 196 logger.warn(
@@ -280,10 +301,13 @@ class Client:
280 301 self.active_messages["pending"] = None
281 302
282 303 logger.info(f"Sending message to {chatbot}: {message}")
304
283 305 # reconnect websocket
284 306 if not self.ws_connected:
285 307 self.disconnect_ws()
308 self.setup_connection()
286 309 self.connect_ws()
310
287 311 message_data = self.send_query("SendMessageMutation", {
288 312 "bot": chatbot,
289 313 "query": message,
Modified quora/cookies.txt +1 -0
@@ -15,3 +15,4 @@ juCAh6kB0sUpXHvKik2woA==
15 15 nBvuNYRLaE4xE4HuzBPiIQ==
16 16 oyae3iClomSrk6RJywZ4iw==
17 17 1Z27Ul8BTdNOhncT5H6wdg==
18 wfUfJIlwQwUss8l-3kDt3w==
Modified quora/mail.py +30 -53
@@ -1,62 +1,39 @@
1 from requests import Session
2 from string import ascii_letters
3 from random import choices
1 import html
2 import json
3 from tls_client import Session
4 4
5 5 class Mail:
6 def __init__(self, proxies: dict = None) -> None:
7 self.client = Session()
8 self.client.proxies = None #proxies
9 self.client.headers = {
10 "host": "api.mail.tm",
11 "connection": "keep-alive",
12 "sec-ch-ua": "\"Google Chrome\";v=\"111\", \"Not(A:Brand\";v=\"8\", \"Chromium\";v=\"111\"",
13 "accept": "application/json, text/plain, */*",
14 "content-type": "application/json",
15 "sec-ch-ua-mobile": "?0",
16 "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36",
17 "sec-ch-ua-platform": "\"macOS\"",
18 "origin": "https://mail.tm",
19 "sec-fetch-site": "same-site",
20 "sec-fetch-mode": "cors",
21 "sec-fetch-dest": "empty",
22 "referer": "https://mail.tm/",
23 "accept-encoding": "gzip, deflate, br",
24 "accept-language": "en-GB,en-US;q=0.9,en;q=0.8"
25 }
6 def __init__(self, proxies: str = None, timeout: int = 15, bearer_token: str or None = None) -> None:
7 self.session = Session(client_identifier='chrome110')
8 self.base_url = 'https://web2.temp-mail.org'
9 self.proxies = proxies
10 self.timeout = timeout
26 11
12 self.session.headers['authorization'] = f'Bearer {bearer_token}' if bearer_token else None
13
27 14 def get_mail(self) -> str:
28 token = ''.join(choices(ascii_letters, k=10)).lower()
29
30 init = self.client.post("https://api.mail.tm/accounts", json={
31 "address" : f"{token}@bugfoo.com",
32 "password": token
33 })
34
35 if init.status_code == 201:
36 resp = self.client.post("https://api.mail.tm/token", json = {
37 **init.json(),
38 "password": token
39 })
40
41 self.client.headers['authorization'] = 'Bearer ' + resp.json()['token']
42
43 return f"{token}@bugfoo.com"
15 status: html = self.session.get(self.base_url).status_code
44 16
45 else:
46 raise Exception("Failed to create email")
47
48 def fetch_inbox(self):
49 return self.client.get(f"https://api.mail.tm/messages").json()["hydra:member"]
50
51 def get_message(self, message_id: str):
52 return self.client.get(f"https://api.mail.tm/messages/{message_id}").json()
17 try:
18 if status == 200:
19 data = self.session.post(f'{self.base_url}/mailbox').json()
53 20
21 self.session.headers['authorization'] = f'Bearer {data["token"]}'
22 return data["token"], data["mailbox"]
23
24 except Exception as e:
25 print(e)
26 return f'Email creation error. {e} | use proxies', False
27
28 def fetch_inbox(self) -> json:
29 return self.session.get(f'{self.base_url}/messages').json()
30
54 31 def get_message_content(self, message_id: str):
55 return self.get_message(message_id)["text"]
32 return self.session.get(f'{self.base_url}/messages/{message_id}').json()["bodyHtml"]
56 33
34 # if __name__ == '__main__':
57 35
58 # if __name__ == "__main__":
59 # client = Mail()
60 # client.get_mail()
61
62
36 # email_client = TempMail()
37 # token, email = email_client.get_mail()
38 # print(email)
39 # print(token)