patch to download

Google OAuth 2.0 + Google Photo Library API

Using the Google Photos Library API your app can read, write, and share photos and videos in Google Photos.

API uses OAuth 2.0 to handle authentication and authorization. Your app can request access to the user's Google Photos library via the various authorization scopes provided by the API.

To begin, obtain OAuth client credentials from the Google API Console. Then your client application requests an access token from the Google Authorization Server, extracts a token from the response, and sends the token to the Google API that you want to access. Both of then u should playce into PLACE HERE.


...
gapi.client.init({
        'apiKey': 'PLACE HERE YOUR APIKEY',
        'discoveryDocs': [discoveryUrl],
        'clientId': 'PLACE HERE YOUR CLIENTID',
        'scope': SCOPE
    }).then(function () {
...


right now we have option of authorizing users through the OAuth protocol.

If we are in the testing phase and our application has not yet been verified by Google, please use the photo below when authorizing.


Functionalities :

  • user authorization from Google
  • displaying photos from the user's gallery
  • display photos in timeline mode
  • displaying photos from the selected album
  • filtering by date
  • limiting the number of displayed photos


The attachment contains an example of use shown below and a library.

A simple example of using the prepared library for the Google Photo Libery API.

 

 

Przygotowana biblioteka dla Google Photos Library API



class GooglePhotosLibraryAPI {
$/*
the function lists user's pictures (timeline)
the pageSize parameter is the maximum number of photos that are returned in response
nextPageToken accepts an empty string when 1 page
nextPageToken accepts nextPageToken from the answer to go to the next page                                                                                          
$*/
listPhotoGoogleApiTimeline (pageSize, nextPageToken, callbackFunction) {
gapi.client.request({
'path': 'https://photoslibrary.googleapis.com/v1/mediaItems',
'params': {
'pageSize': pageSize,
'pageToken': nextPageToken
},
'method': 'GET',
'body':{
'filters': {
'mediaTypeFilter': {
'mediaTypes': ['PHOTO']
}
}
}
}).then(function (resp) {
callbackFunction(resp);
}, function (reason) {
return reason;
});
}

$/*
the function lists the user's albums
         the pageSize parameter is the maximum number of albums to be returned in response
$*/
listAlbumsGoogleApi(pageSize, callbackFunction) {
gapi.client.request({
'path': 'https://photoslibrary.googleapis.com/v1/albums',
'params': {
'pageSize': pageSize
},
'method': 'GET'
}).then(function (resp) {
callbackFunction(resp);
}, function (reason) {
return reason;
});
}

$/*
        function lists photos from the album
         the pageSize parameter is the maximum number of photos that are returned in response
         selectedToken parameter is the id of the album we want to list
         nextPageToken accepts an empty string when 1 page
         nextPageToken accepts nextPageToken from the answer to go to the next page

$*/
getSelectedValueListAlbumsGoogleApi (selectedToken, pageSize, nextPageToken, callbackFunction) {
gapi.client.request({
'path': 'https://photoslibrary.googleapis.com/v1/mediaItems:search',
'params': {
'albumId' : selectedToken,
'pageToken': nextPageToken,
'pageSize': pageSize
},
'method': 'POST'
}).then(function (resp) {
callbackFunction(resp);
}, function (reason) {
return reason;
});
}

$/*
funkjca filtruje galerię użytkownika
parametr pageSize to maksymalna liczba zdjęć zwaracana w odpowiedzi
startDay,startMonth,startYear - filtrowanie od
endDay,endMonth,endYear - filtrowanie do
nextPageToken przyjmuje pusty string kiedy 1 strona
nextPageToken przyjmuje nextPageToken z odpowiedzi aby przejść do kolejnej strony
$*/
searchPhotoGoogleApiFromAlbum (startDay, startMonth, startYear, endDay, endMonth, endYear, pageSize, nextPageToken, callbackFunction) {
gapi.client.request({
"path": "https://photoslibrary.googleapis.com/v1/mediaItems:search",
"method": "POST",
"params": {
"pageSize": pageSize,
"pageToken": nextPageToken
},
"body":{
"filters": {
"mediaTypeFilter": {
"mediaTypes": ["PHOTO"]
},
"dateFilter": {
"ranges": [
{
"startDate": {
"day": startDay,
"month": startMonth,
"year": startYear
},
"endDate": {
"day": endDay,
"month": endMonth,
"year": endYear
}
}
]
}
}
}
}).then(function (resp) {
callbackFunction(resp);
}, function (reason) {
return reason;
});
}

}

JavaScript OAuth 2.0



function handleClientLoad() {
// Load the API's client and auth2 modules.
// Call the initClient function after the modules load.
gapi.load('client:auth2', initClient);
}

function initClient() {
// Retrieve the discovery document for version 3 of Google Drive API.
// In practice, your app can retrieve one or more discovery documents.
var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

// Initialize the gapi.client object, which app uses to make API requests.
// Get API key and client ID from API Console.
// 'scope' field specifies space-delimited list of access scopes.
gapi.client.init({
'apiKey': 'PLACE HERE YOUR APIKEY',
'discoveryDocs': [discoveryUrl],
'clientId': 'PLACE HERE YOUR CLIENTID',
'scope': SCOPE
}).then(function () {
GoogleAuth = gapi.auth2.getAuthInstance();
// Listen for sign-in state changes.
GoogleAuth.isSignedIn.listen(updateSigninStatus);
// Handle initial sign-in state. (Determine if user is already signed in.)
var user = GoogleAuth.currentUser.get();
setSigninStatus();
// Call handleAuthClick function when user clicks on
// "Sign In/Authorize" button.
jq('#sign-in-or-out-button').click(function() {
handleAuthClick();
});
jq('#revoke-access-button').click(function() {
revokeAccess();
});
});
}

function handleAuthClick() {
if (GoogleAuth.isSignedIn.get()) {
// User is authorized and has clicked 'Sign out' button.
GoogleAuth.signOut();
} else {
// User is not signed in. Start Google auth flow.
GoogleAuth.signIn();
}
}
function revokeAccess() {
GoogleAuth.disconnect();
}
function setSigninStatus(isSignedIn) {
var user = GoogleAuth.currentUser.get();
var isAuthorized = user.hasGrantedScopes(SCOPE);
if (isAuthorized) {
jq('#sign-in-or-out-button').html('Sign out');
jq('#revoke-access-button').css('display', 'inline-block');
jq('#auth-status').html('You are currently signed in and have granted ' +
'access to this app.');
googlePhotosLibrary.listAlbumsGoogleApi(20,drawMyAlbumDroplist)
googlePhotosLibrary.listPhotoGoogleApiTimeline(10,'', drawMyPicturesTimeline)
} else {
jq('#sign-in-or-out-button').html('Sign In/Authorize');
jq('#revoke-access-button').css('display', 'none');
jq('#auth-status').html('You have not authorized this app or you are ' +
'signed out.');
}
}
function updateSigninStatus(isSignedIn) {
setSigninStatus();
}

JavaScript API



$/*
funkcja obrabia odpowiedź i wyświetla zdjęcia na osi czasu
$*/
function drawMyPicturesTimeline(resp){
if(resp.result.nextPageToken){
jq('#nextPagePhotoGoogle').show()
nextPageToken = resp.result.nextPageToken
}else{
jq('#nextPagePhotoGoogle').hide()
nextPageToken = '';
}
for (i=0; i<resp.result.mediaItems.length; i++) {
baseUrl = resp.result.mediaItems[i].baseUrl
filename = resp.result.mediaItems[i].filename
var img = document.createElement('img');
img.height = 250;
img.style = "padding:10px";
img.title = filename;
img.src = baseUrl;
document.getElementById('imagediv').appendChild(img);
}
}
$/*
funkcja obrabia odpowiedź i tworzy dropliste albumów użytkownika
$*/
function drawMyAlbumDroplist(resp){
var div = document.querySelector("#dropListAlbumContainer"),
frag = document.createDocumentFragment(),
select = document.createElement("select");
select.options.add( new Option("Oś czasu",-1) );
for (i=0; i<resp.result.albums.length; i++) {
title = resp.result.albums[i].title;
productUrl = resp.result.albums[i].productUrl;
token = resp.result.albums[i].id;
select.options.add( new Option(title,token) );
}
frag.appendChild(select);
div.appendChild(frag);
}
$/*
funkcja na podstawie input hidden wybiera funkcję,
której ma użyć do wyświetlenia kolejnych zdjęć
$*/
function drawMoreMyPicturesManager(){
if( jq('#status').val() == 0 ) {
googlePhotosLibrary.listPhotoGoogleApiTimeline(10, nextPageToken, drawMyPicturesTimeline)
}else if ( jq('#status').val() == 1) {
googlePhotosLibrary.getSelectedValueListAlbumsGoogleApi(selectedToken, 10, nextPageToken, drawMyPicturesFromAlbum)
}else if ( jq('#status').val() == 2){
googlePhotosLibrary.searchPhotoGoogleApiFromAlbum(startDay, startMonth, startYear, endDay, endMonth, endYear, 10, nextPageToken, drawMyPicturesFromSearchDate)
}
}
$/*
funkcja na podstawie input hidden wybiera funkcję,
której ma użyć do wyświetlenia zdjęć z wybranego albumu
$*/
function drawMyPicturesFromDroplist(){
jq("#imagediv").empty();
nextPageToken='';
selectedToken = jq('#dropListAlbumContainer').find( "select" ).val();
if( selectedToken == -1 ) {
jq('#status').val(0)
googlePhotosLibrary.listPhotoGoogleApiTimeline(10, '', drawMyPicturesTimeline)
}else{
jq('#status').val(1)
googlePhotosLibrary.getSelectedValueListAlbumsGoogleApi(selectedToken, 10, '', drawMyPicturesFromAlbum)
}
}
$/*
funkcja na listuje zdjęcia z wybranego albumu
$*/
function drawMyPicturesFromAlbum(resp){
if(resp.result.nextPageToken){
jq('#nextPagePhotoGoogle').show()
nextPageToken = resp.result.nextPageToken
}else{
jq('#nextPagePhotoGoogle').hide()
nextPageToken = '';
}
for (i=0; i<resp.result.mediaItems.length; i++) {
baseUrl = resp.result.mediaItems[i].baseUrl
filename = resp.result.mediaItems[i].filename
var img = document.createElement('img');
img.height = 250;
img.style = "padding:10px";
img.title = filename;
img.src = baseUrl;
document.getElementById('imagediv').appendChild(img);
}
}
$/*
funkcja na listuje zdjęcia z filtru daty
$*/
function drawMyPicturesFromSearchDate(resp) {
if(!resp.result.mediaItems){
alert("Brak wyników.")
}else{
if(resp.result.nextPageToken){
nextPageToken = resp.result.nextPageToken
jq('#nextPagePhotoGoogle').show()
}else{
nextPageToken = '';
jq('#nextPagePhotoGoogle').hide()
}
for (i=0; i<resp.result.mediaItems.length; i++) {
baseUrl = resp.result.mediaItems[i].baseUrl
filename = resp.result.mediaItems[i].filename
var img = document.createElement('img');
img.height = 250;
img.style = "padding:10px";
img.title = filename;
img.src = baseUrl;
document.getElementById('imagediv').appendChild(img);
}
}
}
$/*
Pobiera dane ustawionej daty do filtrowania,
następnie przekazuje do funkcji wysyłającej zapytanie
$*/
function searchDateManager(){
jq('#status').val(2);
var date = new Date(jq('#startFilterDate').val());
startDay = date.getDate();
startMonth = date.getMonth() + 1;
startYear = date.getFullYear();
date = new Date(jq('#endFilterDate').val());
endDay = date.getDate();
endMonth = date.getMonth() + 1;
endYear = date.getFullYear();
googlePhotosLibrary.searchPhotoGoogleApiFromAlbum(startDay, startMonth, startYear, endDay, endMonth, endYear, 10, '', drawMyPicturesFromSearchDate)
}

HTML



<input type="hidden" id="status" value="0"/>
<button id="sign-in-or-out-button" style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button" style="display: none; margin-left: 25px">Revoke access</button>
$//container na status OAuth
<div id="auth-status" style="display: inline; padding-left: 25px"></div>
$//container na droplista z albumi
<div id="dropListAlbumContainer" style="display: inline; padding-left: 25px">
<input type="button" id="selectedAlbum" value="Wybierz" onclick="drawMyPicturesFromDroplist()" />
</div>
od:
<input type="date" id="startFilterDate"/>
do:
<input type="date" id="endFilterDate"/>
<input type="button" id="submitDateFilterButton" value="Szukaj" onclick="searchDateManager()">
$//container na zdjeca
<div id="imagediv"></div>
<input type="button" id="nextPagePhotoGoogle" value="Więcej" onclick="drawMoreMyPicturesManager()">
 



Return