Category Archives: Google Apps Developer Blog

Information for Google Apps Developers

Code updates required for Apps Script advanced services

The APIs for three of Apps Script's advanced servicesAnalytics, BigQuery, and Prediction — will undergo breaking changes on Monday, November 18. If you don't update your code to the new syntax before then, you'll receive error messages such as Required parameter is missing.

Advanced services allow you to easily connect to certain public Google APIs from Apps Script. We're working to expand and improve our advanced services, and as a side effect some methods and parameters that were incorrectly listed as optional are now required.

On November 18, these services will switch to use the new method signatures shown in the tables below. To learn how new arguments should be structured, refer to the documentation for the underlying API. For example, the documentation for the BigQuery service's Jobs.query()method shows the valid properties for the resource object in the "Request body" section of the page.


OldNew
Analytics.Management.Uploads

.deleteUploadData(
accountId,
webPropertyId,
customDataSourceId,
optionalArgs)

.deleteUploadData(
resource,
accountId,
webPropertyId,
customDataSourceId)
BigQuery.Datasets

.insert(
resource,
optionalArgs)

.insert(
resource,
projectId)

.update(
resource,
optionalArgs)

.update(
resource,
projectId,
datasetId)
BigQuery.Jobs

.insert(
resource,
mediaData,
optionalArgs)

.insert(
resource,
projectId,
mediaData)

.query(
projectId,
query)

.query(
resource,
projectId)
BigQuery.Tabledata

.insertAll(
projectId,
datasetId,
tableId,
optionalArgs)

.insertAll(
resource,
projectId,
datasetId,
tableId)
BigQuery.Tables

.insert(
resource,
optionalArgs)

.insert(
resource,
projectId,
datasetId)

.update(
resource,
optionalArgs)

.update(
resource,
projectId,
datasetId,
tableId)
Prediction.Hostedmodels

.predict(
project,
hostedModelName,
optionalArgs)

.predict(
resource,
project,
hostedModelName)
Prediction.Trainedmodels

.insert(
project,
optionalArgs)

.insert(
resource,
project)

.predict(
project,
id,
optionalArgs)

.predict(
resource,
project,
id)

.update(
project,
id,
optionalArgs)

.update(
resource,
project,
id)

If you want to prepare your code ahead of time, you can add a try/catch around your existing code that retries with the new method signature if the old one fails. For example, the following sample applies this approach to the BigQuery service's Jobs.query() method:


var result;
try {
result = BigQuery.Jobs.query(projectId, query, {
timeoutMs: 10000
});
} catch (e) {
// Refer to the BigQuery documentation for the structure of the
// resource object.
var resource = {
query: query,
timeoutMs: 1000
};
result = BigQuery.Jobs.query(resource, projectId);
}

We apologize for inconvenience and look forward to sharing exciting news about advanced services in the coming weeks.


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.

Email address validation with Actions in the Inbox and Mandrill

We launched Actions in the Inbox at Google I/O 2013 as a quick way for users to get things done directly from Gmail. Integrating with this technology only requires adding some markup to an email to define what the message is about and what actions the user can perform.

We support a variety of action types covering common scenarios such as adding a movie to a queue, product reviews, or other even pre-defined requests. Especially popular with senders is the One-Click Action to validate a user’s email address, as shown below:


If you are using Mandrill, the email infrastructure service from MailChimp, writing a Python app to send one of those emails, only takes a few lines of code! Take a look at this example:

import mandrill

# Replace with your own values
API_KEY = 'YOUR_API_KEY'
FROM_ADDRESS = 'YOUR_FROM_ADDRESS'
TO_ADDRESS = 'YOUR_TO_ADDRESS'
SUBJECT = 'Please validate your email address'

HTML_CONTENT = """
<html>
 <body>
   <script type='application/ld+json'>
   {
     "@context": "http://schema.org",
     "@type": "EmailMessage",
     "action": {
       "@type": "ConfirmAction",
       "name": "Confirm Registration",
       "handler": {
         "@type": "HttpActionHandler",
         "url": "https://mydomain.com/validate?id=abc123"
       }
     }
   }
   </script>
   <p>Please click on this link to validate your email address:</p>
   <p><a href="https://mydomain.com/validate?id=abc123">https://mydomain.com/validate?id=abc123</a></p>
 </body>
</html>
"""

# Instantiate the Mandrill client with your API Key
mandrill_client = mandrill.Mandrill(API_KEY)

message = {
'html': HTML_CONTENT,
'subject': SUBJECT,
'from_email': FROM_ADDRESS,
'to': [{'email': TO_ADDRESS}],
}

result = mandrill_client.messages.send(message=message)

To run this app, just replace the API key with the credentials from your Mandrill account and configure the sender and recipient addresses. You should also edit the HTML content to provide your action handler URL, and customize the messaging if you want.

You can use Actions in the Inbox to reduce the friction and increase the conversion rate. Please note that you are not limited to validating email addresses: you can also review products and services, reply to event invitations, and much more.

For more information, please visit our documentation at https://developers.google.com/gmail/actions. You can also ask questions on Stack Overflow, with the tag google-schemas.

Claudio Cherubino   profile | twitter | blog

Claudio is an engineer in the Gmail 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.

Total Eclipse of the Apps Script

Apps Script started out as a simple tool to let developers add new features to Google Apps, but it’s grown into a programming platform that thousands of professional coders use every day. We hear a couple common requests from developers when they’re building complex projects with Apps Script: they want a full-featured IDE, and they want to sync to external version-control systems like GitHub.

Today, we’re introducing support for Apps Script in the Google Plugin for Eclipse. You can now sync with your existing Apps Script files on Google Drive, edit them in Eclipse — offline, if necessary, and with all the benefits of autocomplete — then write your code back to Drive so you can run it in the cloud. Because the plugin stores a copy of each script in a local workspace, you can manage Apps Script projects with your favorite version-control system.


Getting started is easy:

  1. Install Eclipse, if you don’t already use it. If you already have Eclipse, make sure it’s at least version 3.7 (Indigo) for either Java or Java EE.
  2. In Eclipse, select Help > Eclipse Marketplace, then install the Google Plugin for Eclipse (or see our Getting Started guide for alternate installation instructions).
  3. Click Sign in to Google in the bottom-right corner of Eclipse, then enter your username and password.
  4. Select File > Import to transfer your projects into Eclipse. Whenever you’re online, the plugin will automatically sync your local edits with Google Drive.

For step-by-step instructions on installation and use, see the documentation on using Apps Script with the Google Plugin for Eclipse.

Just in case you were wondering, the plugin uses the public Google Drive SDK to sync Apps Script files between your local file system and Google’s servers. We’ve previously covered the techniques it uses in our documentation on importing and exporting projects and the recent episode of Apps Script Crash Course on Google Developers Live below.




Norman Cohen   profile

Norman Cohen is a software engineer based in Google’s New York office. He works primarily on the Google Plugin for Eclipse, focusing on improving developer experience in the cloud.

YouTube, Google Forms, and Apps Script: BFFs

Last month, we announced several new ways to customize Google Forms. As of this week, three of those options are also available in forms created from Apps Script — embedding YouTube videos, displaying a progress bar, and showing a custom message if a form isn’t accepting responses.


Adding a YouTube video is as simple as any other Google Forms operation in Apps Script — from the Form object, just call addVideoItem(), then setVideoUrl(youtubeUrl). Naturally, you can also control the video’s size, alignment, and so forth.

To show a progress bar, call setProgressBar(enabled). Don’t even need a second sentence to explain that one. The custom message for a form that isn’t accepting responses is similarly easy: setCustomClosedFormMessage(message), and you’re done.

Want to give it a try yourself? Copy and paste the sample code below into the script editor at script.google.com, then hit Run. When the script finishes, click View > Logs to grab the URL for your new form, or look for it in Google Drive.

function showNewFormsFeatures() {
var form = FormApp.create('New Features in Google Forms');
var url = form.getPublishedUrl();

form.addVideoItem()
.setVideoUrl('http://www.youtube.com/watch?v=38H7WpsTD0M');

form.addMultipleChoiceItem()
.setTitle('Look, a YouTube video! Is that cool, or what?')
.setChoiceValues(['Cool', 'What']);

form.addPageBreakItem();

form.addCheckboxItem()
.setTitle('Progress bars are silly on one-page forms.')
.setChoiceValues(['Ah, that explains why the form has two pages.']);

form.setProgressBar(true);

form.setCustomClosedFormMessage('Too late — this form is closed. Sorry!');
// form.setAcceptingResponses(false); // Uncomment to see custom message.

Logger.log('Open this URL to see the form: %s', url);
}

Dan Lazin   profile | twitter

Dan is a technical writer on the Developer Relations team for Google Apps Script. Before joining Google, he worked as video-game designer and newspaper reporter. He has bicycled through 17 countries.

Monitor user logins, storage consumption and apps usage with the Admin SDK

Security is a top priority for Google, just as it is for many of our Google Apps customers. As a domain administrator, a big part of keeping your users safe is knowing when and how they are using their accounts. Since we launched the Admin SDK Reports API in June, we've continued to add features to let you more easily visualize Google Apps' usage and security in your domain. These new features include:

Security Reports

  • Login audit—View all web browser based logins with IP information for all users in your domain. You can use this data to monitor all successful, failed, and suspicious logins in your domain.
  • Authorized applications—View a list of third-party applications that users in your domain have shared data with. Gain visibility into how many users are accessing each application. Revoke access to specific apps using the security tab on Admin console.

Usage Reports

  • Storage quota—View user-level quota usage. This is available both as total usage and split by Gmail, Drive and Google+ photos for every user in the domain. Monitor which users are nearing their quota limits and acquire more storage if necessary.
  • Google+ usage—View 1-day, 7-day and 30-day active Google+ usage in your domain. See the number of Hangouts attended by users in your domain.

Refer to the Reports API documentation for more details on how to use the Reports API and to see what is possible with all of our entire Admin SDK.


Rishi Dhand profile

Rishi Dhand is a Product Manager on the Google Apps for Business team. In addition to working on data migration features, he also works on the Google Apps administration platform with focus on building new security and admin reporting features. In his free time, he enjoys playing squash and badminton.

Selecting Upload Destinations with the Picker API

Drive is a great drop zone for incoming files -- no matter if they’re coming from cameras, scanners, faxes, or countless other devices or apps. But throwing files into the root folder makes it difficult for users to find and organize their content.

I’ve seen developers create a folder when the user first connects the app with Drive to keep files organized by the app that created it. It’s a simple technique that is easy to implement and good default behavior for most applications.

With the Picker API, we can go a step further and offer users the choice of destinations too. For example, I’d like my scanner to put work files in one folder and personal files in another, or even configure multiple destinations depending on the type of document I’m scanning.

For this particular use case, the picker needs to be configured to show folders and only show folders. That requires customizing the DocsView just a little.


var docsView = new google.picker.DocsView()
.setIncludeFolders(true)
.setMimeTypes('application/vnd.google-apps.folder')
.setSelectFolderEnabled(true);

By enabling folders & the ability to select them while simultaneously filtering out everything else, users can quickly and easily select one of their existing folders as a destination. The rest of the code to show the picker is par for the course.


// Handle user actions with the picker.
var callback = function(data) {
if (data.action == google.picker.Action.PICKED) {
var doc = data.docs[0];
alert("You picked " + doc.id);
}
};

var picker = new google.picker.PickerBuilder()
.addView(docsView)
.setCallback(callback)
.build();

picker.setVisible(true);

Not only is this easy to implement, it’s safer for users. By offloading this functionality to the Picker API, an app only needs the drive.file scope to write files into the user’s preferred location.

You can learn more about the Picker API at developers.google.com or ask questions at StackOverflow with the google-drive-sdk tag.



Steven Bazyl   profile | twitter

Steve is a Developer Advocate for Google Drive and enjoys helping developers build better 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.