AtlatestRepositorysigil-youtube

sigil-youtube / tree / src / youtubeoauth.sgl

1;;; (youtube oauth) - OAuth 2.0 integration for sigil-youtube.
2;;;
3;;; Provides convenience functions for creating YouTube clients
4;;; with OAuth token management via sigil-oauth. Uses the Google
5;;; provider preset with standard YouTube scopes.
6;;;
7;;; This module adds OAuth support alongside the existing manual
8;;; token-passing API — callers can still construct a youtube-client
9;;; directly with an access-token string.
11(define-library (youtube oauth)
12 (import (sigil core)
13 (sigil dict)
14 (sigil struct)
15 (sigil oauth)
16 (sigil oauth store)
17 (youtube))
19 (export ;; Config helpers
20 youtube-oauth-config
22 ;; Client construction from tokens
23 youtube-oauth-client
25 ;; Auto-refresh: config + tokens + time → client + tokens
26 youtube-ensure-client
28 ;; Token storage helpers
29 youtube-save-tokens
30 youtube-load-tokens
31 youtube-clear-tokens
33 ;; Re-exported from (sigil oauth) for convenience
34 oauth-config
35 oauth-config?
36 oauth-config-client-id
37 oauth-config-client-secret
38 oauth-config-auth-url
39 oauth-config-token-url
40 oauth-config-scopes
41 oauth-config-redirect-uri
42 oauth-config-extra-params
43 oauth-tokens
44 oauth-tokens?
45 oauth-tokens-access-token
46 oauth-tokens-refresh-token
47 oauth-tokens-expires-at
48 oauth-tokens-token-type
49 oauth-tokens-scopes
50 oauth-ensure-valid-token
51 oauth-token-expired?
52 oauth-authorization-url
53 oauth-generate-state
54 oauth-generate-pkce
55 oauth-exchange-code
56 oauth-refresh-token)
58 (begin
60 ;; Default YouTube/Google scopes for System Crafters use.
61 ;; Covers video management, uploads, analytics, and live streaming.
62 (define youtube-default-scopes
63 (list "https://www.googleapis.com/auth/youtube"
64 "https://www.googleapis.com/auth/yt-analytics.readonly"
65 "https://www.googleapis.com/auth/yt-analytics-monetary.readonly"))
67 (define youtube-service-name "youtube")
69 ;; ---------------------------------------------------------------
70 ;; Config
71 ;; ---------------------------------------------------------------
73 ;;; Create an oauth-config for YouTube/Google OAuth2.
74 ;;;
75 ;;; client-id: Google Cloud OAuth2 client ID
76 ;;; client-secret: Google Cloud OAuth2 client secret
77 ;;;
78 ;;; Optional keyword args via opts dict:
79 ;;; scopes: list of scope strings (default: youtube-default-scopes)
80 ;;; redirect-uri: override redirect URI
81 (define (youtube-oauth-config client-id client-secret . rest)
82 (let ((opts (if (null? rest) #{} (car rest))))
83 (let ((scopes (dict-ref opts scopes: youtube-default-scopes)))
84 (oauth-google-config client-id client-secret scopes
85 (if (dict-ref opts redirect-uri: #f)
86 #{ redirect-uri: (dict-ref opts redirect-uri:) }
87 #{})))))
89 ;; ---------------------------------------------------------------
90 ;; Client construction
91 ;; ---------------------------------------------------------------
93 ;;; Build a youtube-client from an oauth-tokens record.
94 ;;;
95 ;;; The access token is extracted from the tokens record.
96 ;;; An optional api-key can be provided for fallback read-only
97 ;;; access when the OAuth token is not available.
98 (define (youtube-oauth-client tokens . rest)
99 (let ((opts (if (null? rest) #{} (car rest))))
100 (youtube-client
101 access-token: (oauth-tokens-access-token tokens)
102 api-key: (dict-ref opts api-key: #f))))
104 ;; ---------------------------------------------------------------
105 ;; Auto-refresh
106 ;; ---------------------------------------------------------------
108 ;;; Ensure tokens are valid (refreshing if needed) and return
109 ;;; both a ready-to-use youtube-client and the (possibly updated)
110 ;;; oauth-tokens record.
111 ;;;
112 ;;; config: oauth-config from youtube-oauth-config
113 ;;; tokens: current oauth-tokens record
114 ;;; current-time: unix timestamp (from current-second)
115 ;;;
116 ;;; Optional keyword args via opts dict:
117 ;;; api-key: YouTube API key for read-only fallback
118 ;;; save?: whether to persist refreshed tokens (default: #t)
119 ;;;
120 ;;; Returns: (values youtube-client oauth-tokens)
121 (define (youtube-ensure-client config tokens current-time . rest)
122 (let* ((opts (if (null? rest) #{} (car rest)))
123 (save? (dict-ref opts save?: #t))
124 (fresh-tokens (oauth-ensure-valid-token config tokens current-time))
125 (client (youtube-oauth-client fresh-tokens opts)))
126 ;; Persist if tokens were refreshed
127 (if (and save?
128 (not (eq? fresh-tokens tokens)))
129 (youtube-save-tokens fresh-tokens))
130 (values client fresh-tokens)))
132 ;; ---------------------------------------------------------------
133 ;; Token storage (thin wrappers)
134 ;; ---------------------------------------------------------------
136 ;;; Save YouTube OAuth tokens to persistent storage.
137 (define (youtube-save-tokens tokens)
138 (oauth-save-tokens youtube-service-name tokens))
140 ;;; Load YouTube OAuth tokens from persistent storage.
141 ;;; Returns oauth-tokens or #f if not found.
142 (define (youtube-load-tokens)
143 (oauth-load-tokens youtube-service-name))
145 ;;; Clear stored YouTube OAuth tokens.
146 (define (youtube-clear-tokens)
147 (oauth-clear-tokens youtube-service-name))
149 ))