Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I access google photos from my node js app?

I am writing an app to access a user's images on Google Photos.

It seems that there is no 'official' API for Google Photos, however the images can be accessed via the Picasa Web Albums API.

There are no official Google Picasa Web Albums API references/documentation for NodeJS / Javascript.

How can I access this API from my Node app ?

like image 332
phelm Avatar asked Jul 03 '15 12:07

phelm


1 Answers

To download the latest 10 photos from google photos, do the first 2 steps of the quickstart, insert the client secret, client id and redirect into the coffeescript below and run it. (npm install --global coffeescript then coffee quickstart.coffee to run or coffee -c quickstart.coffee to compile to javascript)

I think the user has to connect their google photos account with google drive for this to work.

Hints for working with the Reference (v3) and google drive in general:

  • don't forget the auth object when you call api functions that require authentication: service.files.list({auth:auth, other params here...},callback) - if you forget, it returns a Daily Limit for Unauthenticated Use Exceeded error
  • every file has many properties, but in v3 of the Api it doesn't return all the fields of the resource by default. You'll have to specify them via the fields option like this: service.files.get({auth:auth,fileId:"1y3....",fields:"mimeType, webContentLink, webViewLink, thumbnailLink"},callback)
  • if you want to download a file, put alt:"media"in the options
  • you can query files with the q option. Look at the available serach parameters. Note that you can combine and nest searches via and, or and not.
  • there are no real "folders" in google drive. every file can have multiple "parents".
    • you can get the ids of all folders by calling service.files.list with the query option q:'mimeType = "application/vnd.google-apps.folder"'
    • to get a folder by name use query q:'name = "<name of folder>" and mimeType = "application/vnd.google-apps.folder"'
    • you could get the id of the root folder by calling service.files.get({auth:auth, fileId:"root"},callback) - but you can simply use root where you would put this id
    • to list all the things in the root folder call service.files.list({auth:auth,q:'parents in "root"'},callback)
    • if you have the id of a file, you can get the folder(s) of the file by calling service.files.get with the fields:"parents" option
    • you you have the id of a folder you can get the files of this folder by calling service.files.list with a query option q:'parents in "0B7..."' (note that the id needs "...")
    • listing the files in the folder with the path /one/two/three is the same as listing the files of the folder three - but you'll need the id of this folder first. you can get this id by iteratively walking down the path
fs = require('fs')
readline = require('readline')
google = require('googleapis')
googleAuth = require('google-auth-library')

SCOPES = [ 'https://www.googleapis.com/auth/drive' ] # scope for everything :D
TOKEN_PATH = './token.json'
CLIENT_SECRET = <your client secret here>
CLIENT_ID = <your client id here>
REDIRECT = <your redirect url here>

authorize = (callback) ->
    auth = new googleAuth
    oauth2Client = new auth.OAuth2(CLIENT_ID, CLIENT_SECRET,REDIRECT)
    # Read the Token at ./token.json or get a new one
    fs.readFile TOKEN_PATH, (err, token) -> 
        if err
            getNewToken oauth2Client, callback
        else
            oauth2Client.credentials = JSON.parse(token)
            callback oauth2Client

getNewToken = (oauth2Client, callback) ->
    authUrl = oauth2Client.generateAuthUrl({access_type: 'offline', scope: SCOPES})
    console.log 'Authorize this app by visiting this url: ', authUrl

    rl = readline.createInterface({input: process.stdin,output: process.stdout})
    rl.question 'Enter the code in the address bar without the "#"(?code=<code>#)', (code) ->
        rl.close()
        oauth2Client.getToken code, (err, token) ->
            oauth2Client.credentials = token
            fs.writeFile TOKEN_PATH, JSON.stringify(token) # store token for later
            callback oauth2Client

authorize (auth)->
    service = google.drive('v3')
    # get ids of the 10 most recent photos
    # every request needs the auth:auth
    service.files.list {auth:auth,pageSize: 10,orderBy: 'createdTime desc',q:"mimeType = 'image/jpeg'"},(err,response)->
        for file in response.files 
            dest = fs.createWriteStream(file.name)
            # you have to add the alt:"media" option to get the file contents
            # if you want a link to the file that can be used in an <img src=''> tag: add fields:"webContentLink"
            service.files.get({auth:auth,fileId:file.id,alt:"media"}).pipe(dest)
like image 123
tino Avatar answered Sep 25 '22 17:09

tino