You will learn how to utilize 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 section and click the link.
The next step is to create the google apps project. Simply enter the project name and create it.
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 the Google Drive API, we then need to create the Oauth Client ID. Under the credential tab, there is an option called Create Credentials. Choose the option Oauth Client ID.
Please make sure you enter the correct javascript origins. If you are working in localhost, you enter localhost url as the address. If you are using any ports on your address, do not forget to add it as well.
Once you have setup your url origins, you are ready to go. When you download the demo files from this page, remember to change your client id you created under your account.
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.
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.
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> <head> <title>Google Drive API Javascript tutorial</title> <link href="lightbox.css" rel="stylesheet" /> <link href="google-drive.css" rel="stylesheet" type="text/css"/> </head> <body> <div id="transparent-wrapper"></div> <div id="login-box" class="hide"> <p>Please login on your google account.</p> <button id="btnLogin" onclick="handleAuthClick()" class="button">Login</button> </div> <div id="drive-box" class="hide"> <div id="drive-breadcrumb"> <span class='breadcrumb-arrow'></span> <a data-id='root' data-level='0'>Home</a> <span id="span-navigation"></span> </div> <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" onclick="handleSignoutClick()">Logout</a></div> </div> <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> <input type="file" id="fUpload" class="hide"/> <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> <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> <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> <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 async defer src="https://apis.google.com/js/api.js" onload="this.onload=function(){};handleClientLoad()" onreadystatechange="if (this.readyState === 'complete') this.onload()"> </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 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 = 'YOUR_CLIENT_ID.apps.googleusercontent.com'; var API_KEY = 'YOUR_API_KEY'; 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 handleClientLoad() { // Load the API client and auth2 library gapi.load('client:auth2', initClient); } //authorize apps function initClient() { gapi.client.init({ apiKey: API_KEY, //THIS IS OPTIONAL AND WE DONT ACTUALLY NEED THIS, BUT I INCLUDE THIS AS EXAMPLE clientId: CLIENT_ID, scope: SCOPES.join(' ') }).then(function () { // Listen for sign-in state changes. gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus); // Handle the initial sign-in state. updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get()); }); } //check the return authentication of the login is successful, we display the drive box and hide the login box. function updateSigninStatus(isSignedIn) { if (isSignedIn) { $("#drive-box").show(); $("#drive-box").css("display","inline-block"); $("#login-box").hide(); showLoading(); getDriveFiles(); } else { $("#login-box").show(); $("#drive-box").hide(); } } function handleAuthClick(event) { gapi.auth2.getAuthInstance().signIn(); } function handleSignoutClick(event) { if(confirm("Are you sure you want to logout?")){ gapi.auth2.getAuthInstance().signOut(); } } /******************** END AUTHENTICATION ********************/ /******************** PAGE LOAD ********************/ $(function(){ $("#button-reload").click(function () { showLoading(); showStatus("Loading Google Drive files..."); getDriveFiles(); }); $("#button-upload").click(function () { $("#fUpload").click(); }); $("#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 }] }; //if user upload an empty content, create a temp blob with a space content on it. if(file.size <= 0){ var emptyContent = " "; file = new Blob([emptyContent], {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){ var errorResponse = JSON.parse(response); showErrorMessage("Error: " + errorResponse.error.message); $("#fUpload").val(""); $("#upload-percentage").hide(1000); getDriveFiles(); }, onComplete: function(response){ hideStatus(); $("#upload-percentage").hide(1000); var errorResponse = JSON.parse(response); if(errorResponse.message != null){ showErrorMessage("Error: " + errorResponse.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: false } }); uploader.upload(); }catch(exc){ showErrorMessage("Error: " + exc); $("#fUpload").val(""); getDriveFiles(); } }); $("#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(); }); $("#button-addfolder").click(function () { $("#transparent-wrapper").show(); $("#float-box").show(); $("#txtFolder").val(""); }); $("#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); } }); } }); $(".btnClose, .imgClose").click(function () { $("#transparent-wrapper").hide(); $(".float-box").hide(); }); }); /******************** END PAGE LOAD ********************/ /******************** DRIVER API ********************/ function getDriveFiles(){ showStatus("Loading Google Drive files..."); gapi.client.load('drive', 'v2', getFiles); } 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); } }); } 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); } }); } 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 != null && 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 ************************/
Google API Drive demo files
Please click here to download the demo file.
If you have any question, feel free to leave your comment below.