Tag Archives: Google Apps

Connect your organization to Google+ using the Google+ Domains API

Google+ make it easy for Google Apps customers to connect and share within their organisation and encourage collaboration between teams. Today we’re launching an update to the Google+ Android app that includes a number of new features for Google Apps customers, and a new developer offering, the Google+ Domains API.

The Google+ Domains API allows Google Apps customers to integrate Google+ into their existing tools and processes, and allows enterprise software vendors to access Google+ from their products. Applications using the Google+ Domains API can act on behalf of Google Apps users to share posts within the same domain, comment on posts shared within the domain, and manage Circles. In addition, the Google+ Domains API enables Google Apps domain administrators to pre-populate the Circles of new employees, or review sharing activity.

For example, Ocado is building a tool that uses the Google+ Domains API to regularly sync team membership stored in Active Directory with the circles of their employees. This will ensure that every employee always has an up to date circle containing the other members of their team. Cloudlock is using the Google+ Domains API to add support for Google+ to its suite of data loss prevention, governance, and compliance applications.


Any developer can begin developing with the Google+ Domains API today. However only members of a Google Apps domain can use Google+ Domains API applications. To get started check out the documentation. If you have any questions, you can consult the google-plus tag on Stack Overflow, or join the “Developing with Google+” Google+ Community.


Posted by Thor Mitchell, Product Manager, Google+ API

Cross posted on the Google+ Developers blog.

Answering another top request: data validation in Apps Script

Google Apps Script is, first and foremost, a tool for making Google Apps more powerful — and today’s addition of programmatic control over data-validation rules in Google Sheets is a perfect example. For a quick demo, make a copy of this spreadsheet, then follow the instructions provided.


For the last few months, scriptable access to the data validation feature in Sheets has been the most requested feature on the Apps Script issue tracker. A common use for data-validation rules is to require that a cell’s value match one of the values in a different range. The following example shows how to achieve that goal with Apps Script. First, we use the newDataValidation() method to construct a DataValidationBuilder, then set the appropriate options and apply the final DataValidation with setDataValidation().


// Set the data-validation rule for cell A1 to require a value from B1:B10.
var cell = SpreadsheetApp.getActive().getRange('A1');
var range = SpreadsheetApp.getActive().getRange('B1:B10');
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(range)
.build();
cell.setDataValidation(rule);

It’s also possible to modify existing data-validation rules. The next example changes rules that require a date in 2013 to require a date in 2014 instead. You’ll see that the script calls getDataValidations() to retrieve the existing rules, then uses getCriteriaType(), getCriteriaValues(), and the DataValidationCriteria enum to examine the rules before applying the new date restriction via the advanced withCriteria() method.


// Change existing data-validation rules that require a date in 2013
// to require a date in 2014.
var oldDates = [new Date('1/1/2013'), new Date('12/31/2013')];
var newDates = [new Date('1/1/2014'), new Date('12/31/2014')];
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange(1, 1, sheet.getMaxRows(), sheet.getMaxColumns());
var rules = range.getDataValidations();

for (var i = 0; i < rules.length; i++) {
for (var j = 0; j < rules[i].length; j++) {
var rule = rules[i][j];

if (rule != null) {
var criteria = rule.getCriteriaType();
var args = rule.getCriteriaValues();

if (criteria == SpreadsheetApp.DataValidationCriteria.DATE_BETWEEN
&& args[0].getTime() == oldDates[0].getTime()
&& args[1].getTime() == oldDates[1].getTime()) {
rules[i][j] = rule.copy().withCriteria(criteria, newDates).build();
}
}
}
}
range.setDataValidations(rules);

With this new feature in Apps Script, you should find it much easier to manage complex data-validation scenarios. Please keep the feature requests coming!


Asim Fazal   profile

Asim is a software engineer on the Google Sheets team in New York — and an enthusiastic occasional contributor to the Apps Script team.

An update to authorization in Apps Script

For developers, part of the simplicity of Apps Script has always been that authorization requires zero setup — but we heard from users that the process required too many clicks. At Google I/O this year, we launched an opt-in version of an easier authorization flow; today, that new flow becomes the default for all new scripts.


The old way — and the new.

Besides being prettier and easier, the new flow offers benefits behind the scenes: it allows more scripts to be simultaneously authorized on the same account, which means you shouldn’t need to reauthorize a script unless the code changes substantially.

For developers who use the advanced Google services, the new flow also gets rid of some manual steps that were previously required. Every new script now automatically creates a project in the Google APIs Console — no more messing with secret keys!

If you want the same experience for your existing scripts, you can upgrade them manually in just a few seconds.


Steve Lieberman   profile

Steve is an engineer on the Apps Script team in NYC. Before joining Google, he developed financial-trading systems and researched automatically-parallelizing compilers.

Introducing a New Version of the Email Migration API

Today, we are pleased to announce a new release of the Email Migration API. This version of the API provides a simple RESTful interface with several enhancements that make it even easier to write client applications to migrate email to Google Apps.

This API is now part of our Admin SDK, which is useful for managing applications for Google Apps users through the Google APIs Console. Additionally, the Email Migration API v2 now includes support for:
  • Delegated administrators
  • OAuth 2.0
  • Media uploads
The new API also provides support for migrating additional email metadata (such as folders and labels) from existing email systems into Google Apps. For example, a user’s email stored in a nested folder named engineering/backend-support can be migrated with the label engineering-backend-support to retain the previous organization structure.

For more information about the API, visit the the Getting Started guide or explore the API Reference.

Greg Knoke Google+

Greg Knoke is a technical writer in the Google Drive Developer Relations Team. Prior to joining Google, he worked as a scientist developing image and signal processing algorithms. His current interests include new technologies, content management, information architecture, cooking, music, and photography.

Google Drive API Push Notifications

If your app needs to keep up with changes in Drive, whether to sync files, initiate workflows, or just keep users up to date with the latest info, you’re likely familiar with Drive’s changes feed. But periodic polling for changes has always required a delicate balance between resources and timeliness.

Now there’s a better way. With push notifications for the Drive API, periodic polling is no longer necessary. Your app can subscribe for changes to a user’s drive and get notified whenever changes occur.

Suppose your app is hosted on a server with my-host.com domain and push notifications should be delivered to an HTTPS web-hook https://my-host.com/notification:



String subscriptionId = UUID.randomUUID().toString();
Channel request = new Channel()
.setId(subscriptionId)
.setType("web_hook")
.setAddress("https://my-host.com/notification");
drive.changes().watch(request).execute();
 

As long as the subscription is active, Google Drive will trigger a web-hook callback at https://my-host.com/notification. The app can then query the change feed to catch up from the last synchronization point:



changes = service.changes().list()
.setStartChangeId(lastChangeId).execute();
 

If your app only needs to be notified about changes to a particular file or folder your app can watch just those files rather than the entire change feed.

If you are interested in using this new feature, please refer to the documentation at developers.google.com. You can see push notifications in action with the Push Notifications Playground and view the source at Github.



Steven Bazyl   profile | twitter

Steve is a Developer Advocate for Google Drive and enjoys helping developers build better apps.

XML changes in Apps Script

Many developers have come to prefer JSON for data serialization, but we recognize that good ol' XML is still an important format for many Apps Script users. Our existing XML service is good at parsing XML, but has limited ability to create or alter existing documents. In order to provide a more complete and consistent experience, we have created a new XML service, which launches today. The new service is accessed using XmlService, in contrast to the old service which was simply called Xml.

Let's take a look at how you can use the new service to create an XML representation of the emails in your Gmail inbox.

function createXml() {
var root = XmlService.createElement('threads');
var threads = GmailApp.getInboxThreads();
for (var i = 0; i < threads.length; i++) {
var child = XmlService.createElement('thread')
.setAttribute('messageCount', threads[i].getMessageCount())
.setAttribute('isUnread', threads[i].isUnread())
.setText(threads[i].getFirstMessageSubject());
root.addContent(child);
}
var document = XmlService.createDocument(root);
var xml = XmlService.getPrettyFormat().format(document);
Logger.log(xml);
}

The code above logs XML that looks something like this:

<?xml version="1.0" encoding="UTF-8"?>
<threads>
<thread messageCount="1" isUnread="true">
Can't wait for the new XML service!
</thread>
<thread messageCount="1" isUnread="true">
50% off all widgets through Friday
</thread>
<thread messageCount="3" isUnread="false">
Don't forget about the picnic on Saturday
</thread>
</threads>

The new XML service has some notable advantages over the old service:

  • The ability to alter parsed XML content and save it back to a string.
  • Access to all entity types in the XML document (CDATA sections, Comments, etc.)
  • More control over the formatting of the XML string.

With the launch of this new service, we are deprecating some of our older XML tools in Apps Script, specifically the old XML service, the SOAP service, and the JavaScript feature E4X. Calls to these services will continue to work, but we encourage you to start migrating your code to the new XML service for better long-term support. On February 1, 2014, these old services will no longer appear in auto-complete or in our documentation, per the Apps Script sunset schedule.

Introducing Google Docs Cursor/Selection APIs in Apps Script

Ever wanted to programmatically insert something at the cursor in Google Docs (say, a “Sign Here” image) or read the user’s selection (maybe for an on-the-spot translation)? Starting today, you can.

Apps Scripts bound to Google Docs can now access the active user's Cursor and Selection by calling Document.getCursor() and Document.getSelection(), respectively. The returned objects provide useful information like the element the cursor is positioned in and an array of all of the elements contained in the selection.


Example #1: Selection Translator

This Google Doc contains a simple script that uses Apps Script’s Language Service to translate selected text from English to Spanish through a custom menu item.


Here, it uses the getSelectedElements() method of the Selection class to get an array of selected elements:


var selection = DocumentApp.getActiveDocument().getSelection();
if (selection) {
var elements = selection.getSelectedElements();

Next, it loops through each element, performs the translation, and replaces the original text:


var translatedText = LanguageApp.translate(
element.asText().getText(), 'EN', 'ES');
element.asText().setText(translatedText);

Example #2: Bibliography App

At Google I/O this year, Apps Script engineer Jonathan Rascher demonstrated Bibstro, a bibliography sample app for Google Docs that inserts inline citations at the cursor. Today, we’re releasing the source code for Bibstro; you can also try it out by making of copy of this Google Doc.


To insert text, the script calls the aptly named insertText() method of the Cursor object:


var cursor = DocumentApp.getActiveDocument().getCursor();
if (cursor) {
// Determine the text of the new inline citation to insert.
var citation = bibStrategy.getInlineCitationText(...);

var surroundingText = cursor.getSurroundingText().getText();
var surroundingTextOffset = cursor.getSurroundingTextOffset();

if (surroundingTextOffset > 0 &&
surroundingText.charAt(surroundingTextOffset - 1) != ' ') {
// If the cursor follows a non-space character, insert a space
// and then the citation.
cursor.insertText(' ' + citation);
} else {
// Otherwise, just insert the citation.
cursor.insertText(citation);
}
}

You’ll also notice that the script uses the Cursor class’s getSurroundingText() method to determine whether to insert a space before the new inline citation.


Example #3: Cursor Inspector

To help you become familiar with how cursor and selection work, we've also created a Cursor Inspector sample script. As you navigate through a document, the script displays up-to-date information about your cursor or selection in a custom sidebar. We’re also releasing the source code for Cursor Inspector on GitHub.


These new APIs are available immediately. We’re excited to see what kind of scripts you come up with!


Kalyan Reddy profile | Stack Overflow

Kalyan is a Developer Programs Engineer on the Google Apps Script team in New York City. He is committed to increasing developers’ productivity by helping them fully utilize the power of Apps Script. In his free time, he enjoys participating in the maker community and hacking together robots.

Flubaroo 3.0 Released

Flubaroo, a popular Apps Script application that helps teachers with grading, has just reached version 3.0. The new features and improvements include:

  • Smarter emailing of grades.
  • Option to email "Help Tips" for each question.
  • Option to send students individualized feedback.
  • Multi-language support, with first language of Spanish.
  • Easier to read grade emails.

If you know any teachers who aren’t using Flubaroo yet, why not encourage them to try it out? It doesn’t cost a thing, and has helped thousands of teachers save time and gain insight into student performance — all through the power of Apps Script.


Dave Abouav   profile

Dave is a Googler who also teaches physics at community college at nights. He developed Flubaroo as his 20%-time project, and runs edCode.org, a community of teachers and developers creating free, open-source tools for education.

Optimizing Drive API calls

Ever look at the data returned when using the Drive API? A files.list call, even if just returning a single file, can yield upwards of 4kb of data. Drive has a rich set of metadata about files, but chances are your application only needs a small fraction of what’s available.

One of the simplest but most effective optimizations you can make when building apps with the Drive API is limiting the amount of data returned to only those fields needed for your particular use case. The fields query parameter gives you that control, and the results can be dramatic.

A simple example of this is using the files.list call to display a list of files to a user. The naive query, https://www.googleapis.com/drive/v2/files?maxResults=100, generated more than 380kb of data when I ran it against my own corpus. But to render this list nicely, an app only needs a few bits of information -- the document title, icon & thumbnail URLs, the mime type, and of course the file ID.

Using the fields query parameter, the results can be trimmed to just the necessary fields and those needed for fetching subsequent pages of data. The optimized query is https://www.googleapis.com/drive/v2/files?maxResults=100&fields=items(iconLink%2Cid%2Ckind%2CmimeType%2CthumbnailLink%2Ctitle)%2CnextPageToken.

After modifying the query the resulting data was only 30k. That’s more than a 90% reduction in data size! Besides reducing the amount of data on the wire, these hints also enable us to further optimize how queries are processed. Not only is there less data to send, but also less time spent getting it in the first place.



Steven Bazyl   profile | twitter

Steve is a Developer Advocate for Google Drive and enjoys helping developers build better apps.