Google Drive API using Javascript
You will learn how to utilise the Google API Drive completely using Javascript programming only. There will be extra javascript libraries such as JQuery and CSS for styling our Google Drive interface screen.

This tutorial will be divided into couple sections as below:

Create your Google Apps project and how to enable the Google API Drive.
Layout the login panel screen and browsing directories and files of your Google Drive.
Adding the functionalities and features like creating folder, uploading and delete file, browse folders, show shared folders and files only, preview images in lightbox, convert uploaded file to google doc or OCR readable, show the user information and add the logout link.
1. Create your Google Apps project and how to enable the Google API Drive.
Before you start, you must have a Gmail account. If you do not have one, please register the free email first. Once you have it, please go to the following site to create a new project for our google drive api example.

https://console.developers.google.com
Once login, go to enable and manage API sectionand click the link.

enable and manage google api
The next step is to create the google apps project. Simply enter the project name and create it.

create new project google app
Once the project is created, the next step is to enable the Google Drive API. By default, this API is not enabled. You will need to search the Drive API from the list and enable this API.

Once you have enabled you will need to create a credential key. Make sure you choose web browser type as your main API call.

create new google api credential
2. Layout the login panel screen and browsing directories and files of your Google Drive.
The next big step is to design the interface of our Google Drive API screen. The screen will consist of two interfaces, one is for the login screen and the second screen will be the Google Drive Browser screen.

This will be our simple login screen, where it will popup a window to Google login page when you click the login button and it will request a permission to our app to access your google api drive.

login to google site
This is going to be our google drive user panel interface. You will see there are some texts represent on how the interface screen looks like.

google drive interface screen
Both login and user screen will be styled using CSS with some free icons. Let’s started with the html interface screen code. Please see the extra libraries such as CSS and Javascript files. There are only 3 files you need to create which are google-drive.html, google-drive.css and google-drive.js, the remaining files are external libraries.

You can copy the following html source code and name it as google-drive.html.

<!DOCTYPE html>
<html>
<head>
<title>How to use Google Drive API using Javascript.</title>
<link href=”lightbox.css” rel=”stylesheet” />
<link href=”google-drive.css” rel=”stylesheet” type=”text/css”/>
</head>
<body>
<!– This will be the transparent wrapper used as a gradient light black screen to show the screen is on progress –>
<div id=”transparent-wrapper”></div>

<!– This popup panel will be used to display the document text–>
<div id=”login-box” class=”hide”>
<p>Please login on your google account.</p>
<button id=”btnLogin” onclick=”handleAuthClick(event)” class=”button”>Login</button>
</div>

<div id=”drive-box” class=”hide”>
<!– This will be the google drive navigation–>
<div id=”drive-breadcrumb”>
<span class=’breadcrumb-arrow’></span> <a data-id=’root’ data-level=’0′>Home</a>
<span id=”span-navigation”></span>
</div>

<!– This popup panel will be used as user information panel–>
<div id=”drive-info” class=”hide”>
<div class=”user-item”>Welcome <span id=”span-name”></span></div>
<div class=”user-item”>Total Quota: <span id=”span-totalQuota”></span></div>
<div class=”user-item”>Used Quota: <span id=”span-usedQuota”></span></div>
<div class=”user-item”>Share Mode: <span id=”span-sharemode”>OFF</span></div>
<div class=”user-item”><a id=”link-logout” class=”logout-link”>Logout</a></div>
</div>

<!– A list of menus available for user to use–>
<div id=”drive-menu”>
<div id=”button-reload” title=”Refresh”></div>
<div id=”button-upload” title=”Upload to Google Drive” class=”button-opt”></div>
<div id=”button-addfolder” title=”Add Folder” class=”button-opt”></div>
<div id=”button-share” title=”Show shared files only”></div>
</div>
<div id=”drive-content”></div>
<div id=”error-message” class=”flash hidden”></div>
<div id=”status-message” class=”flash hidden”></div>
</div>

<!– This upload control is used for uploading file to google drive–>
<input type=”file” id=”fUpload” class=”hide”/>

<!– This popup panel will be used to create folder–>
<div class=”float-box” id=”float-box”>
<div class=”folder-form”>
<div class=”close-x”><img id=”imgClose” class=”imgClose” src=”images/button_close.png” alt=”close” /></div>
<h3 class=”clear”>Add New Folder</h3>
<div><input type=”text” id=”txtFolder” class=”text-input” /></div>
<button id=”btnAddFolder” value=”Save” class=”button”>Add</button>
<button id=”btnClose” value=”Close” class=”button btnClose”>Close</button>
</div>
</div>

<!– This popup panel will be used to display the document/file information –>
<div id=”float-box-info” class=”float-box”>
<div class=”info-form”>
<div class=”close-x”><img id=”imgCloseInfo” class=”imgClose” src=”images/button_close.png” alt=”close” /></div>
<h3 class=”clear”>File information</h3>
<table cellpadding=”0″ cellspacing=”0″ class=”tbl-info”>
<tr>
<td class=”label”>Created Date</td>
<td><span id=”spanCreatedDate”></span></td>
</tr>
<tr>
<td class=”label”>Modified Date</td>
<td><span id=”spanModifiedDate”></span></td>
</tr>
<tr>
<td class=”label”>Owner</td>
<td><span id=”spanOwner”></span></td>
</tr>
<tr>
<td class=”label”>Title</td>
<td><span id=”spanTitle”></span></td>
</tr>
<tr>
<td class=”label”>Size</td>
<td><span id=”spanSize”></span></td>
</tr>
<tr>
<td class=”label”>Extension</td>
<td><span id=”spanExtension”></span></td>
</tr>
</table>
<button id=”btnCloseInfo” value=”Close” class=”button btnClose”>Close</button>
</div>
</div>

<!– This popup panel will be used to display the document text–>
<div id=”float-box-text” class=”float-box”>
<div class=”info-form”>
<div class=”close-x”><img id=”imgCloseText” class=”imgClose” src=”images/button_close.png” alt=”close” /></div>
<h3 class=”clear”>Text Content</h3>
<div id=”text-content”></div>
<button id=”btnCloseText” value=”Close” class=”button btnClose”>Close</button>
</div>
</div>

<!– This iframe is used for logout–>
<iframe id=”frameLogout” class=”hide”></iframe>
<script src=”https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js”></script>
<script src=”date.js” type=”text/javascript”></script>
<script src=”lightbox.min.js” type=”text/javascript”></script>
<script src=”google-drive.js”></script>
<script src=”https://apis.google.com/js/client.js?onload=checkAuth”></script>
<script src=”upload.js”></script>

</body>
</html>
If you see carefully on the html source code, you can see that I have included a hide class. This class is intended to hide the login and user interface panel when the page loads. All the html code is pretty straight forward. The float-box panel will be hidden by default, it will be used when you click the button and it will be displayed as a popup.

The frame will be used for logout. Unfortunately there is no javascript function written in Google Drive documentation about this. So we can set the logout url manually in the frame source to force logout manually. For upload progress, we have to use external upload file known as MediaUploader as there is no documentation available on google api to show the progress of uploading a file.

The next part is the JavaScript code. I have included the comment on each function sub heading. You can name this file as google-drive.js

/******************** GLOBAL VARIABLES ********************/
var SCOPES = [‘https://www.googleapis.com/auth/drive’,’profile’];
var CLIENT_ID = ‘ENTER YOUR CLIENT ID HERE’;
var FOLDER_NAME = “”;
var FOLDER_ID = “root”;
var FOLDER_PERMISSION = true;
var FOLDER_LEVEL = 0;
var NO_OF_FILES = 1000;
var DRIVE_FILES = [];
var FILE_COUNTER = 0;
var FOLDER_ARRAY = [];

/******************** AUTHENTICATION ********************/
function checkAuth() {
gapi.auth.authorize({
‘client_id’: CLIENT_ID,
‘scope’: SCOPES.join(‘ ‘),
‘immediate’: true
}, handleAuthResult);
}

//authorize apps
function handleAuthClick(event) {
gapi.auth.authorize(
{ client_id: CLIENT_ID, scope: SCOPES, immediate: false },
handleAuthResult);
return false;
}

//check the return authentication of the login is successful, we display the drive box and hide the login box.
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
$(“#drive-box”).css(“display”, “inline-block”);
$(“#login-box”).hide();
showLoading();
getDriveFiles();
} else {
$(“#login-box”).show();
$(“#drive-box”).hide();
}
}
/******************** END AUTHENTICATION ********************/
/******************** PAGE LOAD ********************/
$(function(){
//initiate to reload the google drive files
$(“#button-reload”).click(function () {
showLoading();
showStatus(“Loading Google Drive files…”);
getDriveFiles();
});

//Initiate the upload button.
$(“#button-upload”).click(function () {
$(“#fUpload”).click();
});

//If user has selected a file
$(“#fUpload”).bind(“change”, function () {
var uploadObj = $(“[id$=fUpload]”);
showLoading();
showStatus(“Uploading file in progress…”);
var file = uploadObj.prop(“files”)[0];
var metadata = {
‘title’: file.name,
‘description’: “bytutorial.com File Upload”,
‘mimeType’: file.type || ‘application/octet-stream’,
“parents”: [{
“kind”: “drive#file”,
“id”: FOLDER_ID
}]
};
var arrayBufferView = new Uint8Array(file);
var uploadData = new Blob(arrayBufferView, {type: file.type || ‘application/octet-stream’});
showProgressPercentage(0);

try{
var uploader =new MediaUploader({
file: file,
token: gapi.auth.getToken().access_token,
metadata: metadata,
onError: function(response){
showErrorMessage(“Error: ” + response.error.message);
$(“#fUpload”).val(“”);
getDriveFiles();
},
onComplete: function(response){
hideStatus();
$(“#upload-percentage”).hide(1000);
if(response.error != null){
showErrorMessage(“Error: ” + response.error.message);
$(“#fUpload”).val(“”);
getDriveFiles();
}else{
showStatus(“Loading Google Drive files…”);
getDriveFiles();
}
},
onProgress: function(event) {
showProgressPercentage(Math.round(((event.loaded/event.total)*100), 0));
},
params: {
convert:false,
ocr: true
}
});
uploader.upload();
}catch(exc){
showErrorMessage(“Error: ” + exc);
$(“#fUpload”).val(“”);
getDriveFiles();
}
});

//initiate the share files button
$(“#button-share”).click(function () {
FOLDER_NAME = “”;
FOLDER_ID = “root”;
FOLDER_LEVEL = 0;
FOLDER_ARRAY = [];
$(“#span-navigation”).html(“”);
$(this).toggleClass(“flash”);
if($(this).attr(“class”).indexOf(“flash”) >= 0){
$(“#span-sharemode”).html(“ON”);
}else{
$(“#span-sharemode”).html(“OFF”);
}
showLoading();
showStatus(“Loading Google Drive files…”);
getDriveFiles();
});

//initiate the add folder button. Click this button will popup a window for user to enter the folder name.
$(“#button-addfolder”).click(function () {
$(“#transparent-wrapper”).show();
$(“#float-box”).show();
$(“#txtFolder”).val(“”);
});

//This button will be used to send a request to add a folder to Google API site
$(“#btnAddFolder”).click(function () {
if ($(“#txtFolder”).val() == “”) {
alert(“Please enter the folder name”);
} else {
$(“#transparent-wrapper”).hide();
$(“#float-box”).hide();
showLoading();
showStatus(“Creating folder in progress…”);
var access_token = gapi.auth.getToken().access_token;
var request = gapi.client.request({
‘path’: ‘/drive/v2/files/’,
‘method’: ‘POST’,
‘headers’: {
‘Content-Type’: ‘application/json’,
‘Authorization’: ‘Bearer ‘ + access_token,
},
‘body’:{
“title” : $(“#txtFolder”).val(),
“mimeType” : “application/vnd.google-apps.folder”,
“parents”: [{
“kind”: “drive#file”,
“id”: FOLDER_ID
}]
}
});

request.execute(function(resp) {
if (!resp.error) {
showStatus(“Loading Google Drive files…”);
getDriveFiles();
}else{
hideStatus();
hideLoading();
showErrorMessage(“Error: ” + resp.error.message);
}
});
}
});

//Initiate the close button to hide popup box and transparent gradient wrapper
$(“.btnClose, .imgClose”).click(function () {
$(“#transparent-wrapper”).hide();
$(“.float-box”).hide();
});

//Initiate button to logout the user by specifying the frame source, this will force the logout.
$(“#link-logout”).click(function () {
var c = confirm(“Are you sure you want to logout from your Google Drive account?”);
if (c) {
$(‘#frameLogout’).attr(“src”,”https://accounts.google.com/logout”);
showLoading();
setTimeout(function () {
$(“#login-panel”).show();
$(“#drive-ouput”).hide();
}, 1000);
}
});

});

/******************** END PAGE LOAD ********************/

/******************** DRIVER API ********************/
function getDriveFiles(){
showStatus(“Loading Google Drive files…”);
gapi.client.load(‘drive’, ‘v2’, getFiles);
}

//This will get the files information
function getFiles(){
var query = “”;
if (ifShowSharedFiles()) {
$(“.button-opt”).hide();
query = (FOLDER_ID == “root”) ? “trashed=false and sharedWithMe” : “trashed=false and ‘” + FOLDER_ID + “‘ in parents”;
if (FOLDER_ID != “root” && FOLDER_PERMISSION == “true”) {
$(“.button-opt”).show();
}
}else{
$(“.button-opt”).show();
query = “trashed=false and ‘” + FOLDER_ID + “‘ in parents”;
}
var request = gapi.client.drive.files.list({
‘maxResults’: NO_OF_FILES,
‘q’: query
});

request.execute(function (resp) {
if (!resp.error) {
showUserInfo();
DRIVE_FILES = resp.items;
buildFiles();
}else{
showErrorMessage(“Error: ” + resp.error.message);
}
});
}

//This will show the user information
function showUserInfo(){
var request = gapi.client.drive.about.get();
var obj = {};
request.execute(function(resp) {
if (!resp.error) {
$(“#drive-info”).show();
$(“#span-name”).html(resp.name);
$(“#span-totalQuota”).html(formatBytes(resp.quotaBytesTotal));
$(“#span-usedQuota”).html(formatBytes(resp.quotaBytesUsed));
}else{
showErrorMessage(“Error: ” + resp.error.message);
}
});
}

//This will build the user information
function buildFiles(){
var fText = “”;
if (DRIVE_FILES.length > 0) {
for (var i = 0; i < DRIVE_FILES.length; i++) {
DRIVE_FILES[i].textContentURL = “”;
DRIVE_FILES[i].level = (parseInt(FOLDER_LEVEL) + 1).toString();
DRIVE_FILES[i].parentID = (DRIVE_FILES[i].parents.length > 0) ? DRIVE_FILES[i].parents[0].id : “”;
DRIVE_FILES[i].thumbnailLink = DRIVE_FILES[i].thumbnailLink || ”;
DRIVE_FILES[i].fileType = (DRIVE_FILES[i].fileExtension == null) ? “folder” : “file”;
DRIVE_FILES[i].permissionRole = DRIVE_FILES[i].userPermission.role;
DRIVE_FILES[i].hasPermission = (DRIVE_FILES[i].permissionRole == “owner” || DRIVE_FILES[i].permissionRole == “writer”);
var textContentURL = ”;
if(DRIVE_FILES[i][‘exportLinks’] != null){
DRIVE_FILES[i].fileType = “file”;
DRIVE_FILES[i].textContentURL = DRIVE_FILES[i][‘exportLinks’][‘text/plain’];
}
var textTitle = (DRIVE_FILES[i].fileType != “file”) ? “Browse ” + DRIVE_FILES[i].title : DRIVE_FILES[i].title;

fText += “<div class='” + DRIVE_FILES[i].fileType + “-box’>”;
if (DRIVE_FILES[i].fileType != “file”) {
fText += “<div class=’folder-icon’ data-level='” + DRIVE_FILES[i].level + “‘ data-parent='” + DRIVE_FILES[i].parentID + “‘ data-size='” + DRIVE_FILES[i].fileSize + “‘ data-id='” + DRIVE_FILES[i].id + “‘ title='” + textTitle + “‘ data-name='” + DRIVE_FILES[i].title + “‘ data-has-permission='” +DRIVE_FILES[i].hasPermission + “‘><div class=’image-preview’><img src=’images/folder.png’/></div></div>”;
} else {
if (DRIVE_FILES[i].thumbnailLink) {
fText += “<div class=’image-icon’><div class=’image-preview’><a href='” + DRIVE_FILES[i].thumbnailLink.replace(“s220”, “s800”) + “‘ data-lightbox=’image-” + i + “‘><img src='” + DRIVE_FILES[i].thumbnailLink + “‘/></a></div></div>”;
}else {
fText += “<div class=’file-icon’><div class=’image-preview’><img src=’images/” + DRIVE_FILES[i].fileExtension + “-icon.png” + “‘/></div></div>”;
}
}
fText += “<div class=’item-title’>” + DRIVE_FILES[i].title + “</div>”;

//button actions
fText += “<div class=’button-box’>”;
if (DRIVE_FILES[i].fileType != “folder”) {
fText += “<div class=’button-download’ title=’Download’ data-id='” + DRIVE_FILES[i].id + “‘ data-file-counter='” + i + “‘></div>”;
}

if (DRIVE_FILES[i].textContentURL.length > 0) {
fText += “<div class=’button-text’ title=’Get Text’ data-id='” + DRIVE_FILES[i].id + “‘ data-file-counter='” + i + “‘></div>”;
}

fText += “<div class=’button-info’ title=’Info’ data-id='” + DRIVE_FILES[i].id + “‘ data-file-counter='” + i + “‘></div>”;

if (DRIVE_FILES[i].hasPermission) {
if (DRIVE_FILES[i].permissionRole == “owner”) {
fText += “<div class=’button-delete’ title=’Delete’ data-id='” + DRIVE_FILES[i].id + “‘></div>”;
}else if(DRIVE_FILES[i].fileType != “folder”){
fText += “<div class=’button-delete’ title=’Delete’ data-id='” + DRIVE_FILES[i].id + “‘></div>”;
}
}

fText += “</div>”;

//closing div
fText += “</div>”;
}
} else {
fText = ‘No files found.’;
}
hideStatus();
$(“#drive-content”).html(fText);
initDriveButtons();
hideLoading();
}

//Initialize the click button for each individual drive file/folder
//this need to be recalled everytime the Google Drive data is generated
function initDriveButtons(){
//Initiate the delete button click
$(“.button-delete”).unbind(“click”);
$(“.button-delete”).click(function () {
var c = confirm(“Are you sure you want to delete this?”);
if (c) {
showLoading();
showStatus(“Deleting file in progress…”);
var request = gapi.client.drive.files.delete({
‘fileId’: $(this).attr(“data-id”)
});

request.execute(function(resp) {
hideStatus();
if (resp.error) {
showErrorMessage(“Error: ” + resp.error.message);
}
getDriveFiles();
});
}
});

//Initiate the download button
$(“.button-download”).unbind(“click”);
$(“.button-download”).click(function () {
showLoading();
showStatus(“Downloading file in progress…”);
FILE_COUNTER = $(this).attr(“data-file-counter”);
setTimeout(function () {
//If there is a text version, we get this version instead.
if(DRIVE_FILES[FILE_COUNTER].webContentLink == null){
window.open(DRIVE_FILES[FILE_COUNTER][‘exportLinks’][‘text/plain’]);
}else{
window.open(DRIVE_FILES[FILE_COUNTER].webContentLink);
}
hideLoading();
hideStatus();
}, 1000);
});

$(“.button-info”).unbind(“click”);
$(“.button-info”).click(function () {
FILE_COUNTER = $(this).attr(“data-file-counter”);
$(“#transparent-wrapper”).show();
$(“#float-box-info”).show();
if (DRIVE_FILES[FILE_COUNTER] != null) {
var createdDate = new Date(DRIVE_FILES[FILE_COUNTER].createdDate);
var modifiedDate = new Date(DRIVE_FILES[FILE_COUNTER].modifiedDate);
$(“#spanCreatedDate”).html(createdDate.toString(“dddd, d MMMM yyyy h:mm:ss tt”));
$(“#spanModifiedDate”).html(modifiedDate.toString(“dddd, d MMMM yyyy h:mm:ss tt”));
$(“#spanOwner”).html((DRIVE_FILES[FILE_COUNTER].owners[0].displayName.length > 0) ? DRIVE_FILES[FILE_COUNTER].owners[0].displayName : “”);
$(“#spanTitle”).html(DRIVE_FILES[FILE_COUNTER].title);
$(“#spanSize”).html((DRIVE_FILES[FILE_COUNTER].fileSize == null) ? “N/A” : formatBytes(DRIVE_FILES[FILE_COUNTER].fileSize));
$(“#spanExtension”).html(DRIVE_FILES[FILE_COUNTER].fileExtension);
}
});

//Initiate the get text button
$(“.button-text”).unbind(“click”);
$(“.button-text”).click(function () {
FILE_COUNTER = $(this).attr(“data-file-counter”);
showLoading();
showStatus(“Getting text file in progress…”);
var accessToken = gapi.auth.getToken().access_token;
var xhr = new XMLHttpRequest();
xhr.open(‘GET’, DRIVE_FILES[FILE_COUNTER][‘exportLinks’][‘text/plain’]);
xhr.setRequestHeader(‘Authorization’, ‘Bearer ‘ + accessToken);
xhr.onload = function() {
callBackGetText(xhr.responseText);
};
xhr.onerror = function() {
callBackGetText(null);
};
xhr.send();
});

//Initiate the click folder browse icon
$(“.folder-icon”).unbind(“click”);
$(“.folder-icon”).click(function () {
browseFolder($(this));
});

//Initiate the breadcrumb navigation link click
$(“#drive-breadcrumb a”).unbind(“click”);
$(“#drive-breadcrumb a”).click(function () {
browseFolder($(this));
});
}
//browse folder
function browseFolder(obj) {
FOLDER_ID = $(obj).attr(“data-id”);
FOLDER_NAME = $(obj).attr(“data-name”);
FOLDER_LEVEL = parseInt($(obj).attr(“data-level”));
FOLDER_PERMISSION = $(obj).attr(“data-has-permission”);

if (typeof FOLDER_NAME === “undefined”) {
FOLDER_NAME = “”;
FOLDER_ID = “root”;
FOLDER_LEVEL = 0;
FOLDER_PERMISSION = true;
FOLDER_ARRAY = [];
} else {
if (FOLDER_LEVEL == FOLDER_ARRAY.length && FOLDER_LEVEL > 0) {
//do nothing
} else if (FOLDER_LEVEL < FOLDER_ARRAY.length) {
var tmpArray = cloneObject(FOLDER_ARRAY);
FOLDER_ARRAY = [];

for (var i = 0; i < tmpArray.length; i++) {
FOLDER_ARRAY.push(tmpArray[i]);
if (tmpArray[i].Level >= FOLDER_LEVEL) { break; }
}
} else {
var fd = {
Name: FOLDER_NAME,
ID: FOLDER_ID,
Level: FOLDER_LEVEL,
Permission: FOLDER_PERMISSION
}
FOLDER_ARRAY.push(fd);
}
}

var sbNav = “”;
for (var i = 0; i < FOLDER_ARRAY.length; i++) {
sbNav +=”<span class=’breadcrumb-arrow’></span>”;
sbNav +=”<span class=’folder-name’><a data-id='” + FOLDER_ARRAY[i].ID + “‘ data-level='” + FOLDER_ARRAY[i].Level + “‘ data-name='” + FOLDER_ARRAY[i].Name + “‘ data-has-permission='” + FOLDER_PERMISSION + “‘>” + FOLDER_ARRAY[i].Name + “</a></span>”;
}
$(“#span-navigation”).html(sbNav.toString());

showLoading();
showStatus(“Loading Google Drive files…”);
getDriveFiles();
}

//call back function for getting text
function callBackGetText(response){
if(response == null){
showErrorMessage(“Error getting text content.”);
}else{
hideLoading();
hideStatus();
$(“#transparent-wrapper”).show();
$(“#float-box-text”).show();
$(“#text-content”).html(response.replace(/(\r\n|\n|\r)/gm, “<br>”));
}
}

//function to clone an object
function cloneObject(obj) {
if (obj === null || typeof obj !== ‘object’) {
return obj;
}
var temp = obj.constructor();
for (var key in obj) {
temp[key] = cloneObject(obj[key]);
}
return temp;
}

//show whether the display mode is share files or not
function ifShowSharedFiles() {
return ($(“#button-share.flash”).length > 0) ? true : false;
}

//function to return bytes into different string data format
function formatBytes(bytes) {
if (bytes < 1024) return bytes + ” Bytes”;
else if (bytes < 1048576) return (bytes / 1024).toFixed(3) + ” KB”;
else if (bytes < 1073741824) return (bytes / 1048576).toFixed(3) + ” MB”;
else return (bytes / 1073741824).toFixed(3) + ” GB”;
};

/******************** END DRIVER API ********************/

/******************** NOTIFICATION ********************/
//show loading animation
function showLoading() {
if ($(“#drive-box-loading”).length === 0) {
$(“#drive-box”).prepend(“<div id=’drive-box-loading’></div>”);
}
$(“#drive-box-loading”).html(“<div id=’loading-wrapper’><div id=’loading’><img src=’images/loading-bubble.gif’></div></div>”);
}

//hide loading animation
function hideLoading() {
$(“#drive-box-loading”).html(“”);
}

//show status message
function showStatus(text) {
$(“#status-message”).show();
$(“#status-message”).html(text);
}

//hide status message
function hideStatus() {
$(“#status-message”).hide();
$(“#status-message”).html(“”);
}

//show upload progress
function showProgressPercentage(percentageValue) {
if ($(“#upload-percentage”).length == 0) {
$(“#drive-box”).prepend(“<div id=’upload-percentage’ class=’flash’></div>”);
}
if (!$(“#upload-percentage”).is(“:visible”)) {
$(“#upload-percentage”).show(1000);
}
$(“#upload-percentage”).html(percentageValue.toString() + “%”);
}

//show error message
function showErrorMessage(errorMessage) {
$(“#error-message”).html(errorMessage);
$(“#error-message”).show(100);
setTimeout(function () {
$(“#error-message”).hide(100);
}, 3000);
}

/******************** END NOTIFICATION ********************/
Understanding the JavaScript code.
Let’s review the following code. In the first couple lines, we can see I have declared a list of global variables. Those global variables will be shared across the functions. There are two variables you need to review them carefully. The first one is the SCOPES. This identifies what type of permission you want to give the app to access your google drive. In this example, we give full permission where the app can perform mostly everything. The second variable is CLIENT_ID, this is a key generated when you create your new project app. Make sure when you create your new project, you enter the correct URL that is match with your site URL. If you want to do a testing URL, you can add more than one.

Access SCOPES definition.
Please see the following table consist of available scopes.

Scope Description
https://www.googleapis.com/auth/drive Full permissive scope to access all of a user’s files. Request this scope only when it is strictly necessary. Tokens with scope https://docs.google.com/feeds are accepted and treated the same as tokens with scope https://www.googleapis.com/auth/drive.
https://www.googleapis.com/auth/drive.readonly Allows read-only access to file metadata and file content
https://www.googleapis.com/auth/drive.appfolder Allows access to the Application Data folder
https://www.googleapis.com/auth/drive.apps.readonly Allows apps read-only access to the list of Drive apps a user has installed.
https://www.googleapis.com/auth/drive.file Per-file access to files created or opened by the app
https://www.googleapis.com/auth/drive.install Special scope used to let users approve installation of an app.
https://www.googleapis.com/auth/drive.metadata Allows read-write access to file metadata, but does not allow any access to read, download, write or upload file content. Does not support file creation, trashing or deletion. Also does not allow changing folders or sharing in order to prevent access escalation.
https://www.googleapis.com/auth/drive.metadata.readonly Allows read-only access to file metadata, but does not allow any access to read or download file content
https://www.googleapis.com/auth/drive.photos.readonly Allows read-only access to all photos. The spaces parameter must be set to photos.
https://www.googleapis.com/auth/drive.scripts Allows access to Apps Script files
How does the authentication work?
The authentication start working out when we load the following javascript file.

https://apis.google.com/js/client.js?onload=checkAuth
On the last line of the query string, you can see that after a complete load of the script, it will call a function named checkAuth. This checkAuth function will call google api function to start authenticating the user by specifying the scope and client id information. Once we get the result back, we can identify whether the user has already authenticated on the browser. If they haven’t then we load the login box. The panel for login will have an id named login-box while for the drive files content will have an id of drive-box.

Most of the codes will have a comment heading on it, if you need further help, just drop your question in the comment form.
/******************** GLOBAL VARIABLES ********************/
var SCOPES = [‘https://www.googleapis.com/auth/drive’,’profile’];
var CLIENT_ID = ‘ENTER YOUR CLIENT ID HERE’;
var FOLDER_NAME = “”;
var FOLDER_ID = “root”;
var FOLDER_PERMISSION = true;
var FOLDER_LEVEL = 0;
var NO_OF_FILES = 1000;
var DRIVE_FILES = [];
var FILE_COUNTER = 0;
var FOLDER_ARRAY = [];

/******************** AUTHENTICATION ********************/
function checkAuth() {
gapi.auth.authorize({
‘client_id’: CLIENT_ID,
‘scope’: SCOPES.join(‘ ‘),
‘immediate’: true
}, handleAuthResult);
}

//authorize apps
function handleAuthClick(event) {
gapi.auth.authorize(
{ client_id: CLIENT_ID, scope: SCOPES, immediate: false },
handleAuthResult);
return false;
}

//check the return authentication of the login is successful, we display the drive box and hide the login box.
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
$(“#drive-box”).css(“display”, “inline-block”);
$(“#login-box”).hide();
$(“#drive-box”).removeClass(“hide”);
showLoading();
getDriveFiles();
} else {
$(“#login-box”).show();
$(“#drive-box”).hide();
$(“#login-box”).removeClass(“hide”);
}
}
/******************** END AUTHENTICATION ********************/
<script src=”https://apis.google.com/js/client.js?onload=checkAuth”></script>
This will be the css code, you can name this to google-drive.css.

body{
font-family:arial;
font-size:11px;
}
/*************** Google Login Box ***************/
#login-box{
max-width:300px;
border-radius:5px;
border:solid 1px #ccc;
padding:10px;
background:#f0f9d7;
}
/*************** END Google Login Box ***************/

/*************** Google Drive Breadcrumb ***************/
#drive-breadcrumb{
font-size:11px;
}

#drive-breadcrumb a{
cursor:pointer;
}

.breadcrumb-arrow{
background:url(images/arrow_right.png) no-repeat 0 3px;
display:inline-block;
height:16px;
width:11px;
}
/*************** END Google Drive Breadcrumb ***************/

/*************** Google Drive Box ***************/
#transparent-wrapper
{
display: none;
position: fixed;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: #000;
z-index: 1001;
-moz-opacity: 0.35;
opacity: .35;
filter: alpha(opacity=35);
}

#drive-box{
padding:10px;
margin:10px;
border:solid 1px #ccc;
width:98%;
box-sizing: border-box;
display:none;
position:relative;
min-height:150px;
margin-top:60px;
}

#drive-content{
clear:both;
}

.folder-box, .file-box {
float:left;
font-family:Arial;
width:150px;
height:150px;
text-align:center;
padding:10px;
margin:10px;
border:solid 1px #edeae9;
-webkit-box-shadow: 7px 9px 5px -6px rgba(0,0,0,0.75);
-moz-box-shadow: 7px 9px 5px -6px rgba(0,0,0,0.75);
box-shadow: 7px 9px 5px -6px rgba(0,0,0,0.75);
border-radius:5px;
}

.image-preview{
text-align:center;
height:80px;
}

.image-preview img{
max-width:45%;
cursor:pointer;
}

.item-title {
padding-top:10px;
word-wrap: break-word;
width:150px;
text-align:center;
font-size:11px;
margin-bottom:10px;
}

#drive-menu{
float:right;
display:inline-block;
}

#drive-menu div:hover{
background-color:#fafccc;
border:solid 1px #000;
}

#button-reload, #button-share, #button-addfolder, #button-upload{
width:24px;
height:24px;
display:block;
cursor:pointer;
margin-right:5px;
float:left;
border:Solid 1px #fae8e4;
border-radius:5px;
}

#button-reload {
background:url(images/button_reload.png) no-repeat;
}

#button-share {
background:url(images/button_share.png) no-repeat;
}

#button-share.flash{
background-color:#dbeb2d;
}

#button-addfolder {
background:url(images/button_addfolder.png) no-repeat;
}

#button-upload {
background:url(images/button_upload.png) no-repeat;
}

.button-box{
padding-top:10px;
}

.button-delete, .button-info, .button-download, .button-text{
width:20px;
height:20px;
display:inline-block;
cursor:pointer;
margin-right:5px;
}

.button-delete {
background:url(images/button_delete.png) no-repeat;
}

.button-info {
background:url(images/button_info.png) no-repeat;
}

.button-download {
background:url(images/button_download.png) no-repeat;
}

.button-text {
background:url(images/button_text.png) no-repeat;
}

/*************** END Google Drive Box ***************/

/************* User Drive Information **************/
#user-info
{
position:absolute;
height:100px;
right:0;
width:200px;
margin-top:-110px;
background:#338daf;
z-index:99999999;
color:#fff;
padding:5px;
box-sizing: border-box;
text-align:right;
font-size:11px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}

.user-item
{
padding-bottom:4px;
}

#drive-info{
position:absolute;
height:90px;
right:0;
width:200px;
margin-top:-120px;
background:#338daf;
z-index:99999999;
color:#fff;
padding:5px;
box-sizing: border-box;
text-align:right;
font-size:11px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
/************* END User Drive Information **************/

/************* FLOATING BOX *********************/
.float-box{
border-radius:0px;
-webkit-box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);
-moz-box-shadow:7px 7px 5px rgba(50, 50, 50, 0.75);
box-shadow:7px 7px 5px rgba(50, 50, 50, 0.75);
width:400px;
padding:7px 15px;
border:solid 1px #ccc;
position:fixed;
left:50%;
margin-left:-200px;
top:35%;
z-index:1000000;
background-color:#fff;
display:none;
}

.close-x{
float:right;
display:inline-block;
cursor:pointer;
}

.tbl-info{
border-left:solid 1px #ccc;
border-top:solid 1px #ccc;
margin-bottom:10px;
width:100%;
}

.tbl-info td{
border-right:solid 1px #ccc;
border-bottom:solid 1px #ccc;
padding:5px 10px;
font-size:11px;
}

.tbl-info td.label{
background:#5f5d5c;
color:#fff;
text-align:right;
width:50%;
}

#text-content
{
margin-bottom:10px;
overflow-y:auto;
overflow-x:hidden;
height:180px;
border:solid 1px #ccc;
}

.text-input{
width:90%;
padding:5px;
border-radius:5px;
margin-bottom:10px;
}
/************* END FLOATING BOX *********************/

/*************** NOTIFICATION ******************/
#loading-wrapper{
width:100%;
height:100%;
background:#000;
-moz-opacity: 0.25;
opacity: .25;
filter: alpha(opacity=25);
top:0;
left:0;
position:absolute;
}

#loading{
position:absolute;
left:50%;
top:50%;
margin-left:-60px;
margin-top:-60px;
width:120px;
}

#status-message{
border:solid 1px #fbfbd4;
background:#fbfbd4;
border-radius:5px;
padding:5px;
position:absolute;
right:10px;
bottom:10px;
z-index:9999999999;
}

#error-message{
border:solid 1px #f2fcb9;
background:#d83813;
border-radius:5px;
color:#fff;
padding:10px;
position:absolute;
left:10px;
bottom:10px;
z-index:9999999999;
max-width:400px;
border-radius:5px;
display:none;
}

#upload-percentage{
position:absolute;
left:50%;
top:50%;
margin-left:-25px;
margin-top:-100px;
width:50px;
height:50px;
border-radius: 50%;
background:#297ab8;
color:#fff;
text-align:center;
line-height:50px;
font-weight:bold;
font-size:15px;
display:none;
}
/*************** END NOTIFICATION ******************/

/***************** MISC ************************/
.button {
background: #3498db;
background-image: -webkit-linear-gradient(top, #3498db, #2980b9);
background-image: -moz-linear-gradient(top, #3498db, #2980b9);
background-image: -ms-linear-gradient(top, #3498db, #2980b9);
background-image: -o-linear-gradient(top, #3498db, #2980b9);
background-image: linear-gradient(to bottom, #3498db, #2980b9);
border:none;
-webkit-border-radius: 8;
-moz-border-radius: 8;
border-radius: 8px;
font-family: Arial;
color: #ffffff;
font-size: 11px;
padding: 5px 10px;
text-decoration: none;
cursor:pointer;
}

.button:hover {
background: #3cb0fd;
background-image: -webkit-linear-gradient(top, #3cb0fd, #3498db);
background-image: -moz-linear-gradient(top, #3cb0fd, #3498db);
background-image: -ms-linear-gradient(top, #3cb0fd, #3498db);
background-image: -o-linear-gradient(top, #3cb0fd, #3498db);
background-image: linear-gradient(to bottom, #3cb0fd, #3498db);
text-decoration: none;
border:none;
}

.hide{
display:none;
}

.flash {
-webkit-animation-name: flash;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;

-moz-animation-name: flash;
-moz-animation-duration: 1s;
-moz-animation-timing-function: linear;
-moz-animation-iteration-count: infinite;

animation-name: flash;
animation-duration: 1s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}

@-moz-keyframes flash {
0% { opacity: 1.0; }
50% { opacity: 0.5; }
100% { opacity: 1.0; }
}

@-webkit-keyframes flash {
0% { opacity: 1.0; }
50% { opacity: 0.5; }
100% { opacity: 1.0; }
}

@keyframes flash {
0% { opacity: 1.0; }
50% { opacity: 0.5; }
100% { opacity: 1.0; }
}

/***************** END MISC ************************/