YouTube Data API from browser

I was thinking about some kind of small web page to manage YouTube list of videos I wish to watch

Here is an starting point of how this may be done without 3rd party dependencies

// https://console.cloud.google.com/apis/credentials
var api_key = "AIzaSy....."
var client_id = "9844.....apps.googleusercontent.com"
if (window.location.hash && window.location.hash.length && window.location.hash.length > 1) {
    var params = new URLSearchParams(window.location.hash.substring(1))
    var state = params.get("state")
    var access_token = params.get("access_token")
    var token_type = params.get("token_type")
    var expires_in = params.get("expires_in")
    var scope = params.get("scope")
    var authuser = params.get("authuser")
    var prompt = params.get("prompt")
    var session_state = params.get("session_state")
    var error = params.get("error")
    var error_description = params.get("error_description")
    var error_uri = params.get("error_uri")
    var id_token = params.get("id_token")
    var scopes = scope.split(" ")
    // TODO: check state, error, scopes
    // console.log({ state, access_token, token_type, expires_in, scopes, authuser, prompt, session_state, error, error_description, error_uri, id_token })
    sessionStorage.setItem('token', access_token)
}

// http://localhost:3000/#state=003cceac&access_token=ya29&token_type=Bearer&expires_in=3599&scope=email%20profile%20https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/youtube.force-ssl%20https://www.googleapis.com/auth/youtubepartner%20openid%20https://www.googleapis.com/auth/userinfo.profile%20https://www.googleapis.com/auth/youtube%20https://www.googleapis.com/auth/youtube.readonly&authuser=0&prompt=consent
if (!sessionStorage.getItem('token')) {
    sessionStorage.setItem('state', crypto.randomUUID())
    var url = new URL("https://accounts.google.com/o/oauth2/v2/auth")
    url.searchParams.set("client_id", client_id)
    url.searchParams.set("redirect_uri", window.location.origin + "/")
    url.searchParams.set("response_type", "token")
    url.searchParams.set("scope", ["openid", "profile", "https://www.googleapis.com/auth/youtube.readonly"].join(" "))
    url.searchParams.set("access_type", "online")
    url.searchParams.set("state", sessionStorage.getItem('state'))
    url.searchParams.set("include_granted_scopes", "true")
    // url.searchParams.set("login_hint", "email_or_sub") // TODO: save to localStorage use here
    // url.searchParams.set("nonce", crypto.randomUUID())
    console.log('url', url.toString())
    window.location = url
} else {
    // if success - we are logged in, returns email, name, picture, sub
    fetch("https://openidconnect.googleapis.com/v1/userinfo", {headers: {Authorization: "Bearer " + sessionStorage.getItem('token')}}).then(r => r.json()).then(console.log)
}

// https://www.youtube.com/playlist?list=PL2jJW0z9auIfNcigq0-yVYVLiD--febPX
var url = new URL("https://youtube.googleapis.com/youtube/v3/playlistItems")
url.searchParams.set("part", "snippet")
url.searchParams.set("playlistId", "PL2jJW0z9auIfNcigq0-yVYVLiD--febPX")
url.searchParams.set("key", api_key)
fetch(url, {headers: {Authorization: "Bearer " + sessionStorage.getItem('token')}}).then(r => r.json()).then(r => r.items.map(item => ({id: item.id, video: item.snippet.resourceId.videoId, position: item.snippet.position}))).then(console.log)

// https://developers.google.com/youtube/v3/docs/playlistItems/insert

url = new URL("https://youtube.googleapis.com/youtube/v3/playlistItems")
url.searchParams.set("part", "snippet")
url.searchParams.set("key", api_key)
fetch(url, {
    method: "POST",
    headers: {
        Authorization: "Bearer " + sessionStorage.getItem('token'),
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        snippet: {
            playlistId: "PL2jJW0z9auIfNcigq0-yVYVLiD--febPX",
            position: 0,
            resourceId: {
                kind: "youtube#video",
                videoId: "NiDGTprVJu4"
            }
        }
    })
}).then(r => r.json()).then(console.log)

Adding this for my self because figuring out oauth each time hurts

Api reference can be found here

But at the very end I ended up with syncing Youtube playlist right inside Google sheets