Skip to content

Commit 8e9f10a

Browse files
committed
Update to v0.3 to support Twitch OAuth requirement via App Access Token.
1 parent bb365bb commit 8e9f10a

3 files changed

Lines changed: 91 additions & 20 deletions

File tree

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,19 @@ The included config_example.ini should give you a good idea of what the config.i
3131

3232
### Twitch
3333
#### User
34-
This is simply the username/handle of the streamer/broadcaster. It can be written in whatever case you would like it to appear in the below Discord message/description placeholders, as it will be converted to lowercase automatically for internal functionality.
34+
This is simply the username/handle of the streamer/broadcaster.
35+
It can be written in whatever case you would like it to appear in the below Discord message/description placeholders, as it will be converted to lowercase automatically for internal functionality.
3536
#### ImagePriority
36-
This is what image should be attempted to be used first for the message, Game or Preview. If the game logo or stream preview cannot be loaded, it will fall back to the user logo.
37+
This is what image should be attempted to be used first for the message, Game or Preview.
38+
If the game logo or stream preview cannot be loaded, it will fall back to the user logo.
39+
#### ClientId
40+
This is the Client ID you can get from the [Twitch Developers console.](https://dev.twitch.tv/login)
41+
#### ClientSecret
42+
This is the Client Secret you can get from the [Twitch Developers console.](https://dev.twitch.tv/login)
43+
44+
If you do not have the above ID and Secret, go to the [Twitch Developers console](https://dev.twitch.tv/login), log in, and register an application.
45+
You can provide anything for the name and redirect URL, select any category, and upon creation you will get the ID and secret.
46+
![Example Registration](https://i.imgur.com/ZKqJID9.png)
3747

3848
### Discord
3949
#### Url

config_example.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
[Twitch]
22
User = Sasslyn
33
ImagePriority = Game
4+
ClientId = abcdefghijklmnopqrstuvwxyz1234
5+
ClientSecret = abcdefghijklmnopqrstuvwxyz1234
46

57
[Discord]
68
Url = https://discordapp.com/api/webhooks/ABunchOfRandomNumbers/ABunchOfRandomLettersAndNumbers

twitchlivenotifier/__init__.py

Lines changed: 77 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@
66
77
Python script to notify a Discord server when the streamer goes live, with the current game and box art.
88
9-
:copyright: (c) 2017-2018 Dylan Kauling
9+
:copyright: (c) 2017-2020 Dylan Kauling
1010
:license: GPLv3, see LICENSE for more details.
1111
1212
"""
1313

1414
__title__ = 'twitchlivenotifier'
1515
__author__ = 'Dylan Kauling'
1616
__license__ = 'GPLv3'
17-
__copyright__ = 'Copyright 2017-2019 Dylan Kauling'
18-
__version__ = '0.2'
17+
__copyright__ = 'Copyright 2017-2020 Dylan Kauling'
18+
__version__ = '0.3'
1919

2020
import time
2121
import sys
@@ -24,12 +24,16 @@
2424
import requests
2525
import zc.lockfile
2626

27-
twitch_client_id = 'r5og8xrcb7c4r0b53tyijq2gvxgryp'
28-
twitch_user = None
29-
stream_api_url = None
30-
stream_url = None
31-
discord_url = None
32-
discord_message = None
27+
twitch_client_id = ''
28+
twitch_secret_key = ''
29+
twitch_app_token_json = {}
30+
twitch_user = ''
31+
image_priority = ''
32+
stream_api_url = ''
33+
stream_url = ''
34+
discord_url = ''
35+
discord_message = ''
36+
discord_description = ''
3337
lock = None
3438

3539

@@ -62,6 +66,25 @@ def config():
6266
print('If the game logo or stream preview cannot be loaded, it will fall back to the user logo.')
6367
sys.exit()
6468

69+
global twitch_client_id
70+
try:
71+
twitch_client_id = twitch_config['ClientId']
72+
except KeyError:
73+
print('ClientId not found in Twitch section of config file. Please set ClientId under [Twitch] in config.ini')
74+
print('This is the Client ID you receive when registering an application as a Twitch developer.')
75+
print('Please check the README for more instructions.')
76+
sys.exit()
77+
78+
global twitch_secret_key
79+
try:
80+
twitch_secret_key = twitch_config['ClientSecret']
81+
except KeyError:
82+
print('ClientSecret not found in Twitch section of config file. Please set ClientSecret under [Twitch] in '
83+
'config.ini')
84+
print('This is the Client Secret you receive when registering an application as a Twitch developer.')
85+
print('Please check the README for more instructions.')
86+
sys.exit()
87+
6588
global stream_api_url
6689
stream_api_url = "https://api.twitch.tv/helix/streams"
6790

@@ -112,13 +135,34 @@ def get_lock():
112135
sys.exit()
113136

114137

138+
def authorize():
139+
token_params = {
140+
'client_id': twitch_client_id,
141+
'client_secret': twitch_secret_key,
142+
'grant_type': 'client_credentials',
143+
}
144+
app_token_request = requests.post('https://id.twitch.tv/oauth2/token', params=token_params)
145+
global twitch_app_token_json
146+
twitch_app_token_json = app_token_request.json()
147+
148+
115149
def main():
116150
twitch_json = {'data': []}
117151
while len(twitch_json['data']) == 0:
118-
twitch_headers = {'Client-ID': twitch_client_id}
152+
twitch_headers = {
153+
'Client-ID': twitch_client_id,
154+
'Authorization': 'Bearer ' + twitch_app_token_json['access_token'],
155+
}
119156
twitch_params = {'user_login': twitch_user.lower()}
120-
twitch_request = requests.get(stream_api_url, headers=twitch_headers, params=twitch_params)
121-
twitch_json = twitch_request.json()
157+
request_status = 401
158+
while request_status == 401:
159+
twitch_request = requests.get(stream_api_url, headers=twitch_headers, params=twitch_params)
160+
request_status = twitch_request.status_code
161+
if request_status == 401:
162+
authorize()
163+
twitch_headers['Authorization'] = 'Bearer ' + twitch_app_token_json['access_token']
164+
continue
165+
twitch_json = twitch_request.json()
122166

123167
if len(twitch_json['data']) == 1:
124168
print("Stream is live.")
@@ -136,10 +180,17 @@ def main():
136180
stream_preview = None
137181

138182
game_search_url = "https://api.twitch.tv/helix/games"
139-
game_headers = {'Client-ID': twitch_client_id, 'Accept': 'application/vnd.twitchtv.v5+json'}
140183
game_params = {'id': stream_game_id}
141-
game_request = requests.get(game_search_url, headers=game_headers, params=game_params)
142-
search_response = game_request.json()
184+
search_response = {}
185+
request_status = 401
186+
while request_status == 401:
187+
game_request = requests.get(game_search_url, headers=twitch_headers, params=game_params)
188+
request_status = game_request.status_code
189+
if request_status == 401:
190+
authorize()
191+
twitch_headers['Authorization'] = 'Bearer ' + twitch_app_token_json['access_token']
192+
continue
193+
search_response = game_request.json()
143194

144195
stream_game = "something"
145196
game_logo = None
@@ -155,10 +206,17 @@ def main():
155206
game_logo = game_logo_temp.replace('./', '')
156207

157208
user_search_url = "https://api.twitch.tv/helix/users"
158-
user_headers = {'Client-ID': twitch_client_id, 'Accept': 'application/vnd.twitchtv.v5+json'}
159209
user_params = {'login': twitch_user.lower()}
160-
user_request = requests.get(user_search_url, headers=user_headers, params=user_params)
161-
user_response = user_request.json()
210+
user_response = {}
211+
request_status = 401
212+
while request_status == 401:
213+
user_request = requests.get(user_search_url, headers=twitch_headers, params=user_params)
214+
request_status = user_request.status_code
215+
if request_status == 401:
216+
authorize()
217+
twitch_headers['Authorization'] = 'Bearer ' + twitch_app_token_json['access_token']
218+
continue
219+
user_response = user_request.json()
162220

163221
user_logo = None
164222
print(str(user_response))
@@ -227,4 +285,5 @@ def main():
227285
if __name__ == "__main__":
228286
config()
229287
get_lock()
288+
authorize()
230289
main()

0 commit comments

Comments
 (0)