WorryFree Computers   »   [go: up one dir, main page]



Thousands of developers use Google Calendar API to read, create and modify Google Calendar events, and quite often, these events represent meetings happening not just face-to-face but also remotely. We introduced Hangouts Meet earlier this year to give users richer conference experiences, adding video call links and phone numbers for G Suite Enterprise. Starting today, we are making it possible to access all that conference information through the Google Calendar API. With this update, developers can now:
  • Read conference data associated with events 
  • Copy conference data from one event to another 
  • Request new conference generation for an event 
The API supports all Hangouts versions.

Reading conference data 

Conference information is stored in a new event attribute called conferenceData. conferenceData provides information about the solution that was used to create the conference (such as Hangouts Meet) and a set of entry points (like a video call link and phone number). Everything the user needs to know to join a conference call is there.

To help you build even better user experiences, we also give you access to icons and user-readable labels that you can use in your products. In JSON format, conferenceData looks something like this (of course, your actual meeting IDs and phone numbers will vary):
"conferenceData": {
  "entryPoints": [
   {
    "entryPointType": "video",
    "uri": "https://meet.google.com/wix-pvpt-njj",
    "label": "meet.google.com/wix-pvpt-njj"
   },
   {
    "entryPointType": "more",
    "uri": "https://tel.meet/wix-pvpt-njj?pin=1701789652855",
    "pin": "1701789652855"
   },
   {
    "entryPointType": "phone",
    "uri": "tel:+44-20-3873-7654",
    "label": "+44 20 3873 7654",
    "pin": "6054226"
   }
  ],
  "conferenceSolution": {
   "key": {
    "type": "hangoutsMeet"
   },
   "name": "Hangouts Meet",
   "iconUri": "https://blogger.googleusercontent.com/img/proxy/AVvXsEiaSY9_YfMdiWryFlVhzIs3jdKPPiVuvOTO4I2Roz_qnNGdmlz30rPKsRQpH_zL9sBemoQxmsA-Djl4q_jhz1-as83Gq-49NjORxptsEGxLEp4stip8yhdVitDBWRjGoECBYqs7fbAaINxFem2mwR8pCQXsn1dvNRegYieao0vH5kxDUWsI20mcOka_r5ha_zusG4YlXHa2mzRjZOc="
  },
  "conferenceId": "wix-pvpt-njj",
  "signature": "ADwwud9tLfjGQPpT7bdP8f3bq3DS"
 }

And this, for example, is how you would retrieve and display conference solution name and icon:
var solution = event.conferenceData.conferenceSolution;

var content = document.getElementById("content");
var text = document.createTextNode("Join " + solution.name);
var icon = document.createElement("img");
icon.src = solution.iconUri;

content.appendChild(icon);
content.appendChild(text);
The result of the code above will look like this in the user interface:

Copying conferences across events 

Sometimes displaying information is not enough—you might want to update it as well. This is especially true when scheduling multiple Calendar events with the same conference details. Say you’re developing a recruiting application that sets up separate events for the candidate and the interviewer; you want to protect the interviewer’s identity, but you also want to make sure all participants join the same conference call. To do this, you can now copy conference information from one event to another by simply writing to conferenceData.

To ensure that only existing Hangouts conferences are copied, and to help safeguard your users against malicious actors, copied conference data will always be verified by the Google Calendar API using the signature field, so don’t forget to copy it too.

Creating a new conference for an event 

Finally, the API allows developers to request conference creation. Simply provide a conferenceData.createRequest and set the conferenceDataVersion request parameter to 1 when creating or updating events. Conferences are created asynchronously, but you can always check the status of your request to let your users know what’s happening. For example, to request conference generation for an existing event (again, your request and event IDs will be different):
var eventPatch = {
  conferenceData: {
    createRequest: {requestId: "7qxalsvy0e"}
  }
};

gapi.client.calendar.events.patch({
  calendarId: "primary",
  eventId: "7cbh8rpc10lrc0ckih9tafss99",
  resource: eventPatch,
  sendNotifications: true,
  conferenceDataVersion: 1
}).execute(function(event) {
  console.log("Conference created for event: %s", event.htmlLink);
});
The immediate response to this call might not yet contain the fully-populated conferenceData which is indicated by status pending:
"conferenceData": {
  "createRequest": {
   "requestId": "7qxalsvy0e",
   "conferenceSolutionKey": {
    "type": "hangoutsMeet"
   },
   "status": {
    "statusCode": "pending"
   }
  }
 }
Once the statusCode changes to success, the conference information is populated. Finally, if you are developing a Google Calendar client, you might also want to know beforehand which of the three Hangouts solutions (consumer Hangouts, classic Hangouts and Hangouts Meet) will be used to create the conference. You can get that information by checking allowedConferenceSolutionTypes in a calendar’s conferenceProperties.

To get started, check out the documentation page for managing conference data. We can’t wait to see what you build with these new features in the Google Calendar API.


We launched Google Realtime API in 2013 to help developers build collaborative apps using familiar JSON-based data models, while leaving the complexities of real-time synchronization to the API. Since then, we've developed other fast, flexible cloud-based storage solutions like Google Cloud SQL and Google Cloud Firestore. As a result, we’ve decided to deprecate Realtime API in favor of these new, powerful solutions.

We’re investing heavily in Google Cloud Platform, as well as Firebase—our mobile development platform—to help developers build scalable, performant applications. While these solutions aren't a direct analog to the Drive Realtime API, we're confident they can meet most of your needs:
  • Google Cloud SQL: Fully-managed database service that makes it easy to set up, maintain, manage, and administer your relational PostgreSQL and MySQL databases in the cloud. 
  • Firebase Realtime Database: Cloud-hosted NoSQL database that lets you store and sync data between your users in real-time. 
  • Google Cloud Firestore: We recently announced Cloud Firestore to help developers build responsive apps that work regardless of network latency or Internet connectivity. If you're curious about Firebase Realtime Database vs. Cloud Firestore, we've got you covered.
Existing Realtime API client applications will continue to work normally until December 11, 2018, but we are no longer accepting new clients of the API. After the API is decommissioned, to facilitate migration, we will continue to provide a mechanism for applications to access document contents as JSON.

More specific deprecation timelines 

We know developers and partners have come to rely on Realtime API and that migration may be a significant effort. We hope that the deprecation timelines summarized below allow for a smooth transition.


November 28, 2017
Realtime API is no longer available for new projects.1
December 11, 2018
Realtime API documents become read-only, and attempts to modify document contents using the API fail.
January 15, 2019
Realtime API is shut down, but a JSON export API remains available.
1 Projects which accessed the Realtime API prior to November 28, 2017 will continue to function as before. All other projects, including new projects, will be blocked from accessing the Realtime API.

Migration tips 

Applications using the Realtime API will need to migrate to another data store. Our migration guide provides instructions on how to export Realtime document data and also how that data can be imported into Google Cloud Firestore. After Realtime API is shut down, we will continue to provide a means for exporting Realtime document contents as JSON.

Additional information and support 

You can read more about the deprecation in our documentation. If you have questions that aren’t answered there, see the support page for how to get help.



Email remains at the heart of how companies operate. That’s why earlier this year, we previewed Gmail Add-ons—a way to help businesses speed up workflows. Since then, we’ve seen partners build awesome applications, and beginning today, we’re extending the Gmail add-on preview to include all developers. Now anyone can start building a Gmail add-on.

Gmail Add-ons let you integrate your app into Gmail and extend Gmail to handle quick actions. They are built using native UI context cards that can include simple text dialogs, images, links, buttons and forms. The add-on appears when relevant, and the user is just a click away from your app's rich and integrated functionality.

Gmail Add-ons are easy to create. You only have to write code once for your add-on to work on both web and mobile, and you can choose from a rich palette of widgets to craft a custom UI. Create an add-on that contextually surfaces cards based on the content of a message. Check out this video to see how we created an add-on to collate email receipts and expedite expense reporting.

Per the video, you can see that there are three components to the app’s core functionality. The first component is getContextualAddOn()—this is the entry point for all Gmail Add-ons where data is compiled to build the card and render it within the Gmail UI. Since the add-on is processing expense reports from email receipts in your inbox, the createExpensesCard()parses the relevant data from the message and presents them in a form so your users can confirm or update values before submitting. Finally, submitForm() takes the data and writes a new row in an “expenses” spreadsheet in Google Sheets, which you can edit and tweak, and submit for approval to your boss.

Check out the documentation to get started with Gmail Add-ons, or if you want to see what it's like to build an add-on, go to the codelab to build ExpenseIt step-by-step. While you can't publish your add-on just yet, you can fill out this form to get notified when publishing is opened. We can’t wait to see what Gmail Add-ons you build!


You might have seen that we recently announced new Google Slides add-ons. We worked closely with several technology partners to build these new add-on solutions to help speed up workflows. 

One partner, Lucidchart, worked closely with Google to create a new integration that brings added diagramming functionality to Slides. We sat down with Tim Winchester, engineering lead at Lucidchart, to learn more about how his team built the new Lucidchart add-on for Slides.

Tell us about the Google Slides add-on you built for Lucidchart. 

We built it as a sidebar add-on that allows users to insert diagrams directly into Google Slides from within Slides (instead of having to export diagrams from Lucidchart). You can also create a new Lucidchart diagram from within Slides, and simply select “Back to Slides” once you’re finished creating your diagram in the Lucidchart editor. You can modify an existing diagram by clicking “Edit” within Slides. This option will direct you to the Lucidchart editor so you can revise as needed. Once you’ve finished revising, or any time you know a diagram has been updated in Lucidchart, select the refresh button from the Lucidchart Diagrams sidebar.

What prompted you to create your add-on? 

Specifically, how did you envision your add-on would improve user experience? Lucidchart is a visual communication platform, but we know our users sometimes need to have their diagrams available in other places. One of the most popular uses for Lucidchart is in presentations, so an add-on for Slides was a natural fit.

Tell us about how you built your solution. 

Since we already had existing add-ons for Docs and Sheets, this project was less about building from scratch and more about adapting what we already had, then doing rewrites as needed. We started by abstracting app-specific functionality of our existing add-ons into a pluggable IntegratedApp interface. We then implemented the interface for Slides using the new SlidesApp API. Once we had reached feature parity, we created a few new additions, such as a “Refresh All Inserted Diagrams” button, which users could find more easily than a top bar menu entry.



At the same time, the Lucidchart add-on was undergoing a major UI overhaul, which was the most challenging and time-intensive part of the project. Because we liked the results of the UI update in Slides, we refactored the add-on code to make it more generalizable, then ported it back to our Docs and Sheets add-ons.

Did anything surprise you during the build? 

As a security measure, the sidebar iframe can only render elements within its borders, so we couldn’t simply throw a <div> into the center of the screen in client code. Instead, we had to fire an event that the Apps Script backend would handle to create a modal dialog, using printing scriptlets to add whatever data we needed into the dialog’s HTML. Thus, any JS object sent from the sidebar to a modal has to be serialized and deserialized in the process, which means that the sidebar cannot directly detect any events emitted by the modal.

Do you have any code snippets that you can share? 

Because we have multiple Google Apps Script add-ons that share lots of functionality, it was very useful to concentrate app-specific code and strings into a wrapper object (called IntegratedApp), which we then referenced elsewhere in the codebase instead of calling SlidesApp directly. So, in the click handler for the insert button, instead of writing this...
SlidesApp.getActivePresentation()
    .getSelection()
    .getCurrentPage()
    .insertImage(image);

...we write this.
IntegratedApp.insertImage(image);

And then we keep the app-specific implementation in our IntegratedApp object (abridged for clarity):
var IntegratedApp = {
  // direct mapping to function
  createAddonMenu: SlidesApp.getUi().createAddonMenu.bind(SlidesApp.getUi()),

  // wrapper to create consistent behavior across apps
  insertImage: function(image) {
    return SlidesApp.getActivePresentation()
        .getSelection()
        .getCurrentPage()
        .insertImage(image);
  },

  // app-specific strings
  phrases: {
    docType: 'Slide',
    name: 'Google Slides',
    nameWithDocType: 'Google Slides Presentation'
  }
};

This technique allows us to keep the same UI code and business logic across apps; we only need to change the implementation of the IntegratedApp object. So in Sheets (for example), our IntegratedApp.insertImage() function becomes:
insertImage: function(image) {
  var sheet = SpreadsheetApp.getActiveSheet();
  var cell = sheet.getActiveCell();

  sheet.insertImage(image, cell.getColumn(), cell.getRow());
}

What advice would you give other developers looking to build similar add-ons? 

If you are planning to develop multiple similar add-ons that mainly differ in the G Suite app with which they integrate, you should find this technique of reducing the overall code amount by isolating duplicative code immensely useful.

After completing the first add-on, creating another add-on for a new G Suite app is just a matter of updating a new copy of IntegratedApp to work with the new app; the rest of the codebase can be commonly shared. In our case, it means that the updated UI was easily added to our Docs and Sheets add-on after we completed the Slides add-on.

Learn more about how you can create your own Slides add-ons or choose from a number of publicly available APIs to customize your G Suite applications. If you’re interested in becoming a Google Cloud technology partner, you can also join our partnership program.



Today, we announced a collection of exciting new features in Google Slides—among these is support for Google Apps Script. Now you can use Apps Script for Slides to programmatically create and modify Slides, plus customize menus, dialog boxes and sidebars in the user interface.

Programming presentations with Apps Script

Presentations have come a long way—from casting hand shadows over fires in caves to advances in lighting technology (magic lanterns) to, eventually, (in)famous 35mm slide shows of your Uncle Bob's endless summer vacation. More recently, we have presentation software—like Slides—and developers have been able to write applications to create or update them. This is made even easier with the new Apps Script support for Google Slides. In the latest G Suite Dev Show episode, we demo this new service, walking you through a short example that automatically creates a slideshow from a collection of images.
To keep things simple, the chosen images are already available online, accessible by URL. For each image, a new (blank) slide is added then the image is inserted. The key to this script are two lines of JavaScript (given an existing presentation and a link to each image):

var slide = presentation.appendSlide(SlidesApp.PredefinedLayout.BLANK);
var image = slide.insertImage(link);

The first line of code adds a new slide while the other inserts an image on the new slide. Both lines are repeated for each image in the collection. While this initial, rudimentary solution works, the slide presentation created doesn't exactly fit the bill. It turns out that adding a few more lines make the application much more useful. See the video for all the details.

Getting started 

To get started, check the documentation to learn more about Apps Scripts for Slides, or check out the Translate and Progress Bar sample Add-ons. If you want to dig deeper into the code sample from our video, take a look at the corresponding tutorial. And, if you love watching videos, check out our Apps Script video library or other G Suite Dev Show episodes. If you wish to build applications with Slides outside of the Apps Script environment and want to use your own development tools, you can do so with the Slides (REST) API—check out its documentation and video library.

With all these options, we look forward to seeing the applications you build with Google Slides!



Google Classroom makes it easy for teachers and students to use the edtech tools they love, and that’s not just limited to Google tools. With the Classroom API, hundreds of developers have built integrations with Classroom that make it easier for admins and teachers to manage classes, share content and more.

One popular way that applications integrate with Classroom is by re-using Classroom rosters—teachers can import their classes with a click and students don’t have to have a new login. Today, we’re making it easier for developers to keep rosters in-sync between their apps and Classroom by launching real-time notifications of changes.

Now, an application can now receive roster changes for a domain, or for an individual course. Powered by Google Cloud Pub/Sub, a state-of-the-art messaging service for passing information between applications, developers no longer have to poll various Classroom API endpoints for changes, which gives teachers and students a more seamless experience. If a new student joins or leaves a Classroom class, that roster change can be automatically applied across applications.

How Flat Education syncs rosters in real-time 

Flat Education, a collaborative music notation app, uses the new updates to instantly update class rosters. Before, when teachers and students accessed the Flat Education application, it would poll the Classroom API for changes and then make updates, delaying data. Now, roster data can be refreshed instantly.
With today's Classroom API update, applications can sync roster data instantly. When a new student joins Google Classroom (bottom left), the student is instantly added to the corresponding music class in Flat Education (top right).

We’re also making the Classroom API more comprehensive with additional enhancements so you can:
  • Create and update announcements. Last year, we launched the ability for external applications to access and create assignments and questions. This update gives applications access to all the posts in Classroom. 
  • Create and update individualized posts. Earlier this year, we made it possible for teachers to post to individual students in Classroom and now, applications can do the same programmatically. This is especially helpful for applications that help teachers differentiate and individualize learning.
For more details on what you can build with the Classroom API, check out the documentation. You can also ask questions (or answer them!) on StackOverflow using the google-classroom tag, and report bugs or feature requests via the issue tracker.

Lastly, let us know what you're building using the #withClassroom hashtag on Twitter or Google+.



Apps Script is just as popular inside Google as it is among external users and developers. In fact, there are more than 70,000 weekly active scripts written by thousands of Googlers. One of our many uses for Apps Script at Google is to automate and monitor our internal issue tracker.

Your business depends on Apps Script...so does ours 

In spring of this year, we migrated our G Suite issue trackers to a new system based on our internal tracker. This carries a lot of benefits, including improving our ability to track how issues reported from outside of Google relate to bugs and features we’re working on internally. We also have an internal Apps Script API that talks to our issue tracker, which we can now use to work with issues reported from outside of Google.

As soon as the migration was finished, we put Apps Script to work monitoring…itself. Now we have a script in place that monitors Apps Script issues as they are reported and upvoted on the public tracker. When we see an issue that’s having widespread or sudden impact, the script generates an alert that we can then investigate. With the help of our large, active community of developers, and leveraging Apps Script, we’re now able to identify and respond to issues more quickly.

There’s no substitute for independent monitoring, and our Apps Script-based approach isn’t the first or the last line of defense. Instead, this new script helps us catch anything that our monitoring systems miss by listening to what developers are saying on the tracker.

If you see something, say something 

Please help us keep Apps Script humming! When you notice a problem, search the issue tracker for it and file an issue if it's new. Click the star to let us know you’re affected and leave a comment with instructions to reproduce, along with any other relevant details. Those instructions and other details help us respond to the issues more effectively, so please be sure to include them.

Happy scripting!


Google Apps Script has always provided a simple logging tool—the Logger service—to help developers better test their scripts. This works for many simple use cases, but developers need other ways to log messages and errors, particularly when:
  • Troubleshooting or analyzing scripts across multiple executions
  • Working on a script or add-on with multiple users 
  • Looking for trends or insights about their scripts and users
To make Apps Script a friendlier environment for developers, we are announcing general availability of a new integration with Google Stackdriver. This is in addition to the pre-existing Logger service, which is still available.

Using Stackdriver Logging in Google Apps Script

Log messages can now be sent to Stackdriver Logging using the familiar console.log(), console.info(), etc. functions. You can also instruct Apps Script to log messages and stack traces for all exceptions, which also become available for analysis in Stackdriver Error Reporting by simply checking a box. No need to add a single extra line of code.

In Stackdriver, logs are kept for 7 days for free, and the premium tier offers 30-day retention. Powerful search and filtering are available to quickly find log entries by text content or metadata, and developers can also choose to export logs to BigQuery, Cloud Storage, and Cloud Pub/Sub for further analysis, long term conservation, and custom workflows.

Log messages and errors are reported for all users of a script, with a unique but obfuscated identifier assigned to each user. This means log entries can be aggregated anonymously per user, for example allowing developers to count unique users impacted by an issue or analyze user behavior, but without logging users’ personally identifying information.


Developers get some of these aggregated analyses for free. In the Stackdriver Error Reporting tab of the developer console, you can see recurring errors and the numbers of users impacted. You can even subscribe to receive an email alert when a new type of error is detected.


How developers are using Stackdriver Logging

Developers of scripts and add-ons have started to rely more on more on this new logging capability. Romain Vialard, creator of Yet Another Mail Merge, a popular Google Sheets add-on, is using Stackdriver Logging to time the execution of his add-on, exporting data to BigQuery to perform aggregations and analyze trends. Read this tutorial to learn how to export logs to BigQuery and run queries to analyze how users are interacting with your script.

Stackdriver Logging is one of the ways we’re making Apps Script a more manageable platform for developers. We hope that it and other features coming soon make Apps Script developers more productive and their scripts, add-ons and integrations more robust.

You can read more about how to enable and use the Stackdriver integration by reading Apps Script’s logging documentation.

About the authors 

Romain Vialard is a Google Developer Expert. After some years spent as a consultant, he is now focused on products for G Suite (formerly Google Apps) users, including add-ons such as Yet Another Mail Merge and Form Publisher.

Paul McReynolds is a Product Manager at Google focused on Apps Script and G Suite Marketplace. Previously a startup founder and CTO, Paul believes that the easy things need to be easy or the hard things don’t get done. At Google, he's excited to be a part of the company that makes solving problems for business fun again.

Editor's note: Yet Another Mail Merge and Form Publisher are not created, sponsored, or supported by Google.



Last fall, we launched the Google Slides API. Since then, partners, developers and others have been building apps and tools to programmatically create slides that work across desktop and mobile, like the ever popular md2googleslides.

We recently released the Slides API Codelab, which walks you through an example of using Google’s BigQuery and Slide APIs to analyze 3.5 million repositories and create a “Top 10 OSS licenses” presentation. The codelab is a great exercise for learning the Slides API, especially if you have an interest in big data, automating the creation of presentations or open source.
Preview of our Slides Codelab

Getting started with the Slides API Codelab 

To get started, clone the repo. After running the starter script, you’ll find that creating a presentation is divided up into contained steps. These “TODOs” are shown when running the sample app in the start directory.
-- Start generating slides. --
TODO: Get Client Secrets
TODO: Authorize
TODO: Get Data from BigQuery
TODO: Create Slides
TODO: Open Slides
-- Finished generating slides. --

To query GitHub, BigQuery has a public dataset all ready just for you! BigQuery allows you to query massive datasets on Google’s infrastructure in seconds. On bigquery.cloud.google.com, you can explore BigQuery’s public datasets or upload your own. In this codelab, we’re interested in open source licenses, so we'll query public repos on GitHub and grab their licenses.
WITH AllLicenses AS (
  SELECT * FROM `bigquery-public-data.github_repos.licenses`
)
SELECT
  license,
  COUNT(*) AS count,
  ROUND((COUNT(*) / (SELECT COUNT(*) FROM AllLicenses)) * 100, 2) AS percent
FROM `bigquery-public-data.github_repos.licenses`
GROUP BY license
ORDER BY count DESC
LIMIT 10
Our GitHub Open Source Licenses Query
With an infinite number of public and private datasets out there, imagine all the data you can analyze with BigQuery and all the slide decks you can auto-generate with the Google Slides API! The goal of the Slides API Codelab is to get you up-to-speed quickly using both. For issues or questions regarding the Slides API or this codelab, ask us a question on GitHub or Stack Overflow.

We can't wait to see what you build.



We’re constantly working to secure our users and their data. Earlier this year, we detailed some of our latest anti-phishing tools and rolled-out developer-focused updates to our app publishing processes, risk assessment systems, and user-facing consent pages. Most recently, we introduced OAuth apps whitelisting in G Suite to enable admins to choose exactly which third-party apps can access user data.

Over the past few months, we’ve required that some new web applications go through a verification process prior to launch based upon a dynamic risk assessment.

Today, we’re expanding upon that foundation, and introducing additional protections: bolder warnings to inform users about newly created web apps and Apps Scripts that are pending verification. Additionally, the changes we're making will improve the developer experience. In the coming months, we will begin expanding the verification process and the new warnings to existing apps as well.

Protecting against unverified apps 

Beginning today, we’re rolling out an “unverified app” screen for newly created web applications and Apps Scripts that require verification. This new screen replaces the “error” page that developers and users of unverified web apps receive today.

The “unverified app” screen precedes the permissions consent screen for the app and lets potential users know that the app has yet to be verified. This will help reduce the risk of user data being phished by bad actors.

The "unverified app" consent flow

This new notice will also help developers test their apps more easily. Since users can choose to acknowledge the ‘unverified app’ alert, developers can now test their applications without having to go through the OAuth client verification process first (see our earlier post for details).

Developers can follow the steps laid out in this help center article to begin the verification process to remove the interstitial and prepare your app for launch.

Extending security protections to Google Apps Script 

We’re also extending these same protections to Apps Script. Beginning this week, new Apps Scripts requesting OAuth access to data from consumers or from users in other domains may also see the "unverified app" screen. For more information about how these changes affect Apps Script developers and users, see the verification documentation page.

Apps Script is proactively protecting users from abusive apps in other ways as well. Users will see new cautionary language reminding them to “consider whether you trust” an application before granting OAuth access, as well as a banner identifying web pages and forms created by other users.
Updated Apps Script pre-OAuth alert with cautionary language
Apps Script user-generated content banner

Extending protections to existing apps 

In the coming months, we will continue to enhance user protections by extending the verification process beyond newly created apps, to existing apps as well. As a part of this expansion, developers of some current apps may be required to go through the verification flow.

To help ensure a smooth transition, we recommend developers verify that their contact information is up-to-date. In the Google Cloud Console, developers should ensure that the appropriate and monitored accounts are granted either the project owner or billing account admin IAM role. For help with granting IAM roles, see this help center article.

In the API manager, developers should ensure that their OAuth consent screen configuration is accurate and up-to-date. For help with configuring the consent screen, see this help center article

We’re committed to fostering a healthy ecosystem for both users and developers. These new notices will inform users automatically if they may be at risk, enabling them to make informed decisions to keep their information safe, and will make it easier to test and develop apps for developers.



If you’re a G Suite admin (or a developer creating apps for admins), it’s important to understand the various applications your company’s employees are using and how they’re accessing them. Today, we’re making that easier by introducing app identification (i.e. originating_app_id) in the Google Drive audit logs within the Admin SDK Reports API.

Now, your apps will be able to determine whether an activity logged was performed by a user in the Drive Android app, Drive iOS app, Google Chrome, or through a variety of other third-party apps that leverage, modify or create files within Google Drive, like Smartsheet or Asana. This will give you a better sense of the apps being used in your organization, as well as the extent and context of that usage.

Note that App IDs that show up in the logs will be numeric. Should you want to retrieve app names, a separate request using the Google Drive REST API is needed. If you already retrieve information through the Drive activity request, you should start seeing the originating_app_ids show up in your logs. Here are a pair of HTTP requests you can use to query this information:

GET 
https://www.googleapis.com/admin/reports/v1/activity/users/userKey

Or
GET 
https://www.googleapis.com/admin/reports/v1/activity/users/all/applications/drive

To learn more about this new feature, take a look at the documentation, then integrate into your code so you and other G Suite admins can gain a better understanding of app usage in your domain(s). We look forward to seeing what you build!


Starting today, the Google People API will get new endpoints for contacts and contact groups. Last year, we launched the Google People API with read-only endpoints with plans to eventually replace the old Contacts API. We’re one step closer to that goal by adding write endpoints that allow developers to create, delete and update a single contact. In addition, there are new contact group endpoints that allow developers to read and write contact groups.

Applications need to be authorized to access the API so to get started, you will need to create a project on the Google Developers Console with the People API enabled to get access to the service. All of the steps to do so are here. If you’re new to the Google APIs and/or the Developers Console, check out this video, the first in a series of videos to help you get up-to-speed.


Once you’re authorized, you can simply create new contacts like this (using the Google APIs Client Library for Java):
Person contactToCreate = new Person();

List names = new ArrayList<>();
names.add(new Name().setGivenName("John").setFamilyName("Doe"));
contactToCreate.setNames(names);

Person createdContact =
    peopleService.people().createContact(contactToCreate).execute();

The scope your app needs to authorize with is https://www.googleapis.com/auth/contacts. Full documentation on the people.create method is available here. You can update an existing contact like this:

String resourceName = "people/c12345"; // existing contact resource name
Person contactToUpdate = peopleService.people().get(resourceName)
    .setPersonFields("names,emailAddresses")
    .execute();

List emailAddresses = new ArrayList<>();
emailAddresses.add(new EmailAddress().setValue("john.doe@gmail.com"));
contactToUpdate.setEmailAddresses(emailAddresses);

Person updatedContact = peopleService.people().updateContact(contactToUpdate)
    .setUpdatePersonFields("emailAddresses")
    .execute();

Full documentation on the people.update  method is available here. We look forward to seeing what you can do with these new features allowing you to modify contacts. To learn more about the People API, check out the official documentation here.


You might be using the Google Calendar API, or alternatively email markup, to insert events into your users’ calendars. Thankfully, these tools allow your apps to do this seamlessly and automatically, which saves your users a lot of time. But what happens if plans change? You need your apps to also be able to modify an event.

While email markup does support this update, it’s limited in what it can do, so in today’s video, we’ll show you how to modify events with the Calendar API. We’ll also show you how to create repeating events. Check it out:

Imagine a potential customer being interested in your product, so you set up one or two meetings with them. As their interest grows, they request regularly-scheduled syncs as your product makes their short list—your CRM should be able to make these adjustments in your calendar without much work on your part. Similarly, a “dinner with friends” event can go from a “rain check” to a bi-monthly dining experience with friends you’ve grown closer to. Both of these events can be updated with a JSON request payload like what you see below to adjust the date and make it repeating:
var TIMEZONE = "America/Los_Angeles";
var EVENT = {
    "start": {"dateTime": "2017-07-01T19:00:00", "timeZone": TIMEZONE},
    "end":   {"dateTime": "2017-07-01T22:00:00", "timeZone": TIMEZONE},
    "recurrence": ["RRULE:FREQ=MONTHLY;INTERVAL=2;UNTIL=20171231"]
};

This event can then be updated with a single call to the Calendar API’s events().patch() method, which in Python would look like the following given the request data above, GCAL as the API service endpoint, and a valid EVENT_ID to update:
GCAL.events().patch(calendarId='primary', eventId=EVENT_ID,
    sendNotifications=True, body=EVENT).execute()

If you missed it, check out this video that shows how you can insert events into Google Calendar as well as the official API documentation. Also, if you have a Google Apps Script app, you can programmatically access Google Calendar with its Calendar service.

We hope you can use this information to enhance your apps to give your users an even better and timely experience.



Enterprises are always looking for ways to operate more efficiently, and equipping developers with the right tools can make a difference. We launched Team Drives this year to bring the best of what users love about Drive to enterprise teams. We also updated the Google Drive API, so that developers can leverage Team Drives in the apps they build.

In this latest G Suite Dev Show video, we cover how you can leverage the functionality of Team Drives in your apps. The good news is you don’t have to learn a completely new API—Team Drives features are built into the Drive API so you can build on what you already know. Check it out:

By the end of this video, you‘ll be familiar with four basic operations to help you build Team Drives functionality right in your apps:
  1. How to create Team Drives 
  2. How to add members/users to your Team Drives 
  3. How to create folders in Team Drives (just like creating a regular Drive folder) 
  4. How to upload/import files to Team Drives folders (just like uploading files to regular folders) 
The Drive API can help a variety of developers create solutions that work with both Google Drive and Team Drives. Whether you’re an Independent Software Vendor (ISV), System Integrator (SI) or work in IT, there are many ways to use the Drive API to enhance productivity, help your company migrate to G Suite, or build tools to automate workflows.

Team Drives features are available in both Drive API v2 and v3, and more details can be found in the Drive API documentation. We look forward to seeing what you build with Team Drives!



Every company has workflows and processes that are unique to its business, customers and employees. Often, these are captured manually within large spreadsheets or ad-hoc databases with macros and scripts. But what if they could be turned into custom business apps instead? Apps that provide useful UIs and distinct user roles, while helping to minimize data entry errors and increase productivity?

This year at Google I/O, I shared reasons why businesses should use App Maker—our low-code, application development tool that lets companies quickly build custom apps in G Suite. Check it out here:


And for those who’d like more detail, here is a recap of my presentation.

Closing enterprise “app gaps” with App Maker 

“App gaps” are a reality for most companies, even those that embrace major SaaS products. Think about the edge cases that aren’t addressed with a standard CRM offering like conducting territory planning or tracking asset performance.

We experienced similar gaps at Google. A few years ago, our HR recruiters were overwhelmed with the thousands of monthly interviews that each generated lengthy feedback reports from multiple interviewers. This volume made it difficult for hiring committees to calibrate candidates and make timely decisions, and resulted in delayed responses. To fix this, our IT team decided to build an app by cobbling elements from our own infrastructure.

Over time, more app requests came in from other parts of Google, so we created App Maker. What started as a handful of apps within Google, evolved into nearly 400 internal apps used by thousands. Plus, the majority of these apps were built by non-engineers outside of IT.

Today, App Maker gives software engineers and citizen developers—like business analysts or coding enthusiasts—the ability to quickly build and deploy apps to get around their workflow challenges.

How does it work? 

App Maker makes it easy to build apps in days, not months, because of its easy data-binding and drag-and-drop UI design. You can also integrate your apps with various data sources, Google services or APIs to cover broad legacy assets. Any app you create is also a part of Drive in G Suite so your data never leaves your domain.

Here’s how to build an App Maker app in three steps:
  1. Define your data models, by importing existing Google Sheets to App Maker, connecting to Google Cloud SQL instances, or manually defining custom objects field by field.
  2. Build your UI by adding pre-built components like data entry forms, report templates and easily create event triggers and application flows. 
  3. Optionally, add open source HTML, CSS and JavaScript to run on the client UI and on the app server, implementing custom functionality that’s not provided out-of-the-box.
App Maker is currently in Early Adopter Program (EAP) for every G Suite Business customer. To get started, apply here.

Ideas to get started 

By now you’re probably wondering what you can build. Well, based on our customers’ experience, here are some good starting points:
  • If you have a large Sheet with more than a handful of users updating it regularly: Sheets usually have an underlying workflow. An App Maker app will provide a better UI for it—showing the workflow visually, prompting for actions and eliminating data entry errors. 
  • If you perform recurring bulk operations in Calendar or Gmail: Say an employee joins or leaves a department, you can build an App Maker app to generate the appropriate bulk-operations in a few clicks. 
  • If your company is already using Apps Script and BigQuery: This means you’ve already invested in customizing workflows. App Maker can increase the velocity of developing custom apps.
Go build your apps with App Maker in G Suite—sign up for the EAP today.




Last week, we took immediate action to protect users from a phishing attack that attempted to abuse the OAuth authorization infrastructure.

Today, we’re supplementing those efforts to help prevent these types of issues in the future. These changes may add some friction and require more time before you are able to publish your web application, so we recommend that you plan your work accordingly.

Updating app identity guidelines 

As our Google API user data policy states, apps must not mislead users. For example, app names should be unique to your application and should not copy others'.

To further enforce this policy, we are updating our app publishing process, our risk assessment systems, and our user-facing consent page in order to better detect spoofed or misleading application identities. You may see an error message as you’re registering new applications or modifying existing application attributes in the Google API Console, Firebase Console, or Apps Script editor as a result of this change.

New review processes and restrictions on web apps requesting user data 

We have also enhanced our risk assessment for new web applications that request user data.

Based on this risk assessment, some web applications will require a manual review. Until the review is complete, users will not be able to approve the data permissions, and we will display an error message instead of the permissions consent page. You can request a review during the testing phase in order to open the app to the public. We will try to process those reviews in 3-7 business days. In the future, we will enable review requests during the registration phase as well.

You can continue to use your app for testing purposes before it is approved by logging in with an account registered as an owner/editor of that project in the Google API Console. This will enable you to add additional testers, as well as initiate the review process.

We also recommend developers review our earlier post outlining their responsibilities when requesting access to user data from their applications. Our teams will continue our constant efforts to support a powerful, useful developer ecosystem that keeps users and their data safe.



Last year, we launched Quizzes in Google Forms to help teachers and students take assessment to scale. Using Quizzes, teachers are able to automate testing and give feedback to students faster by having Forms check responses against correct answers automatically. Today, we are making that functionality available to developers by extending the Google Apps Script Forms Service. With this feature, you can create and customize quizzes programmatically with Apps Script.

More specifically:
  • Create quizzes 
  • Assign point values and correct answers for questions 
  • Implement custom grading schemes 
Let’s take a look at an example use case and relevant code snippet.

Creating an auto-graded question 

Multiple choice, checkbox and dropdown questions can be auto-graded, which means students can see their grades immediately upon submission. This is done by designating which options are the correct answer. Teachers can also set automatic feedback to show correct or incorrect responses, as well as assign point values to the question.

Here is the Apps Script code that lets you create the quiz above:
function createGradedCheckboxQuestionWithAutofeedback() {
  // Make sure the form is a quiz.
  var form = FormApp.getActiveForm();
  form.setIsQuiz(true);

  // Make a 10 point question and set feedback on it
  var item = FormApp.getActiveForm().addCheckboxItem();
  item.setTitle("What flavors are in neapolitan ice cream?");
  item.setPoints(10);
  // chocolate, vanilla, and strawberry are the correct answers
  item.setChoices([
    item.createChoice("chocolate", true),
    item.createChoice("vanilla", true),
    item.createChoice("rum raisin", false),
    item.createChoice("strawberry", true),
    item.createChoice("mint", false)
  ]);
  // If the respondent answers correctly, they'll see this feedback when they view 
  //scores.
  var correctFeedback = FormApp.createFeedback()
      .setText("You're an ice cream expert!")
      .build();
  item.setFeedbackForCorrect(correctFeedback);
  
  // If they respond incorrectly, they'll see this feedback with helpful links to 
  //read more about ice cream.
  var incorrectFeedback = FormApp.createFeedback()
      .setText("Sorry, wrong answer")
      .addLink(
        "https://en.wikipedia.org/wiki/Neapolitan_ice_cream",
        "Read more")
      .build();
  item.setFeedbackForIncorrect(incorrectFeedback);
}
For more details on what you can build with the Apps Script Forms Service, review the documentation, ask questions on Stack Overflow or in the G+ community, and let us know what else you’d like to see using the new public issue tracker for Apps Script.



We recently demonstrated how to use field masks to limit the amount of data that comes back via response payloads from read (GET) calls to Google APIs. Today, we’ll focus on a different use case for field masks: update requests.

In this scenario, field masks serve a different, but similar purpose—they still filter, but function more like bitmasks by controlling which API fields to update. The following video walks through several examples of update field mask usage with both the Google Sheets and Slides APIs. Check it out.
2
In the sample JSON payload below, note the request to set the cells' bold attribute to true (per the cell directive below), then notice that the field mask (fields) practically mirrors the request:
{
    "repeatCell": {
        "range": {
            "endRowIndex": 1
        },
        "cell": {
            "userEnteredFormat": {
                "textFormat": {
                    "bold": true
                }
            }
        },
        "fields": "userEnteredFormat/textFormat/bold",
    }
}
Now, you might think, “is that redundant?” Above, we highlighted that it takes two parts: 1) the request provides the data for the desired changes, and 2) the field mask states what should be updated, such as the userEnteredFormat/textFormat/bold attribute for all the cells in the first row. To more clearly illustrate this, let’s add something else to the mask like italics. Here, the updated field mask now has both bold and italic fields:
"fields": "userEnteredFormat/textFormat(bold,italic)"

However, while both elements are in the field mask, we’ve only provided the update data for bold. There’s no data for italic setting specified in the request body. In this case, for all cells will be reset, meaning if the cells were originally italicized, those italics will be removed after this API request completes. And vice versa, if the cells were not italicized to begin with, they’ll stay that way. This feature gives developers the ability to undo or reset any prior settings on affected range of cells. Check out the video for more examples and tips for using field masks for update requests.

To learn more about using field masks for partial response in API payloads, check out this video and the first post in this two-part series. For one of the most comprehensive write-ups on both (read and update) use cases, see the guide in the Google Slides API documentation.  Happy field-masking!



Developers using Google Apps Script can now access the richer feature set of the updated Google Sheets API with the recent launch of the Advanced Sheets Service. One key benefit of using an advanced service vs. native Apps Script objects, is that developers can access current API features (without having to wait for native support to come along). For example, the advanced service allows developers to access Sheets filters which make Add-ons more engaging.

Filter functionality 

With the Sheets API, developers can already get filtered rows or set new filters on Sheets data. With the Advanced Sheet Service, developers can now have their Add-ons respect those filters and apply new filters to modify what data is visible in the Sheets UI. Plus, with any of the Apps Script advanced services, you can easily access the Sheets and other Google APIs without using the UrlFetch service nor managing the authorization flow that you’d otherwise have to perform if using the REST API directly. The snippet below will return the indexes of the filtered rows in a given Sheet. Note that it is also possible to retrieve the list of rows hidden manually, using the "hide row" menu item in Google Sheets, as indicated in the API documentation. In the code sample here, we’re only exposing rows hidden by filter.

 function getIndexesOfFilteredRows(ssId, sheetId) {
  var hiddenRows = [];
  
  // limit what's returned from the API
  var fields = "sheets(data(rowMetadata(hiddenByFilter)),properties/sheetId)";
  var sheets = Sheets.Spreadsheets.get(ssId, {fields: fields}).sheets;  
  
  for (var i = 0; i < sheets.length; i++) {
    if (sheets[i].properties.sheetId == sheetId) {
      var data = sheets[i].data;
      var rows = data[0].rowMetadata;
      for (var j = 0; j < rows.length; j++) {
        if (rows[j].hiddenByFilter) hiddenRows.push(j);
      }
    }
  }
  return hiddenRows;
} 
The fields parameter in the code snippet limits what's returned in the Sheets API response, requesting only the values that matter to your app. For more information, check out this page in the Sheets API doc or this recent video on field masks.

See how some Add-ons use filtering 

There are a number of Add-ons that use advanced filtering in Sheets. Here are some good examples:
  • Yet Another Mail Merge: this Add-on helps users send email campaigns from a spreadsheet and is built to process only the filtered rows of a Sheet. Let's say you have a list of people who are registered for an event, but you've only accepted some of these registrants and need to send an email confirmation. With Yet Another Mail Merge and the updated API, you can filter out people you don't approve to attend and the Add-ons skips them without sending confirmations.
  • Sankey Snip and Chord Snip: these Add-ons helps users create special chart types that aren't available in the Google Sheets UI. When respecting filters is enabled with these Add-ons, the charts will dynamically visualize filtered data. Check out the example below from the Chord Snip Add-on.
Of course the API also provides the ability to add, update or delete filters on a Sheet. This is useful if you want to quickly display rows with a specific status to your users. One example would be if you built a workflow approval Add-on. You can show the user rows that are waiting for approval. The snippet below applies the requested filter on a given Sheet—the API documentation describes a standard basic filter object:

function setSheetBasicFilter(ssId, BasicFilterSettings) {
  //requests is an array of batchrequests, here we only use setBasicFilter
  var requests = [
    {
      "setBasicFilter": {
        "filter": BasicFilterSettings
      }
    }
  ];
  Sheets.Spreadsheets.batchUpdate({'requests': requests}, ssId);
}

Yet Another Mail Merge, as many mass-mailing tools do, keeps track of all emails sent, opened and clicked. A tracking report is available in the spreadsheet sidebar, and clicking on the number of emails opened will automatically apply a filter to display only the matching rows—all rows with the status “opened.”

Now, you can determine filters applied in a Sheet directly through the Sheets API or through Apps Script apps and Add-ons using the Advanced Sheets Service, and continue to build the best experience for your users.

About the Authors 

Romain Vialard is a Google Developer Expert. After some years spent as a G Suite consultant, he is now focused on products for G Suite and Google Apps users, including add-ons such as Yet Another Mail Merge and Form Publisher.

Bruce Mcpherson is a Google Developer Expert, an independent consultant, blogger and author of Going GAS, Google Apps Script for Beginners, and Google Apps Script for Developers.



You might have read that we launched new metrics in the Admin SDK Reports API to help you gain reliable, easily-validated perspectives about users within your domain. Today, we're building on these features by giving administrators and developers even greater visibility into how files are shared both inside and outside of domain. These changes include:
  1. New metrics to supplement the set of metrics we launched last year 
  2. New visibility information for audit events 
  3. Deprecation of existing metrics from the Reports API

New Metrics

We’ve created a new set of metrics to complete the set we launched last year. With these new metrics you can:
  • Gain insight into the visibility of files and their sharing state, which is useful for security and reporting. This will replace these older metrics:
    num_docs_internally_visible, num_docs_externally_visible, num_docs_shared_outside_domain.
  • Report on product adoption within your domain with summary statistics about groups of users (collaborators, viewers, creators and sharers). Take advantage of key adoption metrics such as 1-, 7-, and 30-day active users for Google Drive, Docs, Sheets, Slides, Forms, Drawings and more. 
  • Simplify your calculation of “what has changed” in your domain using delta metrics which pre-calculate changes in visibility and items owned.

New Visibility Information 

Now, new visibility information is attached to every audit event which helps you quickly identify the permission change events that lead to files being shared differently both within and outside your domain. Learn more.

Deprecating Existing Metrics 

While we’re aware of the need to have reliable and timely data about your domain’s users and files on Google Drive, Drive’s data and infrastructure has grown considerably, requiring us to make some difficult technical tradeoffs regarding metrics. As a result, today marks the beginning of a 12-month deprecation timeline that will retire these existing metrics from the Reports API and eventually the Admin Console. These metrics will no longer be available starting May 14, 2018.

To get started using the Reports API and see all the different types of metrics you can report on for your domain, check out the official documentation. We hope you find these features useful in your reporting.