1 (изменено: Malcev, 2023-03-12 05:28:33)

Тема: AHK: Google OAuth 2.0 и YouTube API

Так как Гугл прекратил поддержку авторизации с броузеров без включенного джаваскрипт,
https://security.googleblog.com/2018/10 … ts-to.html
то автоматизировать, например, ютуб стало возможным только через апи.
Алгоритм:
Прежде всего нам надо зарегестрировать свое устройство.
Заходим в https://console.developers.google.com
Создаем новый проект.
Выбираем созданный проект.
Переходим на вкладку OAuth consent screen, выбираем external, вписываем название апликации, имейлы -> save and continue.
После чего в test users->add users-> указываем свой имейл.
Переходим на вкладку Library.
Находим YouTube Data API v3, нажимаем на него, потом нажимаем на Enable.
Переходим на вкладку Credentials, нажимаем Create credentials->Api key.
Этот апи ключ нам надо сохранить и посылать каждый раз при использовании ютуб апи.
После чего нажимаем Create credentials->OAuth client ID.
Там выбираем Application type->Desktop Application.
Появляется окошко  OAuth client created, в нем скачиваем json.
Скачиваем JSon.
Должен скачаться такой:

{"installed":{"client_id":"341870872-dgbbg66.apps.googleusercontent.com","project_id":"certain-hau-29","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"JJN1OS7110v-j","redirect_uris":["http://localhost"]}}

В нем нам нужны client_id и client_secret.
Теперь нам надо разрешить доступ нашего устройства.
Создаем такой код со своими данными:

; изменяем данные
ClientId := "341870872-dgbbg66.apps.googleusercontent.com"
ClientSecret := "JJN1OS7110v-j"

; дальше не изменяем
RedirectUri := "http://localhost"
scope := "https://www.googleapis.com/auth/youtube"
msgbox % clipboard := "https://accounts.google.com/o/oauth2/auth?redirect_uri=" UriEncode(RedirectUri) "&response_type=code&client_id=" ClientId "&scope=" UriEncode(scope) "&clientSecret=" ClientSecret "&access_type=offline&approval_prompt=force"

UriEncode(Uri)
{
   VarSetCapacity(Var, StrPut(Uri, "UTF-8"), 0)
   StrPut(Uri, &Var, "UTF-8")
   f := A_FormatInteger
   SetFormat, IntegerFast, H
   While Code := NumGet(Var, A_Index - 1, "UChar")
      If (Code >= 0x30 && Code <= 0x39 ; 0-9
         || Code >= 0x41 && Code <= 0x5A ; A-Z
         || Code >= 0x61 && Code <= 0x7A) ; a-z
         Res .= Chr(Code)
      Else
         Res .= "%" . SubStr(Code + 0x100, -1)
   SetFormat, IntegerFast, %f%
   Return, Res
}

Если нам надо получить доступ к нескольким scope, то их надо перечислять через пробел и без слеша в конце:

scope := "https://mail.google.com https://www.googleapis.com/auth/calendar"

Запускаем код, полученную ссылку вставляем в браузер, переходим по ней.
Разрешаем использовать наше устройство и в итоге будет перенаправление на 404 страницу.
Копируем из адресной строки часть http://localhost/?code=4/7wCaeBV61IBslGg5pU9AZZ-XvrtJp7Dmnfh_khOlv6Co-sUuL0OMd7jt5s&scope.
Это код авторизации.
После чего создаем и запускаем следующий скрипт:

; изменяем данные
ClientId := "341870872-dgbbg66.apps.googleusercontent.com"
ClientSecret := "JJN1OS7110v-j"
AuthorizationCode := "4/7wCaeBV61IBslGg5pU9AZZ-XvrtJp7Dmnfh_khOlv6Co-sUuL0OMd7jt5s"

; дальше не изменяем
RedirectUri := "http://localhost"
Request := "grant_type=authorization_code&code=" AuthorizationCode "&redirect_uri=" UriEncode(RedirectUri) "&client_id=" ClientId "&client_secret=" ClientSecret
WinHTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
WinHTTP.Open("POST", "https://accounts.google.com/o/oauth2/token", true)
WinHTTP.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
WinHTTP.Send(Request)
WinHTTP.WaitForResponse()
msgbox % clipboard := WinHTTP.ResponseText

UriEncode(Uri)
{
   VarSetCapacity(Var, StrPut(Uri, "UTF-8"), 0)
   StrPut(Uri, &Var, "UTF-8")
   f := A_FormatInteger
   SetFormat, IntegerFast, H
   While Code := NumGet(Var, A_Index - 1, "UChar")
      If (Code >= 0x30 && Code <= 0x39 ; 0-9
         || Code >= 0x41 && Code <= 0x5A ; A-Z
         || Code >= 0x61 && Code <= 0x7A) ; a-z
         Res .= Chr(Code)
      Else
         Res .= "%" . SubStr(Code + 0x100, -1)
   SetFormat, IntegerFast, %f%
   Return, Res
}

Ответ должен прийти c access_token и refresh_token:

{
  "access_token": "ya29.GluuBhDBPs66aSxf3TR0k7VetBWezYD_GXBcyKIBMIIOjWkkfsPcNDDh4pVCXy5U4C-g3Y1GxxF_26",
  "expires_in": 3600,
  "refresh_token": "1/SjYrJK9Ja2N57TxxIdoxvMTrrj2vDReeFK7yMOTLgA6fLsJp",
  "scope": "https://www.googleapis.com/auth/youtube",
  "token_type": "Bearer"
}

После чего можно подключиться к управлению апи ютуба.
Следующий код добавляет видео в плейлист:

; изменяем данные
videoId := "A_QfO7g1YsI"
playlistId := "PLp9-Tn608wZdTS44vpp9hYhke"
YoutubeApiKey := "AIzaS9999999999999nm4rYaTA3EC397_ik"
access_token := "ya29.GluuBhDBPs66aSxf3TR0k7VetBWezYD_GXBcyKIBMIIOjWkkfsPcNDDh4pVCXy5U4C-g3Y1GxxF_26"
refresh_token := "1/SjYrJK9Ja2N57TxxIdoxvMTrrj2vDReeFK7yMOTLgA6fLsJp"

; дальше не изменяем
url := "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&key=" YoutubeApiKey
Json = {'snippet': {'playlistId': '%playlistId%', 'resourceId': {'kind': 'youtube#video', 'videoId': '%videoId%'}}}

WinHTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
WinHTTP.Open("POST", url, true)
WinHTTP.SetRequestHeader("Authorization", "Bearer " access_token)
WinHTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
WinHTTP.SetRequestHeader("Content-Type", "application/json")
WinHTTP.Send(Json)
WinHTTP.WaitForResponse()
msgbox % WinHTTP.ResponseText

Обновлять токен так:

; изменяем данные
ClientId := "341870872-dgbbg66.apps.googleusercontent.com"
ClientSecret := "JJN1OS7110v-j"
RefreshToken := "1/SjYrJK9Ja2N57TxxIdoxvMTrrj2vDReeFK7yMOTLgA6fLsJp"

; дальше не изменяем
Request := "refresh_token=" RefreshToken "&client_id=" ClientId "&client_secret=" ClientSecret "&grant_type=refresh_token"
WinHTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
WinHTTP.Open("POST", "https://accounts.google.com/o/oauth2/token", true)
WinHTTP.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
WinHTTP.Send(Request)
WinHTTP.WaitForResponse()
msgbox % clipboard := WinHTTP.ResponseText

Тема для обсуждения