Skip to content

Commit 46b1d12

Browse files
committed
Twitch API using 0Auth token
For FoamyGuy, thank you for the help.
1 parent c662605 commit 46b1d12

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

examples/requests_api_twitch.py

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# SPDX-FileCopyrightText: 2022 DJDevon3 for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
# Coded for Circuit Python 8.0
4+
"""DJDevon3 Adafruit Feather ESP32-S2 Twitch_API_Example"""
5+
import gc
6+
import time
7+
import ssl
8+
import json
9+
import wifi
10+
import socketpool
11+
import adafruit_requests
12+
13+
# Twitch Developer Account & 0Auth App Required:
14+
# Ensure Twitch_ClientID & Twitch_Client_Secret are in secrets.py or .env
15+
16+
# "Twitch_ClientID": "Your Developer APP ID Here",
17+
# "Twitch_Client_Secret": "APP ID secret here",
18+
19+
# For finding your Twitch User ID
20+
# https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/
21+
Twitch_UserID = "0000000" # Set User ID you want endpoints from
22+
23+
# Initialize WiFi Pool (There can be only 1 pool & top of script)
24+
pool = socketpool.SocketPool(wifi.radio)
25+
26+
# Time between API refreshes
27+
# 900 = 15 mins, 1800 = 30 mins, 3600 = 1 hour
28+
sleep_time = 900
29+
30+
try:
31+
from secrets import secrets
32+
except ImportError:
33+
print("Secrets File Import Error")
34+
raise
35+
36+
# Converts seconds in minutes/hours/days
37+
def time_calc(time):
38+
if time < 60:
39+
sleep_int = time
40+
time_output = f"{sleep_int:.0f} seconds"
41+
return time_output
42+
elif 60 <= time < 3600:
43+
sleep_int = time / 60
44+
time_output = f"{sleep_int:.0f} minutes"
45+
return time_output
46+
elif 3600 <= time < 86400:
47+
sleep_int = time / 60 / 60
48+
time_output = f"{sleep_int:.0f} hours"
49+
return time_output
50+
elif 86400 <= time < 432000:
51+
sleep_int = time / 60 / 60 / 24
52+
time_output = f"{sleep_int:.1f} days"
53+
return time_output
54+
else: # if > 5 days convert float to int & display whole days
55+
sleep_int = time / 60 / 60 / 24
56+
time_output = f"{sleep_int:.0f} days"
57+
return time_output
58+
59+
60+
# First we use Client ID & Client Secret to create a token with POST
61+
# No user interaction is required for this type of scope (implicit grant flow)
62+
twitch_0auth_header = {'Content-Type': 'application/x-www-form-urlencoded'}
63+
TWITCH_0AUTH_TOKEN = (
64+
"https://id.twitch.tv/oauth2/token"
65+
)
66+
67+
# Connect to Wi-Fi
68+
print("\n===============================")
69+
print("Connecting to WiFi...")
70+
requests = adafruit_requests.Session(pool, ssl.create_default_context())
71+
while not wifi.radio.ipv4_address:
72+
try:
73+
wifi.radio.connect(secrets["ssid"], secrets["password"])
74+
except ConnectionError as e:
75+
print("Connection Error:", e)
76+
print("Retrying in 10 seconds")
77+
time.sleep(10)
78+
gc.collect()
79+
print("Connected!\n")
80+
81+
while True:
82+
try:
83+
# ----------------------------- POST FOR BEARER TOKEN -----------------------------------------------
84+
print("\nAttempting to GENERATE Twitch Bearer Token!") # ---------------------------------------
85+
# Print Request to Serial
86+
debug_bearer_request = False # STREAMER WARNING: your client secret will be viewable
87+
if debug_bearer_request:
88+
print("Full API GET URL: ", TWITCH_0AUTH_TOKEN)
89+
print("===============================")
90+
twitch_0auth_data = ("&client_id="
91+
+ secrets["Twitch_ClientID"]
92+
+ "&client_secret="
93+
+ secrets["Twitch_Client_Secret"]
94+
+ "&grant_type=client_credentials"
95+
)
96+
97+
# POST REQUEST
98+
twitch_0auth_response = requests.post(url=TWITCH_0AUTH_TOKEN, data=twitch_0auth_data, headers=twitch_0auth_header)
99+
try:
100+
twitch_0auth_json = twitch_0auth_response.json()
101+
twitch_access_token = twitch_0auth_json['access_token']
102+
except ConnectionError as e:
103+
print("Connection Error:", e)
104+
print("Retrying in 10 seconds")
105+
106+
# Print Response to Serial
107+
debug_bearer_response = False # STREAMER WARNING: your client secret will be viewable
108+
if debug_bearer_response:
109+
print("JSON Dump: ", twitch_0auth_json)
110+
print("Header: ", twitch_0auth_header)
111+
print("Access Token: ", twitch_access_token)
112+
113+
twitch_token_expiration = twitch_0auth_json['expires_in']
114+
print("Token Expires in: ", time_calc(twitch_token_expiration))
115+
twitch_token_type = twitch_0auth_json['token_type']
116+
print("Token Type: ", twitch_token_type)
117+
print("Monotonic: ", time.monotonic())
118+
119+
# ----------------------------- GET DATA -----------------------------------------------
120+
# Bearer token is refreshed every time script runs :)
121+
# Twitch sets token expiration to about 64 days
122+
# Helix is the name of the current Twitch API
123+
# Now that we have POST bearer token we can do a GET for data
124+
# --------------------------------------------------------------------------------------
125+
twitch_header = {
126+
'Authorization': 'Bearer '+twitch_access_token+'',
127+
'Client-Id': ''+ secrets["Twitch_ClientID"] +''
128+
}
129+
TWITCH_FOLLOWERS_SOURCE = (
130+
"https://api.twitch.tv/helix/users"
131+
+ "/follows?"
132+
+ "to_id="
133+
+ Twitch_UserID
134+
+ "&first=1"
135+
)
136+
print("\nAttempting to GET TWITCH Stats!") # ------------------------------------------------
137+
print("===============================")
138+
twitch_followers_response = requests.get(url=TWITCH_FOLLOWERS_SOURCE, headers=twitch_header)
139+
try:
140+
twitch_followers_json = twitch_followers_response.json()
141+
except ConnectionError as e:
142+
print("Connection Error:", e)
143+
print("Retrying in 10 seconds")
144+
145+
# Print Response to Serial
146+
debug_bearer_response = False # STREAMER WARNING: your bearer token will be viewable
147+
if debug_bearer_response:
148+
print("Full API GET URL: ", TWITCH_FOLLOWERS_SOURCE)
149+
print("Header: ", twitch_header)
150+
print("JSON Full Response: ", twitch_followers_json)
151+
152+
twitch_username = twitch_followers_json['data'][0]['to_name']
153+
print("Username: ", twitch_username)
154+
twitch_followers = twitch_followers_json['total']
155+
print("Followers: ", twitch_followers)
156+
print("Monotonic: ", time.monotonic()) # Board Up-Time seconds
157+
158+
print("\nFinished!")
159+
print("Next Update in: ", time_calc(sleep_time))
160+
print("===============================")
161+
gc.collect()
162+
163+
except (ValueError, RuntimeError) as e:
164+
print("Failed to get data, retrying\n", e)
165+
time.sleep(60)
166+
continue
167+
time.sleep(sleep_time)

0 commit comments

Comments
 (0)