| 191 | |
| 192 | |
| 193 | class InviteAPI: |
| 194 | BASE_URL = "https://ai.imusic.cn" |
| 195 | |
| 196 | def __init__(self, token: str, cookies: dict = None): |
| 197 | self.token = token |
| 198 | self.session = requests.Session() |
| 199 | self.session.mount('https://', DESAdapter()) |
| 200 | if cookies: |
| 201 | self.session.cookies.update(cookies) |
| 202 | self.session.headers.update({ |
| 203 | "User-Agent": "CtClient;11.3.0;Android;12;Redmi K30 Pro;ODAwODUw!#!MTg2MDg", |
| 204 | "Accept": "application/json, text/plain, */*", |
| 205 | "Accept-Encoding": "gzip, deflate, br, zstd", |
| 206 | "Origin": self.BASE_URL, |
| 207 | "Authorization": f"Bearer {token}", |
| 208 | "Referer": f"{self.BASE_URL}/h5v/fusion/ai-luck-flow?ca=AP3V&cc={CHANNEL_ID}&utm_scha=utm_ch-010001002009.utm_sch-hg_xx_qlxx-1-104705800001-105782800001.utm_af-1000000037.utm_as-158492900001.utm_sd1-default", |
| 209 | "X-Requested-With": "com.ct.client", |
| 210 | "sec-ch-ua": '"Chromium";v="140", "Not=A?Brand";v="24", "Android WebView";v="140"', |
| 211 | "sec-ch-ua-mobile": "?1", |
| 212 | "sec-ch-ua-platform": '"Android"', |
| 213 | "Sec-Fetch-Site": "same-origin", |
| 214 | "Sec-Fetch-Mode": "cors", |
| 215 | "Sec-Fetch-Dest": "empty", |
| 216 | "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7" |
| 217 | }) |
| 218 | |
| 219 | |
| 220 | |
| 221 | def request_plain(self, endpoint: str, params: dict = None) -> dict: |
| 222 | url = f"{self.BASE_URL}{endpoint}" |
| 223 | response = self.session.post(url, params=params, timeout=30) |
| 224 | return response.json() |
| 225 | |
| 226 | def request_encrypted(self, endpoint: str, params: dict) -> dict: |
| 227 | self.session.headers["imencrypt"] = "1" |
| 228 | imrandomnum = generate_random_string(16) |
| 229 | imtimestamp = str(int(time.time() * 1000)) |
| 230 | imencryptkey = encryptmd5(imtimestamp, imrandomnum) |
| 231 | |
| 232 | form_data = {"channelId": CHANNEL_ID, "portal": "45"} |
| 233 | form_data.update(params) |
| 234 | encrypted_form = encrypt_request(form_data, imrandomnum, imtimestamp, imencryptkey) |
| 235 | |
| 236 | headers = { |
| 237 | "imencryptkey": imencryptkey, |
| 238 | "imrandomnum": imrandomnum, |
| 239 | "imtimestamp": imtimestamp, |
| 240 | } |
| 241 | url = f"{self.BASE_URL}{endpoint}" |
| 242 | response = self.session.post(url, params={"formData": encrypted_form}, headers=headers, timeout=30) |
| 243 | |
| 244 | new_auth = response.headers.get("Authorization") |
| 245 | if new_auth: |
| 246 | self.token = new_auth |
| 247 | self.session.headers["Authorization"] = f"Bearer {new_auth}" |
| 248 | |
| 249 | try: |
| 250 | return decrypt_response(response.text, imrandomnum, imtimestamp, imencryptkey) |
no outgoing calls
no test coverage detected