Skip to content

Commit

Permalink
Fix problems caused by OAuth requirements.
Browse files Browse the repository at this point in the history
OAuth is now required for Helix Twitch API Endpoints:

    https://discuss.dev.twitch.tv/t/requiring-oauth-for-helix-twitch-api-endpoints/23916

This broke my code and took a lot of effort to fix. Also,
I had to open this support request which was not as helpful
as I would have liked:

    https://discuss.dev.twitch.tv/t/programattically-get-user-oauth-token-for-subscriber-notifications/26172

I am saving this working code, but will remove some unnecessary
changes in the next commit.
  • Loading branch information
MountainRiderAK committed Jun 9, 2020
1 parent 19c6f55 commit 0c68d2a
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 4 deletions.
25 changes: 24 additions & 1 deletion twitch_channel_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import requests

from configuration import add_configuration
import microsecond_logging


def new_followers(previous_followers, current_followers):
Expand All @@ -32,22 +33,44 @@ def new_followers(previous_followers, current_followers):

class TwitchChannelInterface(object):
def __init__(self, channel, client_id):
self.logger = microsecond_logging.getLogger(__name__)
self.logger.setLevel(microsecond_logging.DEBUG)
self.channel = channel
self.client_id = client_id
add_configuration(self)
self.data = None
self.channel_id = None
self.follows = None
self.new_follows = None
self.access_token = None

def get_access_token(self):
api_url = "https://id.twitch.tv/oauth2/token"
self.logger.debug(f"api_url = {api_url}")
payload = {
"client_id": self.client_id,
"client_secret": "0mhdlly4cxfnhxcbrn4q8ojyangzze",

This comment has been minimized.

Copy link
@BarryCarlyon

BarryCarlyon Jun 9, 2020

You have leaked your client secret!

"grant_type": "client_credentials",
}
self.logger.debug(f"payload = {payload}")
result = requests.post(api_url, data=payload)
if result.status_code == requests.codes.ok:
self.data = result.json()
self.access_token = self.data['access_token']
return self.access_token

def get_id(self):
api_url = f"{self.twitch_api_base}/users"
headers = {"Client-ID": self.client_id}
self.logger.debug(f"api_url = {api_url}")
access_token = self.get_access_token()
headers = {"Client-ID": self.client_id, "Authorization": f"Bearer {access_token}"}
self.logger.debug(f"headers = {headers}")
payload = {"login": self.channel}
result = requests.get(api_url, params=payload, headers=headers)
if result.status_code == requests.codes.ok:
self.data = result.json()
self.channel_id = self.data['data'][0]['id']
self.logger.debug(f"self.channel_id = {self.channel_id}")
return self.channel_id

def get_follows(self):
Expand Down
33 changes: 30 additions & 3 deletions twitch_follow_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,19 @@ def add_url_rules(self):
'new_follower',
self.new_follower,
methods=['GET', 'POST'])
self.app.add_url_rule('/auth/twitch/callback',
'oauth_handler',
self.oauth_handler,
methods=['GET', 'POST'])
self.app.register_error_handler(400, self.bad_request)
self.app.register_error_handler(404, self.not_found)
self.app.register_error_handler(500, self.internal_server_error)

def oauth_handler(self):
self.logger.debug(f"Handling a request: {request}")
result = make_response(jsonify({'success': 'OAuth response'}), 202)
return result

def new_follower(self):
self.logger.debug(f"Handling a request: {request}")
result = make_response(jsonify({'error': 'Bad request'}), 400)
Expand Down Expand Up @@ -111,15 +120,33 @@ def stop(self):


class TwitchWebhookInterface(object):
def __init__(self, logger):
def __init__(self, logger, follow_server):
self.logger = logger
self.follow_server = follow_server
add_configuration(self)
self.webhooks_url = f"{self.twitch_api_base}/webhooks/hub"
self.interface = TwitchChannelInterface(self.channel, self.client_id)
self.user_id = self.interface.get_id()
self.data = None
self.access_token = None

def get_access_token(self):
api_url = "https://id.twitch.tv/oauth2/token"
self.logger.debug(f"api_url = {api_url}")
payload = {
"client_id": self.client_id,
"client_secret": "0mhdlly4cxfnhxcbrn4q8ojyangzze",

This comment has been minimized.

Copy link
@BarryCarlyon

BarryCarlyon Jun 9, 2020

You have leaked your client secret!

"grant_type": "client_credentials",
}
self.logger.debug(f"payload = {payload}")
result = requests.post(api_url, data=payload)
if result.status_code == requests.codes.ok:
self.data = result.json()
self.access_token = self.data['access_token']
return self.access_token

def subscribe(self):
headers = {"Client-ID": self.client_id}
headers = {"Client-ID": self.client_id, "Authorization": f"Bearer {self.interface.access_token}"}
data = {
"hub.mode": "subscribe",
"hub.topic": f"{self.twitch_api_base}/users/follows?first=1&to_id={self.user_id}",
Expand All @@ -145,7 +172,7 @@ def start_server_and_subscribe(logger=None, chatbot=None):
logger.debug("Sleeping to allow server to start...")
time.sleep(1.0)
logger.debug("Subscribing to follower notifications...")
twitch_webhook_interface = TwitchWebhookInterface(logger)
twitch_webhook_interface = TwitchWebhookInterface(logger, twitch_follow_server)
twitch_webhook_interface.subscribe()
return twitch_follow_server

Expand Down

0 comments on commit 0c68d2a

Please sign in to comment.