Skip to content

Commit 512ba00

Browse files
Jordan KingCopilot
andcommitted
Validate YouTube OAuth scopes
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 4973be7 commit 512ba00

1 file changed

Lines changed: 18 additions & 0 deletions

File tree

‎scripts/snapshot_youtube_analytics.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
TOP_VIDEO_LIMIT = 25
2727

2828
TOKEN_URL = "https://oauth2.googleapis.com/token"
29+
TOKENINFO_URL = "https://oauth2.googleapis.com/tokeninfo"
2930
YT_ANALYTICS_URL = "https://youtubeanalytics.googleapis.com/v2/reports"
3031
YT_VIDEOS_URL = "https://www.googleapis.com/youtube/v3/videos"
3132

@@ -38,6 +39,10 @@
3839
"averageViewPercentage",
3940
]
4041
REVENUE_METRICS = ["estimatedRevenue"]
42+
REQUIRED_SCOPES = {
43+
"https://www.googleapis.com/auth/yt-analytics.readonly",
44+
"https://www.googleapis.com/auth/youtube.readonly",
45+
}
4146

4247

4348
class ConfigError(RuntimeError):
@@ -80,6 +85,18 @@ def refresh_access_token(client_id: str, client_secret: str, refresh_token: str)
8085
return str(token)
8186

8287

88+
def validate_access_token_scopes(access_token: str) -> None:
89+
data = api_json(f"{TOKENINFO_URL}?{parse.urlencode({'access_token': access_token})}")
90+
granted = set(str(data.get("scope", "")).split())
91+
missing = sorted(REQUIRED_SCOPES - granted)
92+
if missing:
93+
raise RuntimeError(
94+
"The YouTube refresh token is missing required OAuth scopes. "
95+
"Re-authorize in OAuth Playground with BOTH scopes and replace YOUTUBE_REFRESH_TOKEN: "
96+
+ ", ".join(missing)
97+
)
98+
99+
83100
def metric_names(include_revenue: bool) -> list[str]:
84101
return BASE_METRICS + (REVENUE_METRICS if include_revenue else [])
85102

@@ -364,6 +381,7 @@ def main() -> int:
364381
metrics = metric_names(args.include_revenue)
365382

366383
token = refresh_access_token(client_id, client_secret, refresh_token)
384+
validate_access_token_scopes(token)
367385
daily_cols, daily_rows = rows_from_report(query_report(
368386
token,
369387
channel_id=args.channel_id,

0 commit comments

Comments
 (0)