Doodles for Google Apps


Since 1998, when the first doodle was released, they have been one of the most loved features of the Google home page. There have been doodles to celebrate all kinds of events, including national holidays, birthdays of artists and scientists, sports competitions, scientific discoveries and even video games! Also, doodles have evolved from simple static images to complex applications, such as the interactive electric guitar used to celebrate the birthday of Les Paul.

Want your company logo to change for selected events or holidays, just like doodles? The Admin Settings API allows domain administrators to write scripts to programmatically change the logo of their Google Apps domain, and Google App Engine offers the ability to configure regularly scheduled tasks, so that those scripts can run automatically every day.

With these two pieces combined, it is pretty easy to implement a complete solution to change the domain logo on a daily basis (assuming the graphic designers have prepared a doodle for each day), as in the following screenshot:


Let’s start with a Python App Engine script called

import gdata.apps.adminsettings.service
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from datetime import date

class DoodleHandler(webapp.RequestHandler):
  # list of available doodles
  DOODLES = {    
    '1-1': 'images/newyearsday.jpg',
    '2-14': 'images/valentinesday.jpg',
    '10-31': 'images/halloween.jpg',
    '12-25': 'images/christmas.jpg'

  # returns the path to the doodle corresponding to the date
  # or None if no doodle is available
  def getHolidayDoodle(self, date):
    key = '%s-%s' % (date.month,
    if key not in self.DOODLES:
      return None

    return self.DOODLES[key]

  # handles HTTP requests by setting today’s doodle
  def get(self):
    doodle = self.getHolidayDoodle(

    if doodle:
      service = gdata.apps.adminsettings.service.AdminSettingsService()
      // replace domain, email and password with your credentials
      // or change the authorization mechanism to use OAuth
      service.domain = 'MYDOMAIN.COM' = 'ADMIN@MYDOMAIN.COM'
      service.password = 'MYPASSWORD'
      service.source = 'DoodleApps'

      # reads the doodle image and update the domain logo
      doodle_bytes = open(doodle, "rb").read()

# webapp initialization
def main():
    application = webapp.WSGIApplication([('/', DoodleHandler)],

if __name__ == '__main__':

The script uses a set of predefined doodles which can be edited to match your list of images or replaced with more sophisticated logic, such as using the Google Calendar API to get the list of holidays in your country.

Every time the script is triggered by an incoming HTTP request, it will check whether a doodle for the date is available and, if there is one, update the domain logo using the Admin Settings API.

In order for this script to be deployed on App Engine, you need to to configure the application by defining a app.yaml file with the following content:

application: doodleapps
version: 1
runtime: python
api_version: 1

- url: .*

We want the script to run automatically every 24 hours, without the need for the administrator to send a request, so we also have to define another configuration file called cron.yaml:

- description: daily doodle update
  url: /
  schedule: every 24 hours

Once the application is deployed on App Engine, it will run the script on a daily basis and update the logo.

Visibility versus Authentication and Authorization: Service On/Off

You may have already noticed, but the controls to enable and disable individual apps in Google Apps are now all in one place on the domain Control Panel under Organization & users > Services.

Domain administrators were already able to use this tab to enable and disable the Core Google Apps suite. Now they can do the same for apps they’ve acquired from the Google Apps Marketplace. This replaces the old link labeled “Disable {app name}” in the Dashboard > {app name} > “App status” page.

App and Gadget Visibilty

This on/off switch controls app and gadget visibility. Users in suborganizations where a Marketplace App is ON will see that app in the universal navigation bar under “More”, and will see the app’s contextual gadgets in Gmail. Users where the App is OFF will not see these links or gadgets.

Your customers still configure all apps through the Dashboard tab, but now the Control Panel Services tab unifies how they enable and disable every app.

New Scoping by Suborganization

The unified controls also share an important new scoping capability: now a domain administrator can select a suborganization and control which Marketplace Apps are visible to that organizational unit, just like the Core Google Apps suite!

In the example below, the administrator has overridden the domain settings for four Marketplace Apps to make three new tools visible to just the “Engineering” suborganization and to hide one application.

Visibility versus Authentication and Authorization

As developers, you should note that for any valid Google Apps domain user who goes directly to your website, OpenID/Single Sign On will always authenticate them if their domain has OpenID enabled. This includes users who are in suborganizations where your app is OFF. That means this visibility toggle feature is not a substitute for checking that the users accessing your app have a valid license.

Similarly, the on/off switch does not affect the OAuth scopes your app has been granted when the domain admin installed your app — the admin only revokes those by explicitly revoking data access or by deleting your app. The control panel on/off switch is just a way for a domain administrator to control the visibility of apps and gadgets that would otherwise be site-wide.

Help your customers stay in touch with Google Contacts

A while back we began a series of articles about integrating with Google Apps and the Google Apps Marketplace, starting with how to make a great first impression on your users. Today we’re continuing that series with an eye on collaboration and the various “people” APIs in Google Apps — Contacts, Shared Contacts, Profiles, and Provisioning.

Why contacts? Contacts data is used pervasively and makes it easier to share documents, arrange meetings, or communicate in general. It’s synced with mobile phones & email clients. Many apps in the Google Apps Marketplace use contacts to help users share projects and assign tasks to coworkers. In short, the contacts APIs act as a hub for applications and devices to share important information about the people users communicate and collaborate with the most!

Untangling the APIs

Before jumping in to how to use these APIs to make work easier for users, let’s take a step back and look at the role of each API.

Contacts API – This API provides access to an individual user’s personal contacts & is available to all users on all editions of Google Apps. Each user manages their own contacts separately.

Shared Contacts API – The shared contacts API is available only to Google Apps for Business and Education editions, and provides a way for domain administrators to manage a global address list of external (non-employee) contacts viewable by all users in the domain.

Profiles API – Like the Shared Contacts API, the profiles API is only available for Google Apps for Business and Education education, and is managed by domain administrators. But while shared contacts can be used to manage contact information for people outside the domain, the Profiles API is exclusively for managing contact information for users in the domain.

Provisioning API – A distant cousin of the others, the Provisioning API allows domain administrators to manage users, groups, and organizational units in their domain. While the full version of the API is restricted to Google Apps for Business & Education editions, all editions support a read-only view of the data and it can be a quick and easy way to discover organizational information for a domain.

Speeding Setup

As mentioned in our earlier post on creating a good initial experience, these APIs, can be a great way to help administrators set up and configure applications quickly. The provisioning API in particular is well suited to this and provides user, group, and organizational data for a domain.

Expensify uses the provisioning API to quickly configure roles and reporting relationships for submitting expense reports.

Making Users More Productive

There are a variety of ways to use the various contacts APIs to help users save time and be more productive. Project & task management apps often benefit from importing contact information to speed user entry.

Manymoon’s project management app helps users assign tasks quicker by auto-completing names as the user types.

Likewise, CRM and marketing automation apps can also speed user adoption and reduce the need for time consuming data entry by importing existing customer data stored in contacts.

Importing contacts to Bantam Live

Share and Share Alike

For applications that aim to be the system of record for contact or employee information, pushing data to Google Apps can be a big win both for users and developers. Syncing contact data with Google Apps means syncing with every other application and device that syncs as well. It allows developers to magnify the reach of their integrations and lets users access important partner data no matter what the context.

Sharing contacts with BatchBook

Full bi-directional contacts synchronization is more challenging. It can be equally rewarding. Not only does it allow users to edit contacts in context, it can enable innovative new services that seamless enhance data without disrupting how users work.

Rainmaker’s bi-directional sync automatically enhances contacts with data from social networks and other sources.

While the example so far have focused on the Contacts API and individual users, synchronization with the Shared Contacts API can provide added value for larger organizations on Google Apps for Business.

As our friends over at Manymoon wrote not too long ago, they learned three key lessons about what it takes to be successful in the Google Apps Marketplace: Appeal to a broad audience, integrate deeply, and demonstrate immediate value. Integration with contacts & provisioning APIs is a great way to do accomplish those goals that just about any app can benefit from!