0

I'm trying to load an album from Google Photos via javascript but I don't understand how the api works, I started reading Google Photos API but no luck. Is there a code reference that I can follow to get a list of the photos of my album?

I found this but doesn't work

<script>   

var scopeApi = ['https://www.googleapis.com/auth/photoslibrary', 'https://www.googleapis.com/auth/photoslibrary.readonly', 'https://www.googleapis.com/auth/photoslibrary.readonly.appcreateddata'];

function onAuthPhotoApiLoad() {
    window.gapi.auth.authorize(
        {
            'apiKey': 'MY_API_KEY',
            'client_id': "MY_CLIEND_ID",
            'scope': scopeApi,
            'immediate': false
        },
        handlePhotoApiAuthResult);
}


function handlePhotoApiAuthResult(authResult) {
    if (authResult && !authResult.error) {
        oauthToken = authResult.access_token;

            GetAllPhotoGoogleApi();
    }
}


function GetAllPhotoGoogleApi() {
    gapi.client.request({
        'path': 'https://photoslibrary.googleapis.com/v1/albums',
        'method': 'POST' 
    }).then(function (response) {
        console.log(response);     

    }, function (reason) {
        console.log(reason);
    });
}

onAuthPhotoApiLoad();

1 Answers1

2

While in the process of developing a Photos synching script, I spent a few days researching and testing the Oauth 2.0 documentation. It's a lot to take in, but hopefully this Cliff-notes version is helpful:

  1. App Setup You first need to get an application configuration through the developer console at console.developers.google.com/ and make sure that the Photos data is shared.

    You'll get a JSON file that looks like this

        {"installed":{
         "client_id":"xxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
         "project_id":"xxxx-xxxxxxxx-123456",
         "auth_uri":"https://accounts.google.com/o/oauth2/auth",
         "token_uri":"https://accounts.google.com/o/oauth2/token",
         "auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
         "client_secret":"xxxxxxxxxxxxxxxxxxxxxxxx",
         "redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]
         }}
    
  2. Request Authorization Code - You then need to write code that uses those values to get an authorization token - basically a string that indicates the user has allowed your application access to their data. Send a request to the auth_uri endpoint with these values in the querystring:

    • scope - a space-delimited list of scopes from developers.google.com/photos that says you want your user to grant access to these features
    • redirect_uri - a URL you own that can capture an incoming querystring
    • client_id - from your developer config in step 1
    • state - 32 random bytes, base64 encoded and made URL-friendly by replacing "+","/","=" with "-","_","" respectively
    • code_challenge - a SHA256 hash of another 32 random bytes, base64 encoded and made URL-friendly
    • code_challenge_method - "S256" (no quotes)
  3. Authorization round trip Sending this composed URI to a user's browser will allow them to choose a Google account and show which scopes are being requested. Once that form is submitted, it will redirect to your redirect_uri with querystring (Method = GET) values:

    • code - the authorization code you can use to request an access token
    • state - a string you can use to validate against your hash
  4. Get an access_token Finally you exchange the authorization code for an OAuth AccessToken that you'll put in the HTTP header of all the API requests. The request goes to the token_uri from step 1 and has these request body (Method = POST) parameters:

    • code - you got from the redirect querystring in Step 3
    • redirect_uri - same as above, but this may not be used
    • client_id - from configuration
    • code_verifier - code_challenge before it was hashed
    • client_secret - from configuration
    • scope - can be empty here
    • grant_type - "authorization_code" (no quotes)
  5. Use the access tokens The response from that request will have an access_token and a refresh_token. You can use the short-lived access_token immediately in your API request's HTTP header. Store the long-lived refresh_token so you can get a new access_token without authorizing again.

That's the gist of it. You can look at my Powershell script for an example of the authorization and authentication flows which work even though the rest is a little buggy and incomplete. Paging through albums is getting a 401 error sometimes.

Rich Moss
  • 2,195
  • 1
  • 13
  • 18
  • Thanks.. I'll try it. – user3342679 Aug 22 '18 at 15:53
  • Check the latest version that's fixed a few bugs and added mediaItems support. – Rich Moss Sep 05 '18 at 00:23
  • @RichMoss, I have created a new project in console.developers.google.com, then enabled Photo API, then created oauth credentials for a web application (running from powershell actually, is this correct?). Then I have copied your script changing data from the downloaded json but ..... (continues) – Riccardo Aug 29 '19 at 21:07
  • @RichMoss ..I keep getting a 400 error in the browser "The redirect URI in the request, http://127.0.0.1:58544/, does not match the ones authorized for the OAuth client. To update the authorized redirect URIs, visit: " - Where am I wrong? – Riccardo Aug 29 '19 at 21:08
  • The script I wrote assumes it is running locally and an endpoint at IP 127.0.0.1 Port 58544 is controlled by you. If you are running in console.developers.google.com, you won't have a service listening on that port. – Rich Moss Aug 30 '19 at 19:00
  • @RichMoss could you clarify, eventually pointing out, what steps should I follow to set correctly credentials & settings in the developers console to run your script? My settings: https://prnt.sc/p0fofv – Riccardo Sep 01 '19 at 19:31
  • @Riccardo sorry I'm not much help there. I've had success running my script locally, but not in the developer console; and my console expired a few weeks back so I can't experiment any more. I suggest creating a new question that is likely to get better answers than I can currently provide. – Rich Moss Sep 03 '19 at 05:54