The week before Google I/O, we launched Google Developers Live, a new online channel to connect us with developers from all around the world, all year round.
Google Developers Live features interactive broadcasts about many different products and with many different formats. For Google Drive and Apps Script alone, we have aired app reviews, presentations about Google Drive and Apps Script, question and answer sessions, and a doc feedback session.
We are really interested in knowing from you about your favorite shows. Which types of event would you like to see more of in the future? Are you more interested in introductory material such as getting started tutorials, or more advanced topics?
Please share your feedback with us by adding a comment to this post or by reaching out to us on Google+.
Remember, we go live every Monday and Thursday and our complete schedule can be found at https://developers.google.com/live/drive. See all of you on Google Developers Live!
Three months ago, we launched Google Drive along with the Google Drive SDK. The SDK allows applications to manage files that users have uploaded to Drive and to integrate deeply in the Google Drive UI. Today, we’ve just extended the SDK to allow developers to interact with native Google Docs types such as Google Spreadsheets, Presentations, Documents, and Drawings.
We now provide an easy way to export native Google documents through the Google Drive API. We also allow native Google documents to be opened directly from within the Google Drive UI using third-party applications.
If your application is already a Drive-installable app, you can enable this feature by checking the Allow users to open files that can be converted to a format that this app can open option in the Google APIs Console under Drive SDK > Import:
When this feature is enabled, your application will show up under the “Open with” menu in the Google Drive Web UI for the file formats you support. Here’s how it works: if your application supports opening one of the possible export formats for the Google document, users will be able to open that Google document with your application. So for instance, if your application is configured to open PDF files, then because Google Documents are exportable to PDF, users will be able to use your application to open those documents as shown below.
When opening a native Google Document with your application from the Google Drive UI, we will pass the following JSON Object in the state URL parameter of the OAuth 2.0 redirect request that is forwarding the user to your website.
state
{ "exportIds": ["file_id"], "action":"open" }
Then you can use the file ID contained in the JSON object to query the Google Drive API and fetch the file’s metadata. Note that the state URL parameter is different when opening regular files as we use the JSON attribute exportIds instead of ids.
exportIds
ids
Unlike the metadata of regular files which contain a downloadUrl attribute which you can use to download the file’s content, the metadata for native Google documents contains a collection of export URLs. These URLs - one for each supported export format - are listed under the attribute exportLinks, as shown in the HTTP request/response below.
downloadUrl
exportLinks
Request:
GET /drive/v2/files/<file_id> HTTP/1.1 Host: www.googleapis.com Authorization: Bearer <access_token>
Response:
HTTP/1.1 200 OK Status: 200 ... { "kind": "drive#file", "id": "<file_id>", ... "exportLinks": { "application/vnd.oasis.opendocument.text": "https://docs.google.com/...", "application/msword": "https://docs.google.com/...", "text/html": "https://docs.google.com/...", "application/rtf": "https://docs.google.com/...", "text/plain": "https://docs.google.com/...", "application/pdf": "https://docs.google.com/..." }, ... }
You can query any of these export URLs using an authorized request to download the Google document in your prefered export format.
Below is the full list of supported export formats -- and their associated MIME types -- for the different types of native Google documents:
Google Documents:
Google Spreadsheets:
Google Presentations:
Google Drawings:
Please check out the Google Drive SDK documentation if you’d like to learn more, and feel free to ask any questions you may have on Stack Overflow.
If your application needs a way to let users easily choose a file from their Drive, this is for you.
Users can browse and select files from their Drive file list using the Google Picker API. The Google Picker API provides a user interface containing a list of all the user's files in Google Drive.
Since the user interface is generated by the Picker API, there is very little effort in adding the Picker to an existing site. This article will show how to use the picker for your application, and discuss some of the configuration options.
First create a view on the data describing the type of Picker that we will be using. In this case, we’ll use google.picker.ViewId.DOCS. For more types of Picker, see the documentation.
google.picker.ViewId.DOCS
var view = new google.picker.View(google.picker.ViewId.DOCS);
You can set the MIME types to filter the list of files. This allows you to specify your application’s specific file types to display to the user.
view.setMimeTypes("text/plain,text/html");
Use a PickerBuilder to set the required configuration parameters for your Picker.
PickerBuilder
var picker = new google.picker.PickerBuilder() .enableFeature(google.picker.Feature.NAV_HIDDEN) .setAppId("your app id") .addView(view) .setTitle("Select a Text File") .setCallback(pickerCallback).build();
Once configured, the picker can be popped up to the user as often as you like, using
picker.setVisible(true)
When a user selects a file with the Picker, the callback set in setCallback is called with the data from the dialog. Pass this callback as the action to perform when a user selects a file in the Picker.
setCallback
function pickerCallback(data) { if (data.action == google.picker.Action.PICKED) { var fileId = data.docs[0].id; alert('The user selected: ' + fileId); } }
Check the data’s action, in this case google.picker.action.PICKED, and if it is appropriate, access the file ID as the the first element of the docs attribute.
google.picker.action.PICKED
Here are some additional tips on customizing your Picker.
var picker = new google.picker.PickerBuilder() .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
var picker = new google.picker.PickerBuilder() .enableFeature(google.picker.Feature.NAV_HIDDEN)
For a complete example, including how to load the Picker library, please visit our the Drive SDK documentation. Also, see the Picker API documentation for more information.
Have you tried using the Google Drive API? If so, you’re aware that it allows you to programmatically manage a user’s Google Drive and build applications to manipulate files stored in the user’s account. However, the API might still be capable of doing a few things you didn’t know about. Here is a list of five specific use cases and how each of them can be addressed with the API.
When a file in Google Drive is shared publicly, it can be downloaded without authentication at the URL provided by the API in the webContentLink field of the Files resource. To retrieve that value, send a GET request to retrieve the file metadata and look for the webContentLink element in the JSON response, as in the following example:
webContentLink
{ "kind": "drive#file", "id": "0B8E...", "etag": "WtRjAP...", "selfLink": "https://www.googleapis.com/drive/v2/files/0B8E...", "webContentLink": "https://docs.google.com/a/google.com/uc?id=0B8E...", ... }
When setting permissions for a file with the Drive API, you can choose one of owner, writer and reader as the value for the role parameter. The Drive UI also lists another role, commenter, which is not allowed for that parameter.
owner
writer
reader
role
commenter
In order to grant comment-only access to a user with the Drive API, you have to set the role parameter to reader and include the value commenter in the list of additionalRoles, as in the following example:
additionalRoles
{ "kind": "drive#permission", ... "role": "reader", "additionalRoles": [ "commenter" ], ... }
It is possible to restrict the list of files (and folders) returned by the Drive API by specifying some search criteria in the q query parameter. Each file has a parents collection listing all folders containing it, and the root folder in Google Drive can be conveniently addressed with the alias ‘root’. All you need to do to retrieve all files in that folder is add a search query for element with ‘root’ in their parents collection, as in the following example:
‘root’
GET https://www.googleapis.com/drive/v2/files?q='root' in parents
Remember to URL-encode the search query for transmission unless you are using one of the available client libraries.
Your application might need to know if users have enough available quota to save a file, in order to handle the case when they don’t. Quota information is available in the About feed of the Drive API:
{ "kind": "drive#about", ... "quotaBytesTotal": "59055800320", "quotaBytesUsed": "14547272", "quotaBytesUsedInTrash": "511494", ... }
The feed includes three values related to quota management: quotaBytesTotal, quotaBytesUsed and quotaBytesUsedInTrash. The first value indicates the total amount of bytes available to the user (new accounts currently get 5GB for free) while the second one tells how many of those bytes are in use. In case you need to get more free space, you can use the last value to know how many bytes are used by files that have been trashed. An application might use this value to recommend emptying the trash bin before suggesting to get additional storage.
quotaBytesTotal
quotaBytesUsed
quotaBytesUsedInTrash
Google Drive allows users to store any kind of file and to install applications to open file types that are not directly supported by the native Google applications. In case you need to know what applications are installed and what file types each of them can open, you can retrieve the Apps feed and look for the primaryMimeTypes and secondaryMimeTypes elements for supported MIME types or primaryFileExtensions and secondaryFileExtensions for file extensions:
primaryMimeTypes
secondaryMimeTypes
primaryFileExtensions
secondaryFileExtensions
{ "kind": "drive#app", "name": "Pixlr Editor", ... "primaryMimeTypes": [ "image/psd", "image/pxd", "application/vnd.google-apps.drive-sdk.419782477519" ], "secondaryMimeTypes": [ "image/png", "image/jpeg", "image/gif", "image/bmp" ], "primaryFileExtensions": [ "pxd", "psd" ], "secondaryFileExtensions": [ "jpg", "png", "jpeg", "bmp", "gif" ], … }
Note: to access the Apps feed you have to request access to the https://www.googleapis.com/auth/drive.apps.readonly OAuth scope.
https://www.googleapis.com/auth/drive.apps.readonly
Charts are a great way to visualize information. They let you arrange data in meaningful ways, allow you to tell a story, and can really catch the reader's eye. But when dealing with large datasets, visualizing all the data at once can be somewhere between a tough to impossible mission. You usually need to filter the data and concentrate on a specific part that is of interest, and then when you want to see a different part of the data you'll need to filter it again and refresh the view. That's why we're happy to announce the introduction of dashboards in Apps Script, which allow you to compose multiple charts and filters into a single experience!
What is a dashboard? A dashboard is a visual structure that lets you organize and manage multiple charts that share the same underlying data. The three building blocks of a dashboard are the data source, charts, and controls. Controls are user interface widgets (category pickers, range sliders, or autocompleting text boxes) that someone can interact with in order to drive the data managed by a dashboard to the charts that are part of it.
Dashboards in Apps Script Because of its interactive nature, a dashboard is built in a Google Apps Script UI application. A UI application can be embedded in a Spreadsheet or a Site or served as HTML using the "Deploy as web app" option. They are perfect for creating interactive reports, where users can gain extra insight through exploring the data.
Creating a simple dashboard UI Application Have a look at the following example dashboard where a category picker and a range slider are used to drive the data visualized by a pie chart and a table chart.
Note that a dashboard is an interactive entity. Playing with its controls will change the charts in real time. You can see exactly how this dashboard was created, and learn more about how to build dashboards in general, by reading through our new Building a Charts Dashboard tutorial.
Going further Dashboards can of course be much more complex than the above example. Here is a video demonstrating a more complex dashboard embedded in a Spreadsheet:
To conclude, dashboards are powerful gadgets that allow you to handle and get valuable insights on complex datasets. Now made easy to build in Apps Script, try it on your data.
The Google Drive SDK opens up a great number of possibilities of integration with third-party applications and services. One such integration is via the new Web Intents API.
Web Intents lets web developers integrate their web apps with third-party services and avoid implementing the same feature with similar services over and over again. With Web Intents, a service can register itself to handle specific functionality, such as saving a file or sharing data. Client applications can then discover and interact with the service to use that specific functionality.
In this post, we’ll look at code for two example apps: a service that exposes a “save” web intent, and a client that consumes it to save files to Google Drive.
To demonstrate web intents, we wrote a proof of concept app called Cloudfilepicker.com. This is a service that lets users or applications save and retrieve data from Drive via the Web Intents API. With Cloudfilepicker, any application that fires a “save” intent can save to Google Drive without directly implementing the API.
To build a service application like cloudfilepicker.com that interacts with Drive and Web Intents, create a Chrome app whose manifest exposes a http://webintents.org/save intent action. For example:
http://webintents.org/save
{ "name": "Google Drive Web Intent", "version": "1", "app": { "launch": { "local_path": "index.html" } }, "intents": { "http://webintents.org/save": [ { "type" : ["image/png", "image/jpg", "image/jpeg"], "href": "save.html", "title": "Save to Drive" } ] } }
The intent declaration in the app manifest describes the functionality that your application offers, the data it can work with, and what to launch when the user chooses your application.
In order to use the Drive API, the page has to get an OAuth token for the user. The complete JavaScript implementation of the OAuth flow is available in the project repository.
Once the app receives a valid OAuth token, we can load the Drive client library and perform the file upload request using multipart upload. A Web Intent with action http://webintents.org/save can provide the file data in two ways: as a base64-encoded string or a blob, and our app should support both. With the former, we have to pass the string to the request, while with the latter we have to read the blob content and base64 encode it before we can pass it to insertBase64Data:
insertBase64Data
const boundary = '-------314159265358979323846'; const delimiter = "\r\n--" + boundary + "\r\n"; const close_delim = "\r\n--" + boundary + "--"; function makeApiCall(authResult) { gapi.client.load('drive', 'v2', function() { if(window.webkitIntent) { var data = window.webkitIntent.data; if(data.constructor.name == "Blob") { insertFileData(data, authResult, processResponse); } else if(typeof(data) == "string") { var meta = { 'title': "Test Image " + (new Date()).toJSON(), 'mimeType': window.webkitIntent.type }; insertBase64Data(data.replace(/data:image\/([^;]*);base64,/,""), window.webkitIntent.type, meta, authResult); } } }); } function insertBase64Data(data, contentType, metadata, authRequest, callback) { var multipartRequestBody = delimiter + 'Content-Type: application/json\r\n\r\n' + JSON.stringify(metadata) + delimiter + 'Content-Type: ' + contentType + '\r\n' + 'Content-Transfer-Encoding: base64\r\n' + '\r\n' + data + close_delim; var request = gapi.client.request({ 'path': '/upload/drive/v2/files', 'method': 'POST', 'params': {'uploadType': 'multipart'}, 'headers': { 'Content-Type': 'multipart/mixed; boundary="' + boundary + '"' }, 'body': multipartRequestBody}); if (!callback) { callback = function(file) { console.log(file.id); }; } request.execute(callback); } function insertFileData(fileData, authRequest, callback) { var reader = new FileReader(); reader.readAsBinaryString(fileData); reader.onload = function(e) { var contentType = fileData.type || 'application/octet-stream'; var metadata = { 'title': fileData.fileName, 'mimeType': contentType }; var base64Data = btoa(reader.result); insertBase64Data(base64Data, contentType, metadata, authRequest, callback); } }
Now, any web app that wants to save data to Google Drive could use this service instead of implementing the same functionality by invoking webkitStartActivity with a save intent.
webkitStartActivity
An example client app is http://www.imagemator.com. This app lets users manipulate and save images, but has no direct Drive API integration. When the user invokes the “save” intent in imagemator.com, if they have the “Save to Drive” app installed they will see Drive as an option in the list of apps that can fulfill that action:
If the user selects “Save to Drive”, the browser will send a request to the page listed as the href property of the intent declaration -- save.html in the sample manifest above. The following code shows how to trigger the save request:
href
var fileData = canvas.toDataURL(); var intent = new WebkitIntent({'action': 'http://webintents.org/save', 'type':'image/png', 'data': fileData}); var onSuccess = function(data) { // handle any data that might be sent back }; window.navigator.webkitStartActivity(intent, onSuccess);
To learn more about the Web Intents check webintents.org, and visit https://developers.google.com/drive to learn about the Google Drive SDK. The complete sample described in this post is also available on https://github.com/PaulKinlan/WebIntents/tree/master/server/demos/cloudfilepicker.
Are you an expert in the Drive API or Google Apps APIs? Are you an expert in Google Apps Script? If you are, then you must have been busy coding away for the Google Apps Developer Challenge since its launch earlier last month.
Now it’s time to wow the judges, as the Google Apps Developer Challenge is now open for submissions! If you would like to submit your application, please submit on the website using one of the three following categories:
If you are not ready, don’t worry -- as you still have time. The submission deadline is 24 August 2012 at 23:59:59 PT. Remember to use the many resources available to you in order to get ready. Ask questions on the Google+ Office Hours and Google Developers Live. Read up on Apps Script and the Drive and Apps APIs on Google Developers. Review the latest updates since Google I/O as well as the pre-submission checklist. Post questions and comments using the hashtag #gappschallenge on Google+. Review, and most importantly, finalize your application!
Best of luck!