Skip to content

Instantly share code, notes, and snippets.

@Cyclingbob
Last active August 27, 2023 10:15
Show Gist options
  • Select an option

  • Save Cyclingbob/8f91c5f25cfa86dd669f83f78bf72e71 to your computer and use it in GitHub Desktop.

Select an option

Save Cyclingbob/8f91c5f25cfa86dd669f83f78bf72e71 to your computer and use it in GitHub Desktop.
Google photos download photos from album. Call locoalhost/login to login to google oauth, then go to localhost and use query ?album=<album name>

Requirements

You must create an oauth2 application on google cloud to obtain your client id and secret, and you must create the redirects to that it matches the configuration.

Copyright

Permission is granted, for all files of this github gist, for the ability to modify and use this content for personal use and commercial use. Permission is not granted to redistribute exact copies or modified copies except where this falls under fair use under Copyright and Patents Act 1988 or where explicit permission has been granted by the creator.

{
"client_id": "",
"client_secret": "",
"redirect_uri": "http://localhost/auth/google/callback"
}
const fetch = require("node-fetch")
const express = require("express")
const cookieParser = require("cookie-parser")
const app = express()
app.use(cookieParser())
const fs = require("fs")
const path = require("path")
const file_to_download_to = "your file"
const config = require("./config.json")
app.get('/login', (req, res) => {
res.redirect(`https://accounts.google.com/o/oauth2/v2/auth?client_id=${config.client_id}&redirect_uri=${config.redirect_uri}&response_type=code&scope=https://www.googleapis.com/auth/photoslibrary.readonly`)
})
app.get('/auth/google/callback', (req, res) => {
const code = req.query.code;
if(!code) return res.redirect('/login')
const url = `https://oauth2.googleapis.com/token?code=${code}&client_id=${config.client_id}&client_secret=${config.client_secret}&redirect_uri=${config.redirect_uri}&grant_type=authorization_code`;
fetch(url, { method: 'POST' })
.then(response => response.json())
.then(data => {
res.cookie('token', data.access_token)
res.redirect("/")
})
.catch(error => {
console.error(error)
res.status(500).send('Error retrieving access token')
});
})
app.get('/', (req, res) => {
if(req.cookies.token) var code = req.cookies.token
else return res.redirect('./login')
var selected = req.query.album
fetch("https://photoslibrary.googleapis.com/v1/albums?pageSize=50", {
headers: {
"Authorization": "Bearer " + code,
'Content-Type': 'application/json'
}
}).then(res => res.json()).then(data => {
var album = data.albums.find(a => a.title === selected).id
fetch(`https://photoslibrary.googleapis.com/v1/mediaItems:search?pageSize=50`, {
headers: {
"Authorization": "Bearer " + code,
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify({
pageSize: 10,
albumId: album
})
}).then(res => res.json()).then(json => {
res.send(json)
json.mediaItems.forEach((item, i) => {
setTimeout(item => {
let photo = item
fetch(`https://photoslibrary.googleapis.com/v1/mediaItems/` + photo.id, {
headers: {
"Authorization": "Bearer " + code,
'Content-Type': 'application/json'
},
}).then(res => res.json()).then(data => {
let file = path.join(file_to_download_to, json.mediaItems[i].filename)
console.log(file)
fetch(data.baseUrl + `=w${data.mediaMetadata.width}-h${data.mediaMetadata.height}`).then(res => res.body.pipe(fs.createWriteStream(file)))
})
}, i * 500, item)
})
}).catch(console.error)
}).catch(console.error)
})
app.listen(80)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment