Category Archives: Google Apps Developer Blog

Information for Google Apps Developers

Drive Google Apps Marketplace installs from your site



To increase the discovery of your Google Apps Marketplace listings, you can now embed an Integrate with Google button on your website, marketing pages, blog posts, and other properties. This lets domain administrators install your apps with a single click without leaving your site. Once they click the button, administrators can enable your app for all users (or just some of them) just like they would from the Google Apps Marketplace.

Here’s what the Integrate with Google button looks like on CloudLock.com:



To put the Integrate with Google button on your site, just embed the code below anywhere you want to display the button:
<script src="https://apis.google.com/js/platform.js"></script>
<div class="g-additnow" data-applicationid="your-app-id"></div>
Check out the developer documentation to start integrating today.

Hiranmoy Saha Google+

Hiranmoy Saha is a Software Engineer working on the Google Apps Ecosystem.

More Apps Script APIs and Features

Developers like you have built amazing scripts with Apps Script, and we want to make Apps Script even more useful. We've been working hard to add a variety of new APIs and features in Google Apps Script. Today, we're ready to share a few of them with you.


New in Document service: named ranges, bookmarks, setting cursor or selection, and undo

Named ranges are a popular feature of the Spreadsheet service; and now, you’ll be able to do something similar in the Document service. With named ranges, your scripts can tag a section of a Google Doc for later reference. For example, a bibliography script could set a named range on every citation in a document, then easily update the citations in the future.


You can use a similar API to manage bookmarks, too. Unlike named ranges, bookmarks are visible to the user and allow you to link to a particular place in a document.

Also for Google Docs, we've added the server-side methods setCursor(position) and setSelection(range) to change the user's cursor position or active selection, plus a client-side method, google.script.host.editor.focus(), which switches the browser focus from a sidebar or dialog back to the document.

Oh, and hey: the Undo command in Google Docs can now revert changes made by a script.


New in HTML service: NATIVE mode by default

If you've used HTML service much, you'll know that the Caja security sandbox has two modes. NATIVE mode imposes fewer restrictions than EMULATED mode and generally runs faster. As of today, NATIVE is now the default if you have not specified which mode your script should use. In a few edge cases, this may affect how existing web apps operate; if so, simply append .setSandboxMode(HtmlService.SandboxMode.EMULATED) to your HtmlOutput object to restore the old behavior.


Revised Properties service

In preparation for future improvements to Apps Script, we've revamped script properties and user properties, combining them into a unified Properties service and adding the notion of document properties, which are (surprise!) specific to a particular document, but shared among all collaborators. The biggest change is that user properties are no longer shared between scripts, but our guide to the Properties service provides all the details. As part of the change, the old ScriptProperties and UserProperties services have been deprecated, although they will continue to function in existing scripts until a sunset date is announced.


Deprecation of Finance service

We’re excited to bring you these new tools. With these new additions, we have also deprecated Finance service. It will remain available for the next six months but will be turned off on September 26, 2014.


Saurabh Gupta   profile | twitter | blog

As the product manager for Google Apps Script, Saurabh is responsible for Apps Script’s overall vision and direction.

Building a Rails based app for Google Apps Marketplace

Editor's note: This is a guest post by Benjamin Coe. Benjamin shares tips and best practices on using Ruby on Rails for integrating with Google Apps and launching on the Marketplace. — Arun Nagarajan

Yesware offers an app in the Google Apps Marketplace which allows our users to schedule reminders, from directly within the Gmail UI. Yesware’s app recently relaunched in the updated Google Apps Marketplace. In prep, we revamped our existing Google Apps Integration:
  • Replacing OpenID with OAuth 2.0 for Single-Sign-On.
  • Replacing 2-legged OAuth with OAuth 2.0 Service Accounts, for delegated account access.
  • Releasing a Gmail Contextual Gadget that worked within these new authentication paradigms.
We should like to share some of the decisions we made, and challenges we faced, upgrading our production Ruby on Rails application to support the improved Google Apps Marketplace.

OAuth 2.0 for SSO

In the revamped Google Apps Marketplace, OAuth 2.0 replaces OpenID for facilitating Single-Sign-On. The flow is as follows:

  1. OAuth 2.0 credentials are created in the Cloud Console, within the same project that has the Google Apps Marketplace SDK enabled.
  2. When accessing your application, a user is put through the standard OAuth 2.0 authentication flow using these credentials.
  3. If the user has the Google Apps Marketplace App installed they will be logged directly into your application, skipping the authorization step.
To implement the OAuth 2.0 authentication flow, you can use the OmniAuth Google OAuth2 Strategy gem. Assuming you're already using OmniAuth, you simply add a line to initializers/omniauth.rb that looks something like this:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV["GAM_OAUTH_KEY"], ENV["GAM_OAUTH_SECRET"]
end

Yesware already had a Google OAuth 2.0 authentication strategy, so we opted to subclass the Google OAuth 2.0 OmniAuth Strategy. This allowed us to continue supporting our existing OAuth 2.0 credentials, while adding support for Google Apps Marketplace SSO. Our subclassed strategy looked like this:
# Subclass the GoogleOauth2 Omniauth strategy for
# Google Apps Marketplace V2 SSO.
module OmniAuth
module Strategies
class GoogleAppsMarketplace < OmniAuth::Strategies::GoogleOauth2
option :name, 'google_apps_marketplace'
end
end
end
Our final initializers/omniauth.rb file was this:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV["OAUTH_KEY"],
ENV["OAUTH_SECRET"],
{:scope => ENV["OAUTH_SCOPE"]}
provider :google_apps_marketplace, ENV["GAM_OAUTH_KEY"],
ENV["GAM_OAUTH_SECRET"],
{ :scope => ENV["GAM_OAUTH_SCOPE"],
:access_type => 'online' }end

Note that :access_type is set to online. This is necessary to prevent the authorization prompt from being presented to a SSO user. Omniauth defaults to an :access_type of offline.
That's all it takes. With this OmniAuth strategy in place, when a domain administrator installs your application SSO will be available across the domain.

OAuth 2.0 Service Accounts

To support Yesware's reminder functionality, we needed offline access to a user's email account. In the past, this functionality was supported through 2-legged OAuth. In the new Google Apps Marketplace paradigm, OAuth 2.0 Service Accounts are the replacement.
  • In the Cloud Console, generate a private key for the OAuth 2.0 Service Account associated with your Google Apps Marketplace project. 
  • Download the .p12 private key generated. 
  • Place this key somewhere that will be accessible by your production servers, e.g., a certificates folder in your codebase. 
We used the Google API Ruby Client gem to generate an access token from our Service Account's keys.
Using the deprecated 2-Legged OAuth based approach, our authorization logic looked like this:

Gmail.connect!(:xoauth, '[email protected]', {
token: authentication.token,
secret: authentication.secret,
consumer_key: google.key,
consumer_secret: google.secret,
read_only: true
})
Using the new Service Account Based Approach, it was as follows:
key = Google::APIClient::PKCS12.load_key(
google_apps.service.p12path, # this is a constant value Google uses
# to password protect the key.
'notasecret'
)service_account = Google::APIClient::JWTAsserter.new(
google_apps.service.email,
'https://mail.google.com/',
key
)client = Google::APIClient.new(
:application_name => APPLICATION_NAME,
:version => APPLICATION_VERSION
).tap do |client|
client.authorization = service_account.authorize('[email protected]')end
Google.connect!(:xoauth2, '[email protected]', {
:oauth2_token => client.authorization.access_token,
})
With OAuth 2.0 Service Accounts, the underlying libraries we used to interact with Gmail remained the same. There were simply a few extra steps necessary to obtain an access token.

Contextual Gadgets and SSO

Yesware provides a Gmail Contextual Gadget, for scheduling email reminders. To facilitate this, it's necessary that the gadget interact with a user's email account. To make this a reality, we needed to implement SSO through our contextual gadget. Google provides great reading material on this topic. However, the approach outlined concentrates on the deprecated OpenID-based SSO approach. We used a slightly modified approach.
Rather than OpenID, we used OAuth 2.0 for associating the opensocial_viewer_id with a user. To do this, we needed to modify our OmniAuth strategy to store the opensocial_viewer_id during authentication:
# Subclass the GoogleOauth2 Omniauth strategy for
# Google Apps Marketplace V2 SSO.
module OmniAuth
module Strategies
class GoogleAppsMarketplace < OmniAuth::Strategies::GoogleOauth2

option :name, 'google_apps_marketplace'

def request_phase

# Store the opensocial_viewer_id in the session.
# this allows us to bind the Google Apps contextual
# gadget to a user account.
if request.params['opensocial_viewer_id']
session[:opensocial_viewer_id] = request.params['opensocial_viewer_id']
end

super
end

end
end
end
Once an opensocial_viewer_id was connected to a Yesware user, we could securely make API calls from our contextual gadget. To cut down on the ritual surrounding this, we wrote a Devise Google Apps OpenSocial Strategy for authenticating the OpenSocal signed requests.

Now Go Forth

Once we figured out all the moving parts, we were able to use mostly off the shelf mature libraries for building our Google Apps Marketplace Integration. I hope that this retrospective look at our development process helps other Rails developers hit the ground running even faster than we did.
Benjamin Coe profile

Benjamin Coe cofounded the email productivity company Attachments.me, which was acquired by Yesware, Inc., in  2013. Before starting his own company, Ben was an engineer at FreshBooks, the  world’s #1 accounting solution.
Ben’s in his element when writing scalable cloud-based infrastructure, and loves reflecting on the thought-process that goes into this. A rock-climber, amateur musician, and bagel aficionado, Ben can be found roaming the streets of San Francisco.
[email protected]https://github.com/bcoe@benjamincoe

Get coding fast with Code School and the Google Drive API

The most challenging part of learning anything new is often simply getting started. Unfortunately, when it comes to programming, the first few minutes (or more!) are often occupied with cumbersome details such as setting up an environment, which results in very little time spent actually writing code. We were certain there must be a better way.

Code School has been doing exciting things with learning to program online. This is why we decided to team up with them to create a way for developers to learn to use the Google Drive API, with no setup required. In the Discover Drive course, you can learn at your own pace from your web browser. You’ll spend less time fussing with coding environments and more time writing code.

To find out what the course is all about, go check it out at Code School. Happy coding!



Cross-posted on the Google Developers Blog.

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.

Introducing push notifications and structured user search in the Admin SDK

Since we launched the Admin SDK in May 2013, we’ve been constantly improving it based on your feedback and feature requests. Our first API updates of 2014 bring some features at the top of your requests: push notifications for users, push notifications for activities, and structured user search.


Push notifications for users

Tired of polling user resources to detect changes? With push notifications for users, you can watch for changes to user resources and receive notifications from the Directory API whenever a watched user resource changes.

Check out our user notifications developer guide to learn how to improve the performances of your application by eliminating the extra network and compute costs involved with polling user resources.


Push notifications for activities

Do you want to be notified when changes to a certain document occur or specific events such as the change of a user’s password happen? With push notifications for activities you can watch for changes to activities resources, and receive notifications from the Reports API whenever a watched activity resource changes.

Check out our activities notifications developer guide to learn how to receive notifications for the activities of your interest.


Structured user search

Do you want to know which users in your domain are members of a certain organization, or which users have a common manager in their reporting chain? The new query parameter we’ve just added to the users.list method of the Directory API allows you to perform rich queries over most attributes from the user profile.

For example, you can now retrieve all the users in the Human Resources org by using the query:

orgName='Human Resources'
Or you can retrieve all the users with [email protected] in their reporting chain by using the query:
manager='[email protected]'

Check out our user search developer guide for a more comprehensive guide on how to build your queries and more examples of what you can do.

Silvano Luciani  

Silvano is a Developer Programs Engineer on Google's Admin SDK. Before joining Google in 2011, he has worked in Finland, Italy, Spain and the UK, writing web based configuration management tools for ISPs, social networks, web based training materials, e-commerce apps and more.

Building an Enterprise File Server on Google Drive

Editor's note: This is a guest post by Thomas Gerber. Thomas is the CTO of Altirnao, the developer of the AODocs document management app on the Google Apps Marketplace. Thomas tells the story of his application and provides some tips for developers considering integrating with Google Apps and launching on the Marketplace. — Arun Nagarajan


Google Drive is increasingly popular in the enterprise, and many organizations would like to leverage it as a replacement for their existing on-premises file servers. Moving physical file servers to Drive provides many benefits, such as reliability, cost-effectiveness and the ability to access the files from anywhere and any device. However, the storage structure of Google Drive, where files are owned by many different users, is significantly different from the centralized organization of a file server, where everything is under the control of a small number of system administrators.

To address this problem, AODocs uses the Google Drive API to automatically transfer the ownership of files to a system account, and thus create a sort of “managed area” within Google Drive. With the Google Drive API, AODocs has complete control over the folder structure and the permissions of files owned by this system account. AODocs can be deployed in one click from the Google Apps Marketplace, which makes our application visible (and easy to try out!) for every Google Apps administrator in the world.



Companies who want to store their files on Google Drive may be concerned about losing control of their data (e.g. access to files being lost when an employee leaves the company) and controlling sharing permissions.

AODocs uses a single system account (i.e. a Google Apps account belonging to the customer’s domain, but not used by any human person) as a “proxy” to control the files. When a Google Drive files is added to an AODocs library, the ownership of the file is transferred to the AODocs system account and the file’s writersCanShare attribute is set to false, so that only AODocs is able to modify the file’s permissions afterwards.

To change the ownership of the file, we check if the system account can already access the file, and then either insert a new “owner” permission on it or use the Permissions.update method with the transferOwnership flag:

public void changeOwner(String user, String fileId, String newOwner) {
// Find what is the current permission of the new owner on the file
Permission newOwnerPermission = null;
PermissionList permissionList = RetriableTask.execute(new DrivePermissionListTask(drive.permissions().list(fileId)));
newOwnerPermission = findPermission(permissionList, newOwner);

if (newOwnerPermission == null) {
// New owner is not in the list, we need to insert it
newOwnerPermission = new Permission();
newOwnerPermission.setValue(newOwner);
newOwnerPermission.setType("user");
newOwnerPermission.setRole("owner");
Drive.Permissions.Insert insert = drive.permissions().insert(fileId, newOwnerPermission);
RetriableTask.execute(new DrivePermissionInsertTask(insert));
} else {
// New owner is already in the list, update the existing permission
newOwnerPermission.setRole("owner");
Drive.Permissions.Update update = drive.permissions().update(fileId, newOwnerPermission.getId(), newOwnerPermission);
update.setTransferOwnership(true);
RetriableTask.execute(new DrivePermissionUpdateTask(update));
}
}

Since all the files are owned by the system account, AODocs completely controls the lifecycle of the file (how they are created, in which folder they are located, who can change their permissions, who can delete them, etc). AODocs can thus provide higher-level document management features on top of Google Drive, such as configuring the retention time of deleted files, limiting external sharing to a whitelist of “trusted external domains”, or recording an audit log of file modifications.

As illustrated in the code snippet above, AODocs relies on the Google Drive API to perform all the operations on the managed files. The main challenge we had when using the Drive API was to properly handle all the error codes returned by the API calls, and make sure we make the difference between fatal errors that should not be tried again (for example, permission denied on a file) and the temporary errors that should be re-tried later (for example, “rate limit exceeded”). To handle that, we have encapsulated all our Google Drive API calls (we are using the Java client library) into a class named RetriableTask, which is responsible for handling the non-fatal errors and automatically retry the API calls with the proper exponential back-off. Here is a simplified version:

public class RetriableTask implements Callable {
[...]
private final Callable task;

[...]
@Override public T call() {
T result = null;
try {
startTime = System.currentTimeMillis();
result = task.call();
} catch (NonFatalErrorException e) {
if (numberOfTriesLeft > 0) {
// Wait some time, using exponential back-off in case of multiple attempts
Thread.sleep(getWaitTime());

// Try again
result = call();
} else {
// Too many failed attempts: now this is a fatal error
throw new RetryException();
}
} catch (FatalErrorException e) {
// This one should not be retried
Throwables.propagate(e);
}
return result;
}

AODocs is designed to work seamlessly with Google Drive, and our top priority is to leverage all the integration possibilities offered by the Google APIs. We are very excited to see that new features are added very often in the Admin SDK, the Google+ API, the Drive API that will allow AODocs to provide more options to system administrators and improve the experience for our end users.


Thomas Gerber profile

Thomas is the CTO of Altirnao. Before founding Altirnao, Thomas has led a team of senior technologists and architects on High Availability/High Performance implementations of enterprise software.

Introducing the Google Drive Android API

Author PhotoBy Magnus Hyttsten, Developer Advocate, Google Drive

With today's developer preview of the Google Drive Android API in Google Play Services 4.1, you can add the convenience of Google Drive cloud storage to your apps without breaking a sweat.

While Drive integration on Android was possible in the past, the new API creates a faster, seamless experience that enables your apps to integrate with the Drive backend within minutes.

The new API offers a number of benefits:

1. Transparent use and syncing of local storage

The Google Drive Android API temporarily uses a local data store in case the device is not connected to a network. So, no need to worry about failed API calls in your app because the user is offline or experiencing a network connectivity problem. Data stored locally in this fashion will automatically and transparently be stored in the Google Drive cloud by Android’s sync scheduler when connectivity is available to minimize impact on battery life, bandwidth, and other resources.


2. Designed for Android and available everywhere

The API was developed for Android and conforms to the latest Android design paradigms, such as using the new uniform client API GoogleAPIClient. And being part of the latest release of Google Play Services provides additional benefits:
  • There’s minimal impact on the weight of your apps. As the client library is a stub to Google Play Services, incorporating the API has minimal impact on the size of your .apk binaries, resulting in faster downloads, fewer updates, and smaller execution footprint.
  • User files are automatically synced between different devices (provided the app has the same namespace and is signed with the same key).
  • Any device running the Gingerbread or later releases of Android and Google Play Services will automatically have support for the Google Drive Android API.

3. User interface components

File picker and creator user interface components are provided with this initial release of the Google Drive Android API, enabling users to select files and folders in Google Drive.


For example, the file picker is implemented as an Intent and allows you develop a native Android user experience with just a couple lines of code. This following code snippet launches the picker and allows the user to select a text file:
// Launch user interface and allow user to select file
IntentSender i = Drive.DriveApi
.newOpenFileActivityBuilder()
.setMimeType(new String[] { “text/plain” })
.build(mGoogleApiClient);
startIntentSenderForResult(i, REQ_CODE_OPEN, null, 0, 0, 0);

The result is provided in the onActivityResult callback as usual.

4. Direct access to Drive functionality

You may be wondering how the Google Drive Android API relates to the Storage Access Framework released as part of Android 4.4 KitKat.

The Storage Access Framework is a generic client API that works with multiple storage providers, including cloud-based and local file systems. While apps can use files stored on Google Drive using this generic framework, the Google Drive API offers specialized functionality for interacting with files stored on Google Drive — including access to metadata and sharing features.

Additionally, as part of Google Play services the Google Drive APIs are supported on devices running Android 2.3 Gingerbread and above.

How to get started

As you incorporate the Google Drive Android API into your apps, we hope it makes your life a little bit easier, and enables you to create fun, powerful apps that take advantage of all that Android and Google Drive can do together.

For more information visit our documentation or explore our API demo and other sample applications on the official Google Drive GitHub repository.

Also check out the official launch video:



Let’s keep the discussions going on +GoogleDrive, and Stack Overflow (google-drive-sdk).


Magnus Hyttsten is a Developer Advocate on the Google Drive team. Beyond work, he enjoys trying out new technologies, thinking about product strategies, and exploring California.

Posted by Scott Knaster, Editor

Cross posted on the Google Developers Blog.

More Google services available in Apps Script

One of things that makes Apps Script great is its ability to act as a hub for various types of Google data. In addition to our built-in services for popular products such as Gmail, Drive, Docs, and Calendar, we also provide a line of advanced Google services that let you use existing Google APIs such as Analytics and Tasks. Today, we're expanding that family of advanced services to include the following:

From Google Apps administrators and data-heads to Glass Explorers and YouTube content creators, this collection of new services has something for everyone. Getting started with advanced services is easy, since we take cake of the authorization for you and even provide autocomplete in the script editor.

While our built-in services are hand-crafted for ease-of-use, our advanced services are automatically generated from existing public Google APIs. They provide access to the full power of the underlying API but can be slightly more difficult to use. Let's look at some sample code that searches for YouTube videos with the keyword "dogs".

function searchByKeyword() {
var part = 'id,snippet';
var optionalArgs = {
q: 'dogs',
maxResults: 25
};

var results = YouTube.Search.list(part, optionalArgs);

for (var i = 0; i < results.items.length; i++) {
var item = results.items[i];
Logger.log('[%s] Title: %s', item.id.videoId, item.snippet.title);
}
}

This function uses the YouTube.Search.list() method, which has a required parameter part and optional parameters q and maxResults, among others. Required parameters are passed individually as method arguments, while optional parameters are passed as one key-value map. The full list of parameters this method accepts can be found in the YouTube API's reference documentation.

We're also changing our advanced services to behave more like vanilla JavaScript, so that it's easier to reference the APIs' existing documentation. You can now pass native JavaScript objects into these services' methods, and access the results using regular dot-notation. Below is some sample code that adds a new user to a Google Apps domain.

function addUser() {
var user = {
primaryEmail: '[email protected]',
name: {
givenName: 'Elizabeth',
familyName: 'Smith'
},
// Generate a random password string.
password: Math.random().toString(36)
};
user = AdminDirectory.Users.insert(user);
Logger.log('User %s created with ID %s.', user.primaryEmail, user.id);
}

Notice that the user resource is constructed as a plain object literal, and the ID of the created user is accessed via dot-notation. The legacy getter/setter notation will continue to work but will no longer appear in autocomplete.

Finally, it's worth reminding that advanced Google services must be enabled in each script that uses them. This involves toggling them on once in the script editor under Resources > Advanced Google services and again in the associated Google Developers Console project.


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.

New security management features for domain users with the Admin SDK

We launched the Admin SDK in May as a new way for developers to build customized administrative tools for organizations that use Google Apps. A top priority for most administrators is keeping their users safe. Today, we're adding new security management features to the Directory API to help administrators manage:

These new utilities allow Google Apps administrators to programmatically manage end-user access to third party applications, and enable third party developers to build new security management features in their applications.

As an example, FlashPanel, a popular tool used by Google Apps administrators, is using these new features to allow domain admins to review installed applications and manage or revoke access to them. The Apps Explorer in FlashPanel allows admins to see which are the most installed apps in his domain or use a filter to review applications by type of permissions (Drive, GMail, etc). It also allows admins to review the number of users who have granted access to a particular application.

The screenshot below shows an example of FlashPanel’s customized view of third-party application installs.

In FlashPanel’s integration, admins have the power to whitelist or blacklist apps, as shown below.

The Directory API now also provides the ability to manage admin notifications that are delivered to the Admin Console. Currently, admins receive notifications for events that affect their domains such as users approaching their storage limits or monthly bills that are due. Now you can use the API to list notifications, update their read status, or pull them into custom tools.

If you are interested in using these new endpoints, please refer to the Directory API documentation.

Ajay Guwalani  

Ajay Guwalani is Product Manager on Google Apps Admin APIs. His current focus is to build next generation admin APIs to make enterprise developers and admins happy.

Your apps + Google Apps = awesome

In 2013, we have made a lot of enhancements to our developer ecosystem. From the Admin SDK to the Google+ API for Domains, we've provided developers with better tools to build applications that integrate with, and add functionality to, Google Apps.

We are starting to roll out some significant changes that will make it easier for developers to build, deploy, and market applications for domain installation. This is a major improvement to our existing Google Apps Marketplace experience that we originally launched in 2010. You can get started right away by following our documentation here.

Some of the major enhancements in the new Google Apps Marketplace:

Improved security — Domain admins can install and authorize your applications for specific organizational units rather than the whole domain.
Consistent development experience — Use OAuth 2.0 for authorization and manage Google APIs in the Google Developer console.
Test before publishing — Test your app easily using the “Test Install” button in the Google Developers console vs. having to publish a live app.
Simplified publishing experience — Publish to the Chrome Web Store to use a single app listing for apps that work with both Google Drive and Google Apps for Business.
Deeper integration — Integrate with services like Google Drive and Google+ and into Google’s new app launcher.
Easier discoverability — Domain admins can discover your great apps directly from the Admin console.

We love our developers who are building third-party solutions for Google users. Please provide feedback on how we can improve the experience and help you connect with over 5 million companies that use Google Apps to improve how they get work done. Here are some great apps to get you inspired - Promevo gPanel, Draw.io, UberConference, AODocs, Spanning Calendar Undelete, Flashpanel, and MindMeister. Get started with your Google Apps integration today!



Arun Nagarajan   profile

Arun is a Developer Advocate on Google Apps. Arun works closely with the community of partners, customers and developers to help them build compelling applications on top of Google Apps. Arun is originally from the Boston area and enjoys basketball and snowboarding.