Skip to content

Commit

Permalink
Switch to MOBILE_WEB Client ID
Browse files Browse the repository at this point in the history
  • Loading branch information
DevilXD committed Aug 15, 2023
1 parent 137f540 commit 70035cd
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 29 deletions.
52 changes: 47 additions & 5 deletions constants.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from __future__ import annotations

import sys
import random
import logging
from pathlib import Path
from copy import deepcopy
from enum import Enum, auto
from datetime import timedelta
from typing import Any, Dict, Literal, NamedTuple, NewType, TYPE_CHECKING
from typing import Any, Dict, Literal, NewType, TYPE_CHECKING

from yarl import URL

Expand Down Expand Up @@ -97,9 +98,17 @@ def _resource_path(relative_path: Path | str) -> Path:
OUTPUT_FORMATTER = logging.Formatter("{levelname}: {message}", style='{', datefmt="%H:%M:%S")


class ClientInfo(NamedTuple):
CLIENT_ID: str
USER_AGENT: str
class ClientInfo:
def __init__(self, client_id: str, user_agents: str | list[str]) -> None:
self.CLIENT_ID: str = client_id
self.USER_AGENT: str
if isinstance(user_agents, list):
self.USER_AGENT = random.choice(user_agents)
else:
self.USER_AGENT = user_agents

def __iter__(self):
return iter((self.CLIENT_ID, self.USER_AGENT))


class ClientType:
Expand All @@ -110,7 +119,40 @@ class ClientType:
"(KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
),
)
ANDROID = ClientInfo(
MOBILE_WEB = ClientInfo(
"r8s4dac0uhzifbpu9sjdiwzctle17ff",
[
(
"Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/115.0.5790.166 Mobile Safari/537.36"
),
(
"Mozilla/5.0 (Linux; Android 13; SM-A205U) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/115.0.5790.166 Mobile Safari/537.36"
),
(
"Mozilla/5.0 (Linux; Android 13; SM-A102U) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/115.0.5790.166 Mobile Safari/537.36"
),
(
"Mozilla/5.0 (Linux; Android 13; SM-G960U) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/115.0.5790.166 Mobile Safari/537.36"
),
(
"Mozilla/5.0 (Linux; Android 13; SM-N960U) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/115.0.5790.166 Mobile Safari/537.36"
),
(
"Mozilla/5.0 (Linux; Android 13; LM-Q720) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/115.0.5790.166 Mobile Safari/537.36"
),
(
"Mozilla/5.0 (Linux; Android 13; LM-X420) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/115.0.5790.166 Mobile Safari/537.36"
),
]
)
ANDROID_APP = ClientInfo(
"kd1unb4b3q4t58fwlpcbzcbnm76a8fp",
(
"Dalvik/2.1.0 (Linux; U; Android 7.1.2; SM-G977N Build/LMY48Z) "
Expand Down
33 changes: 9 additions & 24 deletions twitch.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import re
import sys
import json
import random
import asyncio
import logging
from time import time
Expand Down Expand Up @@ -91,7 +90,7 @@ def decode(self, s: str, *args):
return obj


CLIENT_ID, USER_AGENT = ClientType.SMARTBOX
CLIENT_ID, USER_AGENT = ClientType.MOBILE_WEB
SAFE_LOADS = lambda s: json.loads(s, cls=SkipExtraJsonDecoder)


Expand Down Expand Up @@ -499,8 +498,8 @@ def headers(
headers["User-Agent"] = user_agent
if hasattr(self, "session_id"):
headers["Client-Session-Id"] = self.session_id
if hasattr(self, "client_version"):
headers["Client-Version"] = self.client_version
# if hasattr(self, "client_version"):
# headers["Client-Version"] = self.client_version
if hasattr(self, "device_id"):
headers["X-Device-Id"] = self.device_id
if gql:
Expand All @@ -526,10 +525,11 @@ async def _validate(self):
"GET", BASE_URL, headers=self.headers()
) as response:
page_html = await response.text("utf8")
match = re.search(r'twilightBuildID="([-a-z0-9]+)"', page_html)
if match is None:
raise MinerException("Unable to extract client_version")
self.client_version = match.group(1)
assert page_html is not None
# match = re.search(r'twilightBuildID="([-a-z0-9]+)"', page_html)
# if match is None:
# raise MinerException("Unable to extract client_version")
# self.client_version = match.group(1)
# doing the request ends up setting the "unique_id" value in the cookie
cookie = jar.filter_cookies(BASE_URL)
self.device_id = cookie["unique_id"].value
Expand Down Expand Up @@ -639,21 +639,6 @@ async def get_session(self) -> aiohttp.ClientSession:
if session.closed:
raise RuntimeError("Session is closed")
return session
# try to obtain the latest Chrome user agent from a Github project
try:
async with aiohttp.request(
"GET",
"https://jnrbsn.github.io/user-agents/user-agents.json",
proxy=self.settings.proxy or None,
) as response:
agents = await response.json()
if sys.platform == "win32":
chrome_agent = random.choice(agents[:3])
elif sys.platform == "linux":
chrome_agent = random.choice(agents[7:11])
except Exception:
# looks like we can't rely on 3rd parties too much
chrome_agent = ClientType.WEB.USER_AGENT
# load in cookies
cookie_jar = aiohttp.CookieJar()
try:
Expand All @@ -668,7 +653,7 @@ async def get_session(self) -> aiohttp.ClientSession:
self._session = aiohttp.ClientSession(
connector=connector,
cookie_jar=cookie_jar,
headers={"User-Agent": chrome_agent},
headers={"User-Agent": USER_AGENT},
timeout=aiohttp.ClientTimeout(connect=5, total=10),
)
return self._session
Expand Down

0 comments on commit 70035cd

Please sign in to comment.