Skip to content

Commit

Permalink
new UA, login fix (only console)
Browse files Browse the repository at this point in the history
  • Loading branch information
rdavydov committed Nov 16, 2022
1 parent 07cfbdf commit 822e784
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 28 deletions.
2 changes: 1 addition & 1 deletion TwitchChannelPointsMiner/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
__version__ = "1.4.1"
__version__ = "1.5.0"
from .TwitchChannelPointsMiner import TwitchChannelPointsMiner

__all__ = [
Expand Down
15 changes: 10 additions & 5 deletions TwitchChannelPointsMiner/classes/Twitch.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ def __init__(self, username, user_agent, password=None):
Path(cookies_path).mkdir(parents=True, exist_ok=True)
self.cookies_file = os.path.join(cookies_path, f"{username}.pkl")
self.user_agent = user_agent
self.twitch_login = TwitchLogin(
CLIENT_ID, username, self.user_agent, password=password
)
self.running = True
self.device_id = "".join(
choice(string.ascii_letters + string.digits) for _ in range(32)
)
self.twitch_login = TwitchLogin(
CLIENT_ID, self.device_id, username, self.user_agent, password=password
)
self.running = True
self.integrity = None
self.integrity_expire = 0
self.client_session = token_hex(16)
Expand Down Expand Up @@ -126,9 +126,14 @@ def update_stream(self, streamer):

def get_spade_url(self, streamer):
try:
headers = {"User-Agent": self.user_agent}
# fixes AttributeError: 'NoneType' object has no attribute 'group'
#headers = {"User-Agent": self.user_agent}
from TwitchChannelPointsMiner.constants import USER_AGENTS
headers = {"User-Agent": USER_AGENTS["Linux"]["FIREFOX"]}

main_page_request = requests.get(streamer.streamer_url, headers=headers)
response = main_page_request.text
#logger.info(response)
regex_settings = "(https://static.twitchcdn.net/config/settings.*?js)"
settings_url = re.search(regex_settings, response).group(1)

Expand Down
45 changes: 33 additions & 12 deletions TwitchChannelPointsMiner/classes/TwitchLogin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

logger = logging.getLogger(__name__)

def interceptor(request) -> str:
"""def interceptor(request) -> str:
if (
request.method == 'POST'
and request.url == 'https://passport.twitch.tv/protected_login'
Expand All @@ -29,11 +29,12 @@ def interceptor(request) -> str:
data['client_id'] = CLIENT_ID
request.body = json.dumps(data).encode('utf-8')
del request.headers['Content-Length']
request.headers['Content-Length'] = str(len(request.body))
request.headers['Content-Length'] = str(len(request.body))"""

class TwitchLogin(object):
__slots__ = [
"client_id",
"device_id",
"token",
"login_check_result",
"session",
Expand All @@ -45,13 +46,14 @@ class TwitchLogin(object):
"cookies"
]

def __init__(self, client_id, username, user_agent, password=None):
def __init__(self, client_id, device_id, username, user_agent, password=None):
self.client_id = client_id
self.device_id = device_id
self.token = None
self.login_check_result = False
self.session = requests.session()
self.session.headers.update(
{"Client-ID": self.client_id, "User-Agent": user_agent}
{ "Client-ID": self.client_id, "X-Device-Id": self.device_id, "User-Agent": user_agent }
)
self.username = username
self.password = password
Expand All @@ -69,8 +71,8 @@ def login_flow(self):
"remember_me": True,
}
# login-fix
#use_backup_flow = False
use_backup_flow = True
use_backup_flow = False
#use_backup_flow = True

for attempt in range(0, 25):
password = (
Expand Down Expand Up @@ -131,8 +133,8 @@ def login_flow(self):
# If the user didn't load the password from run.py we can just ask for it again.
break
# login-fix
#elif err_code == 1000:
elif err_code in [1000, 5022]:
elif err_code == 1000:
#elif err_code in [1000, 5022]:
logger.info(
"Console login unavailable (CAPTCHA solving required)."
)
Expand Down Expand Up @@ -162,11 +164,18 @@ def set_token(self, new_token):
self.session.headers.update({"Authorization": f"Bearer {self.token}"})

def send_login_request(self, json_data):
response = self.session.post("https://passport.twitch.tv/protected_login", json=json_data)
#response = self.session.post("https://passport.twitch.tv/protected_login", json=json_data)
response = self.session.post("https://passport.twitch.tv/login", json=json_data, headers={
'Accept': 'application/vnd.twitchtv.v3+json',
'Accept-Encoding': 'gzip',
'Accept-Language': 'en-US',
'Content-Type': 'application/json; charset=UTF-8',
'Host': 'passport.twitch.tv'
},)
return response.json()

def login_flow_backup(self, password = None):
"""Backup OAuth Selenium login"""
"""Backup OAuth Selenium login
from undetected_chromedriver import ChromeOptions
import seleniumwire.undetected_chromedriver.v2 as uc
from selenium.webdriver.common.by import By
Expand Down Expand Up @@ -218,7 +227,9 @@ def login_flow_backup(self, password = None):
logger.error("Couldn't extract login, probably bad cookies.")
return False
return self.get_cookie_value("auth-token")
return self.get_cookie_value("auth-token")"""
logger.error("Backup login flow is not available. Use a VPN or wait a while to avoid the CAPTCHA.")
return False

def check_login(self):
if self.login_check_result:
Expand All @@ -230,7 +241,17 @@ def check_login(self):
return self.login_check_result

def save_cookies(self, cookies_file):
pickle.dump(self.cookies, open(cookies_file, "wb"))
#pickle.dump(self.cookies, open(cookies_file, "wb"))
# ^ only this line was needed with Selenium ^
cookies_dict = self.session.cookies.get_dict()
cookies_dict["auth-token"] = self.token
if "persistent" not in cookies_dict: # saving user id cookies
cookies_dict["persistent"] = self.user_id

self.cookies = []
for cookie_name, value in cookies_dict.items():
self.cookies.append({"name": cookie_name, "value": value})
pickle.dump(self.cookies, open(cookies_file, "wb"))

def get_cookie_value(self, key):
for cookie in self.cookies:
Expand Down
3 changes: 3 additions & 0 deletions TwitchChannelPointsMiner/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
"CHROME": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36",
"FIREFOX": "Mozilla/5.0 (X11; Linux x86_64; rv:85.0) Gecko/20100101 Firefox/85.0",
},
"Android": {
"App": "Dalvik/2.1.0 (Linux; U; Android 7.1.2; SM-G975N Build/N2G48C) tv.twitch.android.app/13.4.1/1304010"
}
}

BRANCH = "master"
Expand Down
7 changes: 4 additions & 3 deletions TwitchChannelPointsMiner/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ def create_nonce(length=30) -> str:
nonce += char
return nonce


# for mobile-token
def get_user_agent(browser: str) -> str:
try:
"""try:
return USER_AGENTS[platform.system()][browser]
except KeyError:
return USER_AGENTS["Linux"]["FIREFOX"]
return USER_AGENTS["Linux"]["FIREFOX"]"""
return USER_AGENTS["Android"]["App"]


def remove_emoji(string: str) -> str:
Expand Down
3 changes: 0 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,3 @@ colorama
flask
irc
pandas
selenium
selenium-wire
undetected_chromedriver
5 changes: 1 addition & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ def read(fname):
"colorama",
"flask",
"irc",
"pandas",
"selenium",
"selenium-wire",
"undetected_chromedriver"
"pandas"
],
long_description=read("README.md"),
long_description_content_type="text/markdown",
Expand Down

0 comments on commit 822e784

Please sign in to comment.