Can I read a drive file opened using Google Picker with drive.file oauth scope? - google-apps-script

I created a forms addon with scope:
https://www.googleapis.com/auth/drive.file
and created a picker:
function onOpen(e)
{
FormApp.getUi().createAddonMenu()
.addItem('Sync to Drive', 'showPicker')
.addToUi();
}
function getOAuthToken() {
return ScriptApp.getOAuthToken();
}
function showPicker() {
var html = HtmlService.createHtmlOutputFromFile('Picker.html')
.setWidth(600)
.setHeight(425)
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
FormApp.getUi().showModalDialog(html, 'Select Folder');
}
// Use Advanced Drive Service - https://developers.google.com/apps-script/advanced/drive
function getFileWithAdvancedDriveService(fileId)
{
var drivefl = Drive.Files.get(fileId);
FormApp.getUi().alert('File: '+drivefl);
return drivefl;
}
// Use Drive Service - https://developers.google.com/apps-script/reference/drive
function getFileWithDriveService(fileId)
{
var drivefl = DriveApp.getFileById(fileId);
FormApp.getUi().alert('File: '+drivefl);
return drivefl;
}
After I open a file using this picker, I am trying to read it in the pickerCallback:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css" />
<script type="text/javascript">
var DIALOG_DIMENSIONS = {
width: 600,
height: 425,
};
var authToken;
var pickerApiLoaded = false;
function onApiLoad() {
gapi.load('picker', {
callback: function () {
pickerApiLoaded = true;
},
});
google.script.run.withSuccessHandler(createPicker).withFailureHandler(showError).getOAuthToken();
}
function createPicker(token) {
authToken = token;
if (pickerApiLoaded && authToken) {
var docsView = new google.picker.DocsView()
.setIncludeFolders(true);
var picker = new google.picker.PickerBuilder()
.addView(docsView)
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.hideTitleBar()
.setOAuthToken(authToken)
.setCallback(pickerCallback)
.setOrigin('https://docs.google.com')
.build();
picker.setVisible(true);
} else {
showError('Unable to load the file picker.');
}
}
function pickerCallback(data, ctx) {
var action = data[google.picker.Response.ACTION];
if(action == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
var id = doc[google.picker.Document.ID];
// Option 1 - Advanced Drive Service in apps script
return google.script.run.withSuccessHandler(showMessage).withFailureHandler(showError).getFileWithAdvancedDriveService(id);
// Option 2 - Drive Service in apps script
return google.script.run.withSuccessHandler(showMessage).withFailureHandler(showError).getFileWithDriveService(id);
// Option 3 - Drive Service in client
return gapi.load('client', function () {
gapi.client.load('drive', 'v2', function () {
gapi.client.setToken({ access_token: authToken });
var file = gapi.client.drive.files.get({ 'fileId': id });
file.execute(function (resp) {
showMessage(resp);
});
});
});
} else if(action == google.picker.Action.CANCEL) {
google.script.host.close();
}
}
function showMessage(message) {
document.getElementById('result').innerHTML = '<div>Message:</div> ' + JSON.stringify(message);
}
function showError(message) {
document.getElementById('result').innerHTML = `<div>Error:</div> <div style="color:red;">${message}</div>`;
}
</script>
</head>
<body>
<div>
<p id="result"></p>
</div>
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
</body>
</html>
gapi.client.drive.files.get fails with the error:
code: 404, message: "File not found: 1d0cqiT3aipgjMfLPolzgWVrnsl4xPxUJ1_7pH3ONVzU"
I tried the same on the server side (apps script) and got similar error:
DriveApp.getFolderById(fileId)
returns:
You do not have permission to call DriveApp.getFolderById. Required permissions: (https://www.googleapis.com/auth/drive.readonly || https://www.googleapis.com/auth/drive)
Same with advanced drive api:
Drive.Files.get(fileId)
returns:
GoogleJsonResponseException: API call to drive.files.get failed with error: File not found: 1d0cqiT3aipgjMfLPolzgWVrnsl4xPxUJ1_7pH3ONVzU
Do I need drive.readonly scope to read the file opened by the user using Google Picker?

Yes, as the https://www.googleapis.com/auth/drive.file scope only allows you to:
View and manage Google Drive files and folders that you have opened or created with this app
And https://www.googleapis.com/auth/drive.readonly:
See and download all your Google Drive files
You can review the full list of scopes here.

I found the problem. It works if I move this gapi.load code from pickerCallback:
return gapi.load('client', function () {
gapi.client.load('drive', 'v2', function () {
gapi.client.setToken({ access_token: authToken });
var file = gapi.client.drive.files.get({ 'fileId': id });
file.execute(function (resp) {
showMessage(resp);
});
});
});
to javascript onload:
function onGsiLoad()
{
return gapi.load('client', function () {
return gapi.client.load('drive', 'v2', function () {
gsiLoaded = true;
maybeEnablePicker();
});
});
}
And only have gapi.client.drive.files.get in pickerCallback:
var file = gapi.client.drive.files.get({ 'fileId': fileId });
file.execute(function (resp) {
showMessage(resp);
});
Working test case is here: https://docs.google.com/forms/d/1h3FWKVpGbCApg1_2unD3L86QlOmh9CIwK-W1Q97UTYQ/edit?usp=sharing
Buggy one is here:
https://docs.google.com/forms/d/1jpEa-mp8ccCZhEGlgBN52AML2i1oHIShFpY8Oe3GC44/edit?usp=sharing

Related

Drive file picker from the older Google Sign-In platform library to the newer Google Identity Services library for authentication

I have a code where I read the file data as blob. I have implemented using the old gapi, how do I migrate from the older Google Sign-In platform library to the newer Google Identity Services library for authentication.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Google Picker Example</title>
</head>
<body>
<button id="authorize_button" style="display: none;">Authorize</button>
<button id="signout_button" style="display: none;">Sign Out</button>
<div id="result"></div>
<script type="text/javascript" src="script.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
<script>
const API_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const CLIENT_ID = '995979103146-6qdmadbu7ha5ptrthsg8uqonkpplvc8e.apps.googleusercontent.com';
const appId = "995979103146";
const SCOPES = ["https://www.googleapis.com/auth/drive"];
const DISCOVERY_DOCS = [
"https://www.googleapis.com/discovery/v1/apis/drive/v3/rest",
];
const authorizeButton = document.getElementById("authorize_button");
const signoutButton = document.getElementById("signout_button");
// Use the Google API Loader script to load the google.picker script.
function handleClientLoad() {
gapi.load("client:auth2:picker", initClient);
}
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES[0]
})
.then(
function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(handleSignIn);
// Handle the initial sign-in state.
handleSignIn(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
},
function (error) {
appendPre(JSON.stringify(error, null, 2));
}
);
}
function handleSignIn(isSignedIn) {
if (isSignedIn) {
authorizeButton.style.display = "none";
signoutButton.style.display = "block";
createPicker();
} else {
authorizeButton.style.display = "block";
signoutButton.style.display = "none";
}
}
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
function createPicker() {
const token = gapi.client.getToken().access_token
if (token) {
let view = new google.picker.View(google.picker.ViewId.DOCS);
view.setMimeTypes("image/png,image/jpeg,image/jpg");
let picker = new google.picker.PickerBuilder()
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.setAppId(appId)
.setOAuthToken(token)
.addView(view)
.addView(new google.picker.DocsUploadView())
.setDeveloperKey(API_KEY)
.setCallback(getFile)
.build();
picker.setVisible(true);
}
}
function getFile(pickerResp) {
console.log(JSON.stringify(pickerResp))
if(pickerResp.action == "picked") {
gapi.client.drive.files
.get({
fileId: pickerResp.docs[0].id,
alt: 'media'
})
.then(resp => {
console.log("fetch response", resp.status)
let binary = resp.body
// EDIT - addition from Gabrielle vvvv
let l = binary.length
let array = new Uint8Array(l);
for (var i = 0; i<l; i++){
array[i] = binary.charCodeAt(i);
}
let blob = new Blob([array], {type: 'application/octet-stream'});
console.log(blob)
// EDIT - addition from Gabrielle ^^^^
});
}
}
</script>
</body>
</html>
It is really easy to implement the new Google Identity Library. As you can compare here, you only have to change a few things.
This example is the easiest approach (implicit flow):
One button for retrieving the token
One button for loading the picker
<html>
<body>
<script
src="https://accounts.google.com/gsi/client"
onload="initClient()"
async
defer
></script>
<script>
var client;
var access_token;
function loadPicker() {
gapi.load('picker', {'callback': ()=>console.log("Picker Loaded")});
}
function initClient() {
client = google.accounts.oauth2.initTokenClient({
client_id: "<CLIENT_ID>",
scope:
"https://www.googleapis.com/auth/drive.file",
callback: (tokenResponse) => {
access_token = tokenResponse.access_token;
},
});
}
function getToken() {
client.requestAccessToken();
}
function revokeToken() {
google.accounts.oauth2.revoke(access_token, () => {console.log('access token revoked')});
}
function onPickerApiLoad() {
var picker = new google.picker.PickerBuilder()
.addView(google.picker.ViewId.DOCS)
.setOAuthToken(access_token)
.build();
picker.setVisible(true);
}
</script>
<!-- The Google API Loader script. -->
<h1>Google Identity Services Authorization Token model</h1>
<button onclick="getToken();">Get access token</button><br /><br />
<button onclick="onPickerApiLoad()">Load picker</button>
<script src="https://apis.google.com/js/api.js?onload=loadPicker"></script>
</body>
</html>
Documentation:
Migrate to Google Identity Services
Google has released a new Code sample I would start there to see the changes for authorizaotn. It should just be a matter of swapping out the authorization methods. The rest of the code is unchanged.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Google Picker Example</title>
<script type="text/javascript">
// The Browser API key obtained from the Google API Console.
// Replace with your own Browser API key, or your own key.
var developerKey = 'xxxxxxxYYYYYYYY-12345678';
// The Client ID obtained from the Google API Console. Replace with your own Client ID.
var clientId = "1234567890-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com"
// Replace with your own project number from console.developers.google.com.
// See "Project number" under "IAM & Admin" > "Settings"
var appId = "1234567890";
// Scope to use to access user's Drive items.
var scope = ['https://www.googleapis.com/auth/drive.file'];
var pickerApiLoaded = false;
var oauthToken;
// Use the Google API Loader script to load the google.picker script.
function loadPicker() {
gapi.load('auth', {'callback': onAuthApiLoad});
gapi.load('picker', {'callback': onPickerApiLoad});
}
function onAuthApiLoad() {
window.gapi.auth.authorize(
{
'client_id': clientId,
'scope': scope,
'immediate': false
},
handleAuthResult);
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
oauthToken = authResult.access_token;
createPicker();
}
}
// Create and render a Picker object for searching images.
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var view = new google.picker.View(google.picker.ViewId.DOCS);
view.setMimeTypes("image/png,image/jpeg,image/jpg");
var picker = new google.picker.PickerBuilder()
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.setAppId(appId)
.setOAuthToken(oauthToken)
.addView(view)
.addView(new google.picker.DocsUploadView())
.setDeveloperKey(developerKey)
.setCallback(pickerCallback)
.build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
if (data.action == google.picker.Action.PICKED) {
var fileId = data.docs[0].id;
alert('The user selected: ' + fileId);
}
}
</script>
</head>
<body>
<div id="result"></div>
<!-- The Google API Loader script. -->
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=loadPicker"></script>
</body>
</html>

Google Drive Picker - Not showing all folders

I am using the Google Drive Picker API to facilitate file upload from within a Google Spreadsheet.
The problem the user is reporting is that not all folders in a sub folder are visible or searchable.
The sub folder in question has a large amount of sub folders itself. (About a 1000+)
Does anyone know if Drive Picker has some kind of a limitation around the number of folders it can display?
As requested my code below:
function showPicker() {
var html = HtmlService.createHtmlOutputFromFile('0.2 Picker.html')
.setWidth(600)
.setHeight(425)
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi().showModalDialog(html, 'Select Invoice(s)');
}
function getOAuthToken() {
DriveApp.getRootFolder();
return ScriptApp.getOAuthToken();
}
//Picker.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<script type="text/javascript">
var DIALOG_DIMENSIONS = {
width: 600,
height: 425
};
var pickerApiLoaded = false;
function onApiLoad() {
gapi.load('picker', {
'callback': function() {
pickerApiLoaded = true;
}
});
google.script.run.withSuccessHandler(createPicker)
.withFailureHandler(showError).getOAuthToken();
}
function createPicker(token) {
if (pickerApiLoaded && token) {
var docsView = new google.picker.DocsView(google.picker.ViewId.FOLDERS)
.setIncludeFolders(true)
.setMimeTypes('application/vnd.google-apps.spreadsheet')
.setParent("ID_OF_FOLDER_GOES_HERE");
var picker = new google.picker.PickerBuilder()
.addView(docsView)
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.enableFeature(google.picker.Feature.SUPPORT_DRIVES)
.hideTitleBar()
.setSize(DIALOG_DIMENSIONS.width - 2, DIALOG_DIMENSIONS.height - 2)
.setOAuthToken(token)
.setCallback(pickerCallback)
.setOrigin('https://docs.google.com')
.build();
picker.setVisible(true);
} else {
showError('Unable to load the file picker.');
}
}
/**
* A callback function that extracts the chosen document's metadata from the
* response object. For details on the response object, see
* https://developers.google.com/picker/docs/result
*
* #param {object} data The response object.
*/
function pickerCallback(data) {
//Get the user's response action
var action = data[google.picker.Response.ACTION];
//Test if users selected "Picked", if true, do the following:
if (action == google.picker.Action.PICKED) {
//Get documents uploaded by google picker
var files = data[google.picker.Response.DOCUMENTS];
//Create an array to house ID's of uploaded documents
var arrayOfIds = [];
//For the number of elements in the files array do the following
for (var i = 0; i < files.length; i++) {
//Get the id of the current file
var id = files[i][google.picker.Document.ID]
//Push id of current file into arrayOfIds
arrayOfIds.push(id)
}//END OF FOR LOOP I
//Call getInvoiceData passing in array of IDs
google.script.run.getInvoiceData(arrayOfIds);
//Close the upload box
google.script.host.close()
}//END OF IF STATEMENT
//Check action does not "Picked", check if action is "Cancel"
else if (action == google.picker.Action.CANCEL) {
google.script.host.close();
}//END OF ELSE IF
}//END OF FUNCTION
function showError(message) {
document.getElementById('result').innerHTML = 'Error: ' + message;
}
</script>
</head>
<body>
<div>
<p id='result'></p>
</div>
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
</body>
</html>

How to set light theme on viewer?

I have this sample code, to initialize viewer:
<div id="viewer"></div>
<script>
var app;
var options = {
env: 'AutodeskProduction',
accessToken: 'mytoken'
};
var urn = 'myUrn';
Autodesk.Viewing.Initializer(options, function() {
app = new Autodesk.Viewing.ViewingApplication('viewer');
app.registerViewer(app.k3D, Autodesk.Viewing.Private.GuiViewer3D);
function onDocumentLoadSuccess() {
const viewables = app.bubble.search({ 'type': 'geometry' });
app.selectItem(viewables[0].data);
}
function onDocumentLoadFailure() {}
app.loadDocument('urn:' + urn, onDocumentLoadSuccess, onDocumentLoadFailure);
});
</script>
I want to use light theme but I'm not sure how to do that.
How to set light theme to viewer, please?
Thank you
You can add during inside the Initializer
Autodesk.Viewing.Initializer(options, function onInitialized() {
viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('MyViewerDiv'));
viewer.setTheme("light-theme");
viewer.start();
loadDocument(....)
});
Are you looking for the following API? Just call this method after your viewer is initialized.
/**
* Sets the current UI theme of the viewer.
* Supported values are "light-theme" and "dark-theme", which is the default.
*
* #param {string} name - Name of the theme, it will be added to the viewer's container class list.
*
* #alias Autodesk.Viewing.Viewer3D#setTheme
*/
Viewer3D.prototype.setTheme = function (name) {
};
Modified your code as follow and added one line of code in onItemLoadSuccess() as follow.
viewerApp.myCurrentViewer.setTheme("light-theme");
<script>
var viewerApp;
var options = {
env: 'AutodeskProduction',
getAccessToken: function(onGetAccessToken) {
//
// TODO: Replace static access token string below with call to fetch new token from your backend
// Both values are provided by Forge's Authentication (OAuth) API.
//
// Example Forge's Authentication (OAuth) API return value:
// {
// "access_token": "<YOUR_APPLICATION_TOKEN>",
// "token_type": "Bearer",
// "expires_in": 86400
// }
//
var accessToken = 'mytoken';
var expireTimeSeconds = 60 * 30;
onGetAccessToken(accessToken, expireTimeSeconds);
}
};
let config3d = {
};
var documentId = 'urn:myurn';
Autodesk.Viewing.Initializer(options, function onInitialized(){
viewerApp = new Autodesk.Viewing.ViewingApplication('MyViewerDiv');
viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D, config3d);
viewerApp.loadDocument(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
});
function onDocumentLoadSuccess(doc) {
// We could still make use of Document.getSubItemsWithProperties()
// However, when using a ViewingApplication, we have access to the **bubble** attribute,
// which references the root node of a graph that wraps each object from the Manifest JSON.
var viewables = viewerApp.bubble.search({'type':'geometry'});
if (viewables.length === 0) {
console.error('Document contains no viewables.');
return;
}
// Choose any of the avialble viewables
viewerApp.selectItem(viewables[0].data, onItemLoadSuccess, onItemLoadFail);
}
function onDocumentLoadFailure(viewerErrorCode) {
console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
}
function onItemLoadSuccess(viewer, item) {
console.log('onItemLoadSuccess()!');
viewerApp.myCurrentViewer.setTheme("light-theme");
}
function onItemLoadFail(errorCode) {
console.error('onItemLoadFail() - errorCode:' + errorCode);
}
</script>

How to add Google Drive Picker in Google web app

what I'm trying to do is to show the Google Picker in my Google Web app. I already tried many ways to accomplish that, but nothing works.
At the moment my code looks like this:
WebApp.html
<!-- rest of the code -->
<button type="button" id="pick">Pick File</button>
</div>
<script>
function initPicker() {
var picker = new FilePicker({
apiKey: "####################",
clientId: "##########-##########################",
buttonEl: document.getElementById('pick'),
onSelect: function(file) {
alert('Selected ' + file.title);
} // onSelect
}); // var picker
} // function initPicker()
</script>
<!-- rest of the code -->
WebAppJS.html
/* rest of the code */
var FilePicker = window.FilePicker = function(options) {
this.apiKey = options.apiKey;
this.clientId = options.clientId;
this.buttonEl = options.buttonEl;
this.onSelect = options.onSelect;
this.buttonEl.addEventListener('click', this.open.bind(this));
this.buttonEl.disabled = true;
gapi.client.setApiKey(this.apiKey);
gapi.client.load('drive', 'v2', this._driveApiLoaded.bind(this));
google.load('picker', '1', { callback: this._pickerApiLoaded.bind(this) });
}
FilePicker.prototype = {
open: function() {
var token = gapi.auth.getToken();
if (token) {
this._showPicker();
} else {
this._doAuth(false, function() { this._showPicker(); }.bind(this));
}
},
_showPicker: function() {
var accessToken = gapi.auth.getToken().access_token;
this.picker = new google.picker.PickerBuilder().
addView(google.picker.ViewId.DOCUMENTS).
setAppId(this.clientId).
setOAuthToken(accessToken).
setCallback(this._pickerCallback.bind(this)).
build().
setVisible(true);
},
_pickerCallback: function(data) {
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var file = data[google.picker.Response.DOCUMENTS][0],
id = file[google.picker.Document.ID],
request = gapi.client.drive.files.get({ fileId: id });
request.execute(this._fileGetCallback.bind(this));
}
},
_fileGetCallback: function(file) {
if (this.onSelect) {
this.onSelect(file);
}
},
_pickerApiLoaded: function() {
this.buttonEl.disabled = false;
},
_driveApiLoaded: function() {
this._doAuth(true);
},
_doAuth: function(immediate1, callback) {
gapi.auth.authorize({
client_id: this.clientId + '.apps.googleusercontent.com',
scope: 'https://www.googleapis.com/auth/drive.readonly',
immediate: immediate1
}, callback);
}
}; // FilePicker.prototype
/* rest of the code */
For now, what this code does is showing kind of a popup, but empty. Code is based on Daniel15's code.
What I already tried is:
relocating chunks of code, to server-side and client-side,
using htmlOutput, htmlTemplate - non of those works,
many other things, that i can't exactly remember.
What I would like to get is answer to the question: Why this code doesn't show Google Picker.
Thanks in advance.
Try adding a call origin and developer key
_showPicker: function() {
var accessToken = gapi.auth.getToken().access_token;
this.picker = new google.picker.PickerBuilder()
.addView(google.picker.ViewId.DOCUMENTS)
.setAppId(this.clientId)
.setOAuthToken(accessToken)
.setCallback(this._pickerCallback.bind(this))
.setOrigin('https://script.google.com') //
.setDeveloperKey(BROWSERKEYCREATEDINAPICONSOLE) //
.build()
.setVisible(true);
},

This JS code returns an error for retrieving children in a folder with Google Drive SDK API

The following code returns an error in the chrome console:
Uncaught TypeError: Cannot read property 'children' of undefined
Initial error appeared 5 lines from last script close tag, and at a later point (currently), appears in line 38 of gapi.loaded_0
Combining these two code chunks https://developers.google.com/drive/v2/reference/children/list#examples and https://developers.google.com/drive/web/quickstart/quickstart-js#step_2_set_up_the_sample to get below to list children of a folder
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<script type="text/javascript">
var CLIENT_ID = 'semi-secret-clientIdString.apps.googleusercontent.com';
var SCOPES = 'https://www.googleapis.com/auth/drive';
var thisFolderId = 'folderIdString';
/**
* Called when the client library is loaded to start the auth flow.
*/
function handleClientLoad() {
window.setTimeout(checkAuth, 1);
}
/**
* Check if the current user has authorized the application.
*/
function checkAuth() {
gapi.auth.authorize(
{'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': true},
handleAuthResult);
}
/**
* Called when authorization server replies.
*
* #param {Object} authResult Authorization result.
*/
function handleAuthResult(authResult) {
var authButton = document.getElementById('authorizeButton');
var lister = document.getElementById('Lister');
authButton.style.display = 'none';
lister.style.display = 'none';
if (authResult && !authResult.error) {
// Access token has been successfully retrieved, requests can be sent to the API.
lister.style.display = 'block';
lister.onchange = retrieveAllFilesInFolder(thisFolderId);
} else {
// No access token could be retrieved, show the button to start the authorization flow.
authButton.style.display = 'block';
authButton.onclick = function() {
gapi.auth.authorize(
{'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': false},
handleAuthResult);
};
}
}
///// Start retrieval function
function retrieveAllFilesInFolder(folderId,callback) {
var retrievePageOfChildren = function(request, result) {
request.execute(function(resp) {
result = result.concat(resp.items);
var nextPageToken = resp.nextPageToken;
if (nextPageToken) {
request = gapi.client.drive.children.list({
'folderId' : folderId,
'pageToken': nextPageToken
});
retrievePageOfChildren(request, result);
} else {
callback(result);
}
});
}
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<error on the next line>>>>>>>>>>>>>>>>>>>>>*/
var initialRequest = gapi.client.drive.children.list({
'folderId' : folderId
});
retrievePageOfChildren(initialRequest, []);
}
/////
</script>
<script type="text/javascript" src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
</head>
<body>
<input id="Lister" type="button" value="clickme" style="display: none" />
<input type="button" id="authorizeButton" style="display: none" value="Authorize" />
</body>
</html>