It’s time for the 2012 General Election in the United States and along with it comes the tedious process of finding your voter registration, polling sites, times, directions, etc. The previously announced Google Civic Information API provides a great service to programmatically obtain much of this information based on the your home address. Google Apps Script makes it really quick and easy to build a web application that queries this information and uses various Google services to organize and track your information.

It’s time for the 2012 General Election in the United States and along with it comes the tedious process of finding your voter registration, polling sites, times, directions, etc. The previously announced Google Civic Information API provides a great service to programmatically obtain much of this information based on the your home address. Google Apps Script makes it really quick and easy to build a web application that queries this information and uses various Google services to organize and track your information.

Election Info is a sample application built using Apps Script that can:

  • Query the Google Civic Information API to find polling locations and hours using client side JavaScript and AJAX.
  • Display polling information using HtmlService with jQuery for a clean effective UI.
  • Generate static maps via UrlFetch and the MapsService to show polling maps and directions.
  • Create a calendar event for election day with your polling location using the Calendar service.
  • Generate a bring-along document with poll directions and hours using the Document service.
  • Send you an email with a summary with your polling place information using the Gmail service.
  • Store your previous searches in UserProperties so it will remember your likely home address the next time you launch the app.

As you can see, this is a comprehensive sample app that is useful while also highlighting key Apps Script capabilities.

Install the app from the Chrome Web Store. Check back soon as we will be writing a blog post with details and sample code on how the sample was built.



Arun Nagarajan   profile | twitter

Arun is a Developer Advocate on Google Apps Script. Arun works closely with the community of partners, customers and developers to help them build compelling applications on top of Google Apps using Apps Script. In the past, he spent over 9 years building and designing platforms and infrastructure for enterprise mobile applications.. Arun is originally from the Boston area and enjoys basketball and snowboarding.

Since we released version 2 of the Google Drive SDK at Google I/O, we’ve been quietly updating the DrEdit sample application to use the new API. As part of the update, the UI for DrEdit has been rewritten to use AngularJS, a modern web application toolset developed by Google and used in apps at DoubleClick. You might be wondering -- why go through the trouble of rewriting the UI for a basic sample app just to show off some new API features? Turns out it was more of a happy coincidence, but a valuable one and great learning experience!

Since we released version 2 of the Google Drive SDK at Google I/O, we’ve been quietly updating the DrEdit sample application to use the new API. As part of the update, the UI for DrEdit has been rewritten to use AngularJS, a modern web application toolset developed by Google and used in apps at DoubleClick. You might be wondering -- why go through the trouble of rewriting the UI for a basic sample app just to show off some new API features? Turns out it was more of a happy coincidence, but a valuable one and great learning experience!

Practice what you preach

I had the pleasure of co-presenting a session on building great apps for Google Drive, and a big focus of the talk was on all the little things that go into making an app intuitive and user-friendly. This is particularly important for Google Drive, where many users are already familiar with the built-in apps like Docs, Presentations, and Spreadsheets.

The first version of DrEdit was a good demo app, but didn’t follow all of our recommendations. I didn’t want to tell developers all the things they should be doing without having tried them myself. I decided to write a separate sample for the talk and needed a solid base to build on. It was the perfect opportunity to learn a new tool!

HTML & Javascript, only smarter

Angular doesn’t aim to abstract away HTML, Javascript & CSS. Rather, it enhances HTML to make building dynamic apps easier. One benefit, besides a nice short learning curve, is the positive interaction with other tools. To give the app some structure, I used Bootstrap. For example, the HTML for displaying the authenticated user’s info and a small dropdown to link to their profile in the navigation bar only required a few minor changes from typical Bootstrap usage (shown in bold) to wire up to a controller.

<ul class="nav pull-right" ng-controller="UserCtrl">
  <li class="dropdown">
    <a class="dropdown-toggle" data-toggle="dropdown" href="#">
    {{user.email}}
    </a>
    <ul class="dropdown-menu">
      <li><a href="{{user.link}}" target="_blank">Profile</a></li>
    </ul>
  </li>
</ul>

Even models are plain javascript objects. Anything reachable through a scope (the binding between a view and controller) is considered part of the model. These can be primitives, hashes, or objects. No need to extend a base class or access properties through special properties. Rather than use change listeners that require special instrumentation, Angular uses dirty checking to detect model changes and update views.

The one catch with this approach is it requires any changes to the model to be made inside the scope of a scope.$apply(fn) call. In most cases, this is done automatically. When working with external libraries or raw XMLHttpRequests that can fire asynchronous callbacks, calling $apply yourself is necessary to make sure mutations are tracked correctly.

Speaking of asynchronous tasks…

Promises, Promises

No, I’m not talking about the hit song by 80’s band Naked Eyes, rather Angular’s $q service based on one of the proposed CommonJS Promises APIs. If you’re already familiar with JQuery’s deferred object or any of the other related implementations, this is familiar territory. If not, time to learn. Working with deferred objects can be a lot easier than the traditional callback approach. You can compose async tasks either serially or in parallel, chain callbacks, and return deferred objects from functions like normal results.

Where this mostly comes into play is Angular’s $http service. If you’ve used jQuery, you’ll find it similar to jQuery.ajax() & the jqXHR result. It is based on the deferred/promises API and also ensures callbacks are executed correctly inside $apply for safe & efficient model mutations. This combination makes it easy to work with remote services in Angular.

Room for improvement

Trying to learn some new frameworks while preparing for Google I/O and helping developers to launch apps on our updated API all within a few weeks was a lot to take on. A few corners were cut and there are a few things I’d like to revisit when time permits:

  • Tests! AngularJS boasts testability as one of its key features and leverages dependency injection throughout to help keep things simple and testable. Since this was originally intended as a live demo instead of a reference app, I cut a few corners here. Yeah, I know better than that...
  • Rethink how ACE is used. In most cases it’s easy to figure out if something should be a controller, directive, filter, or service. But trying to pigeonhole libraries like ACE into one of those is daunting. Out of expediency, I chose to hide ACE behind a service, but it feels like it belongs in a directive. It would be nice to be able to declare in HTML:
    <editor content=”myModel.text”/>
    and have that sync with the model just like any other input in Angular. I started down that route, but correctly wiring up ACE to do that was more effort than it seemed worth at the time. This resulted in some other warts with how the app’s routes & views are structured.
  • Talking to the backend servers. Not so much an issue with Angular, but rather with a late decision to replace the DrEdit UI. The original goal was a separate app. Once we decided to build on the previous sample, I didn’t want to make unnecessary changes to the server side code that was already written. This led to implementing some of the new features in less than ideal ways. For example, the editor can not independently save metadata from the document content when the file is renamed or starred but the content left untouched. A minor inefficiency, but something that could have been done better.

I know I’ve only scratched the surface and have a lot more to learn. Even so, it was incredibly fun diving head first into AngularJS, and I highly recommend considering it if you’re dissatisfied with your current framework or just want to learn something new!



Steven Bazyl   profile | twitter | events

Steve is a Developer Advocate for Google Drive, Google Apps, and the Google Apps Marketplace. He enjoys helping developers find ways to integrate their apps and bring added value to users.

Do you like to store photos in Google Drive? You are not alone! Photographs are one of the most common file types stored in Google Drive. The Google Drive API now exposes Exif data for photos, so that Google Drive Apps can use it. The Exif data contains information about camera settings and photo attributes.

Do you like to store photos in Google Drive? You are not alone! Photographs are one of the most common file types stored in Google Drive. The Google Drive API now exposes Exif data for photos, so that Google Drive Apps can use it. The Exif data contains information about camera settings and photo attributes.

Despite being an awful photographer, I love photographing benches, and here is one I took while at the beach. Let’s have a look at some of these new fields for this photo.

When I examine the metadata for this image using a drive.files.get call, there is now a field, imageMediaMetadata, containing the detailed photo information:

"imageMediaMetadata": {
  "width": 2888,
  "height": 1000,
  "rotation": 0,
  "date": "2012:07:08 15:22:25",
  "cameraMake": "NIKON CORPORATION",
  "cameraModel": "NIKON D90",
  "exposureTime": 8.0E-4,
  "aperture": 5.6,
  "flashUsed": false,
  "focalLength": 105.0,
  "isoSpeed": 200
 }

So whether you are just storing your amateur snaps like me, or using Google Drive to store serious photographs, we hope this will be useful information for Drive apps. For example, a photo organizing application will be able to create thumbnail and information views for photos without ever having to download them.

For more information, please visit our documentation, and if you have any technical questions, please ask them on StackOverflow. Our team are waiting to hear from you.

Ali Afshar profile | twitter

Tech Lead, Google Drive Developer Relations. As an eternal open source advocate, he contributes to a number of open source applications, and is the author of the PIDA Python IDE. Once an intensive care physician, he has a special interest in all aspects of technology for healthcare

Whenever you upload a file to Google Drive, we try to be smart and understand more about the new file. We index its text content, generate thumbnails and even use Google Goggles to recognize images. However, as any kind of files can be uploaded to Drive, there are cases where it is impossible for Drive to understand what the file content is. For instance, when inserting or updating a shortcut, the file content is not known to Drive and a thumbnail can’t be automatically generated.

Whenever you upload a file to Google Drive, we try to be smart and understand more about the new file. We index its text content, generate thumbnails and even use Google Goggles to recognize images. However, as any kind of files can be uploaded to Drive, there are cases where it is impossible for Drive to understand what the file content is. For instance, when inserting or updating a shortcut, the file content is not known to Drive and a thumbnail can’t be automatically generated.

Developers can now use the Google Drive SDK to provide thumbnail images for those files. The new thumbnail property on the File resource includes two sub-properties that you can set when uploading a new file or updating an existing one: “image” to contain the base64-encoded image data and “mimeType” to specify one of the supported image formats: “image/png”, “image/gif”, or “image/jpeg”.

As thumbnails must reflect the current status of the file, they are invalidated every time the file content changes, so your application should make sure to always upload a new thumbnail together with the updated content.

For more information and to learn about all requirements and recommendations about this new feature, please refer to the Uploading thumbnails section of the Google Drive SDK documentation, and don’t hesitate to ask us your technical questions!

Claudio Cherubino   profile | twitter | blog

Claudio is an engineer in the Google Drive Developer Relations team. Prior to Google, he worked as software developer, technology evangelist, community manager, consultant, technical translator and has contributed to many open-source projects. His current interests include Google APIs, new technologies and coffee.

The Drive SDK allows apps to store all kinds of files and file-like items in user-managed cloud storage. Files can be standard document formats like PDF, images, video & audio clips, or even your proprietary application data files. Storing files in Drive makes it easy for users to organize, search, and securely share them with their coworkers, friends, or family.

The Drive SDK allows apps to store all kinds of files and file-like items in user-managed cloud storage. Files can be standard document formats like PDF, images, video & audio clips, or even your proprietary application data files. Storing files in Drive makes it easy for users to organize, search, and securely share them with their coworkers, friends, or family.

However, some applications work better with document or application data stored in a database. For example, let’s imagine a modern, web-based project management tool that provides lots of awesome features via data objects that are assembled dynamically at runtime for presentation to the user. In such cases, there is no single file to store all the data that comprises the project -- though there is of course a named “file” item that users will want to save and list in their Drive. Drive applications like this can create file-like entries called shortcuts that allow users to organize, access, and share items as if they were files stored in Drive.


Creating Shortcuts

Creating a shortcut is not much different than creating a regular file. Just set the MIME type to application/vnd.google-apps.drive-sdk, and make sure you don’t upload any actual content in the call to files.insert. Here’s an example of creating a shortcut using Python:

shortcut = {
    'title': 'My project plan',
    'mimetype': 'application/vnd.google-apps.drive-sdk',
    'description': 'Project plan for the launch of our new product!'
  }
  file = service.files().insert(body=shortcut).execute()
  key = file['id'] # Key to use when re-opening shortcuts

For examples in other supported languages, see the Drive SDK documentation.

Opening shortcuts in Drive always launches the application that created them. Shortcuts can even be synchronized to the desktop. Opening a shortcut from the desktop will launch the application that created it in a new browser tab.


Sharing and Security

Shortcuts require special consideration when it comes to sharing and security. Since the actual content is not stored in Drive, applications are responsible for enforcing permissions and ensuring that only authorized users are allowed to read or update content. Follow these best practices when working with shortcuts:

  • Always call files.get with the current user’s access token to verify the user has access to the content.
  • Restrict user actions based on the userPermission property of the file and disable saves if the user only has reader or commenter roles.

Honoring permissions not only ensures the protection of user data, but also provides a consistent user experience and added value to Drive applications. Users should be able to safely share an item in Drive without worrying about the particular implementation details of the application that created it.

If you have any questions about shortcuts, don’t hesitate to ask us on our Stack Overflow tag, google-drive-sdk



Steven Bazyl   profile | twitter | events

Steve is a Developer Advocate for Google Drive, Google Apps, and the Google Apps Marketplace. He enjoys helping developers find ways to integrate their apps and bring added value to users.

Over the past few years we've seen lots of Apps Script adoption within the EDU community. Educators need lightweight systems that integrate with the Google Apps they already use. Empowered by a cloud-hosted and simple to use platform, non-programmers have been able to create powerful scripts that have a real impact on the lives of their students. In honor of World Teachers' Day we're highlighting some popular scripts educators have created and other materials teachers can use to get started.

Over the past few years we've seen lots of Apps Script adoption within the EDU community. Educators need lightweight systems that integrate with the Google Apps they already use. Empowered by a cloud-hosted and simple to use platform, non-programmers have been able to create powerful scripts that have a real impact on the lives of their students. In honor of World Teachers' Day we're highlighting some popular scripts educators have created and other materials teachers can use to get started.

Earlier this year we sat down with Andrew Stillman, Program Officer for Digital Instruction at New Visions for Public Schools and co-founder of youpd.org. We discussed about how he uses Apps Script to build solutions for the New York City school system. He's the author of many popular scripts in the Script Gallery, including formMule, doctopus, and autocrat, which he uses to create powerful systems that tie together Google Forms, Spreadsheets, Docs and GMail in a way that teachers and administrators can maintain and enhance.

Flubaroo is another popular script among teachers, as it extends the usability of Google Forms for online assignments. After students have submitted their responses this script scores their answers against an answer key, generates histograms of the class's performance, and sends out personalized emails to each student with their grades.

Even more exciting, however, is that teachers have been writing their own scripts to solve problems and make their lives easier. For example, Adelphi University professor Lee Stemkoski wrote a small script that he uses to populate a Google Calendar with the topics for each lecture he'll give during the semester. In just 30 lines of code he was able to complete a long, monotonous task with the click of a button.

Teachers looking to get a better idea of how Apps Script works and what it can be used for should watch our video Google Apps EDU Fireside Chat: An Introduction to Apps Script. In it we cover the basic functionality and use cases supported, and even do some live coding to show how easy it is to get started. More than 20 million students, faculty and staff worldwide use Google Apps for Education, so if you build something interesting and worth sharing, consider publishing to the Chrome Web Store.


Eric Koleda profile

Eric is a Developer Programs Engineer based in NYC on the Google Apps Script team. He's previously worked with the AdWords API and enterprise content management software.