返回提交历史
Modified
quora/__init__.py
+50
-31
Modified
quora/api.py
+38
-14
Modified
quora/cookies.txt
+1
-0
Modified
quora/mail.py
+30
-53
XFEstudio/gpt4free
quora (poe) [gpt-4/3.5] api unpatch
c38e367e
代码差异
4 个文件
+119
-98
@@ -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():
@@ -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,
@@ -15,3 +15,4 @@ juCAh6kB0sUpXHvKik2woA==
15
15
nBvuNYRLaE4xE4HuzBPiIQ==
16
16
oyae3iClomSrk6RJywZ4iw==
17
17
1Z27Ul8BTdNOhncT5H6wdg==
18
wfUfJIlwQwUss8l-3kDt3w==
@@ -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)