Refactor Instagram username resolution to enhance response handling and improve error logging
Browse files
app.py
CHANGED
@@ -62,6 +62,13 @@ def resolve_instagram_username(username: str, logger: Callable[[str, str], None]
|
|
62 |
pattern = r'^(?!.*\.\.)(?!.*\._)(?!.*_\.)(?![\.])[a-zA-Z0-9](?!.*\.$)[a-zA-Z0-9._]{0,28}[a-zA-Z0-9]$'
|
63 |
return re.match(pattern, username) is not None
|
64 |
def resolve() -> bool:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
restricted_usernames = [
|
66 |
# "username", "we", "instagram"
|
67 |
]
|
@@ -69,13 +76,14 @@ def resolve_instagram_username(username: str, logger: Callable[[str, str], None]
|
|
69 |
raise Exception(f'"{username}" is not allowed')
|
70 |
if not is_valid_instagram_username(username):
|
71 |
raise Exception(f'"{username}" is not a valid instagram username')
|
72 |
-
|
|
|
73 |
_username = get_json_value(response.text, "username", "\w+") or ""
|
|
|
|
|
|
|
74 |
if _username.lower().strip() == username.lower().strip():
|
75 |
-
return (
|
76 |
-
username,
|
77 |
-
True,
|
78 |
-
f"https://www.instagram.com/{username}/")
|
79 |
x_ig_app_id = get_json_value(response.text, "X-IG-App-ID", "\d+")
|
80 |
user_data_response = requests.get(
|
81 |
url=f"https://www.instagram.com/api/v1/users/web_profile_info/?username={username}",
|
@@ -84,10 +92,14 @@ def resolve_instagram_username(username: str, logger: Callable[[str, str], None]
|
|
84 |
},
|
85 |
allow_redirects = False)
|
86 |
logger("user_data_response:status", user_data_response.status_code)
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
|
|
|
|
91 |
return resolve
|
92 |
|
93 |
def resolve_linkedin_username(username: str, company_or_user: Literal["company", "in"]) -> tuple[str, bool, str]:
|
@@ -136,6 +148,4 @@ async def async_availability_status(
|
|
136 |
'url': uri
|
137 |
}
|
138 |
except Exception as e:
|
139 |
-
return {
|
140 |
-
'message': f"❌ {str(e)}"
|
141 |
-
}
|
|
|
62 |
pattern = r'^(?!.*\.\.)(?!.*\._)(?!.*_\.)(?![\.])[a-zA-Z0-9](?!.*\.$)[a-zA-Z0-9._]{0,28}[a-zA-Z0-9]$'
|
63 |
return re.match(pattern, username) is not None
|
64 |
def resolve() -> bool:
|
65 |
+
# await fetch("https://www.instagram.com/ajax/bulk-route-definitions/", {
|
66 |
+
# "headers": {
|
67 |
+
# "content-type": "application/x-www-form-urlencoded",
|
68 |
+
# },
|
69 |
+
# "body": 'route_urls[0]=/us/&lsd=AVr8bTpwtk4', // "lsd" or 'token'
|
70 |
+
# "method": "POST",
|
71 |
+
# }).then(resp => resp.text()).then(text => JSON.parse(text.replace('for (;;);', ''))?.payload?.payloads)
|
72 |
restricted_usernames = [
|
73 |
# "username", "we", "instagram"
|
74 |
]
|
|
|
76 |
raise Exception(f'"{username}" is not allowed')
|
77 |
if not is_valid_instagram_username(username):
|
78 |
raise Exception(f'"{username}" is not a valid instagram username')
|
79 |
+
profile_uri = f"https://www.instagram.com/{username}/"
|
80 |
+
response = requests.get(profile_uri, allow_redirects = False)
|
81 |
_username = get_json_value(response.text, "username", "\w+") or ""
|
82 |
+
logger("user_data_response:_username", _username)
|
83 |
+
_return_result = lambda is_available: (username, is_available, profile_uri)
|
84 |
+
# if there is a username in the page, then this is likely an existing account
|
85 |
if _username.lower().strip() == username.lower().strip():
|
86 |
+
return _return_result(True)
|
|
|
|
|
|
|
87 |
x_ig_app_id = get_json_value(response.text, "X-IG-App-ID", "\d+")
|
88 |
user_data_response = requests.get(
|
89 |
url=f"https://www.instagram.com/api/v1/users/web_profile_info/?username={username}",
|
|
|
92 |
},
|
93 |
allow_redirects = False)
|
94 |
logger("user_data_response:status", user_data_response.status_code)
|
95 |
+
# if status is 404, then the account doesnt exist!
|
96 |
+
is_html = re.match(r'.*(\w+)/html', user_data_response.headers.get("Content-Type"))
|
97 |
+
if user_data_response.status_code == 404 and is_html:
|
98 |
+
return _return_result(False)
|
99 |
+
# if status is 200, check status of the json
|
100 |
+
is_json = re.match(r'.*(\w+)/json', user_data_response.headers.get("Content-Type"))
|
101 |
+
json_status = (user_data_response.json() or {}).get('status') == 'ok' if is_json else False
|
102 |
+
return _return_result(user_data_response.status_code == 200 and json_status)
|
103 |
return resolve
|
104 |
|
105 |
def resolve_linkedin_username(username: str, company_or_user: Literal["company", "in"]) -> tuple[str, bool, str]:
|
|
|
148 |
'url': uri
|
149 |
}
|
150 |
except Exception as e:
|
151 |
+
return { 'message': f"❌ {str(e)}" }
|
|
|
|