import requests import json import time def fetch_donna_external_ids(page_number, device_id): DONNA_AUTH_HEADER = "Basic bW9iYWltdXNpY3VzZXI6TW9iYWltdXNpYzE0MjYhaGlnaGZpdmU=" url = "https://donna.appsthatworth.com/explore/new" params = {"limit": "20", "page": str(page_number), "review": "false"} headers = { "Host": "donna.appsthatworth.com", "invitefriendab": "1", "version": "1.0.39", "current": str(int(time.time() * 1000000)), # Current epoch microseconds "Authorization": DONNA_AUTH_HEADER, "Accept": "*/*", "premium": "false", "creditgroup": "first", "Accept-Language": "en-US;q=1.0", "showsingle": "true", "Cache-Control": "no-cache", "deviceId": device_id, "User-Agent": "donna/1.0.39 (com.ai.sound.donna; build:11; iOS 18.0.0) Alamofire/5.9.1", "lang": "en", "Connection": "keep-alive", # note: there is a secret header that Donna adds that we don't like # secret: 2C+yvXYybR1AJpAA3KcfCne9dNjDLpN+ko0z6OI/KVrQW7x07ZPMMXeYP7hjhJrq3xV52yqxyDPM1VCNGLxkU57XAPf8L2v5zjxzHJovGes=:JXX1QtmLu8A8bcjzIJpxeQ== # # according to Claude this is an encrypted value split into two parts, likely AES with the first part # being the secret and the second being the iv. # we don't need this header to make these requests successfully, just noting it here } response = requests.get( url, params=params, headers=headers, verify=False, ) if response.status_code == 200: data = response.json() external_ids = [item["externalId"] for item in data["data"]] return external_ids else: print(f"Error: {response.status_code}") return [] def get_recent_donna_clip_ids() -> list[str]: DEVICE_ID = "02167ECA-E096-4B3A-8A9A-16EA8AC8E8B2" clip_ids = [] pages = random.randint(6, 12) for page_number in range(1, pages): external_ids = fetch_donna_external_ids(page_number, DEVICE_ID) if external_ids: clip_ids.extend(external_ids) sleep_duration = random.uniform(3, 8) time.sleep(sleep_duration) print(f"Fetched {len(clip_ids)} recent clips over {pages - 1} pages") return clip_ids