Add flexible search and Google reviews to your local apps with the Google Places API

The following article by Thor Mitchell, Product Manager, Google Places AP, describes the updates to the Google Places API.

Google Places API Update

We launched the Google Places API at Google I/O last year to enable developers to search more than 95 million places, such as businesses and landmarks, around the world. We have continued to enhance the API since then, adding a number of features requested by developers such as keyword search, rank by distance, and support for Events. At Google I/O this year we continued to respond to your feedback, with the launch of Google Reviews, Text Search, Opening Hours, and Paging.

Google Reviews

By far the most popular request from developers since the day we launched has been access to the Google Reviews offered on Google+ Local. We’re therefore delighted to announce that the top 5 Google Reviews for a Place are now included in the response to a Place Details request. Each review is accompanied by additional information such as the scores given by the author, author details, and the date that the review was submitted.

Text Search

Today we are introducing Text Search, a whole new way of searching that broadens the scope of the Places API to any device that can accept text input, be it from a keyboard or from voice recognition.

Text Search brings the flexible capabilities of the Google Maps search field to your application. Rather than requiring the user’s location to search around, Text Search interprets free text queries that can include both what the user is searching for, and where they are searching for it. For example, you can submit a search for “Pizza in New York”, or “Sushi near Sydney”. You can also bias queries to a particular area, so that even queries with no address component can be correctly interpreted.

Opening Hours

Another popular request from developers has been access to the opening hours for businesses. The Place API now returns the 7 day opening hours for a Place in the Place Details results where available. Place Search results also now include a property that indicates if a Place for which opening hours are available is currently open.


Today we are also introducing support for paging, which increases the number of search results that can be retrieved to 60. Applications can now request two additional sets of 20 results after the initial request has been made.

You can try these new features with the below demo. Enter a search query to see 20 matching results, with more loaded when you scroll to the end of the list. Click on a result to see the reviews for that place under the map, and the opening hours for today in the InfoWindow on the map.

To accompany these launches we’re also pleased to announce a new dedicated home page for the Places API at In addition to the Places API web service, all of the above new features are also available in the places library of the JavaScript Maps API v3.

If you want to know more about how your application can benefit from the power of the Google Places API join our developer community on Stack Overflow. We look forward to seeing the innovative new apps that these great new Places API features inspire you to develop.

Google Geo Developers Blog

New version of Google Apps Connector for BlackBerry® Enterprise Server now available

Version 4.5 of Google Apps Connector for BlackBerry® Enterprise Server is now available with the following improvements:

  • Support for automatic user password generation in BlackBerry Administration Service (BAS)
  • New Configuration Settings page for easier enablement of common optional features, such as send-as and read-receipt support
  • Performance, reliability, and stability improvements
    Resolved issues that caused PST file corruption
  • Google Apps Connector attempts to repair any remaining corruptions automatically.
    Miscellaneous bug fixes

Editions included:

Google Apps for Business, Government and Education

Languages included:

US English

How to access what’s new:

Download page

For more information:

Release notes
Admin guide

Get these product update alerts by email

Subscribe to the RSS feed of these updates

Google Apps update alerts

Approval Workflow using Apps Script

Editor’s Note: This blog post is authored by Dito’s Steve Webster who is a Google
Apps Script Top Contributor – Saurabh Gupta

Ethics Disclosure Review Workflow

Recently a company who operates retail stores throughout a few
states reached out to Dito. When their associates conduct business
discussions with vendors or customers where monetary exchanges are
involved, their Ethics Disclosure policy requires a log for each event,
a supervisor approval, and committee review.

The customer’s existing disclosure review process was cumbersome and
time consuming. The employees would add a disclosure review request to
a spreadsheet with 29 columns. The new review request would then be
reviewed by their supervisor. The supervisor and the employee would go
back and forth exchanging emails and making changes to a dense
spreadsheet until an approval was granted. It was clear that the
customer needed a workflow solution. They decided to hire Dito to build a workflow solution
based on Google
Apps Script

Workflow Solution based on Google Apps Script

To make the process more user friendly and productive, Dito decided to
build a user interface to collect ethics disclosure events, make
updates, and automate the routing of email notifications. Writing a
Google Apps Script to
create a user interface
 (UI), enabled associates to interact with
their contacts to select their supervisor’s email address and simplify
the data collection with list boxes. The script sends approval emails
with HTML form radio buttons, text box, approve/decline buttons, and a
“Post” command to invoke other workflow scripts. Below are some of the
main design points for this Approval Workflow script.

1. Disclosure Review Workflow

The Disclosure Review workflow requires (a) Associates to fill
out the Ethics Disclosure form. (b) Supervisor to either approve or
decline the submission. (c) If supervisor approves, the Ethics
Disclosure Committee is notified. (d) If supervisor declines, the
associate is notified to make corrections. (e) After improving the
submission, the workflow repeats itself.

2. Disclosure Review Request Form

Dito developed a custom review request form. A form was developed using
Google Apps Script’s UI
. The form provides the ability to look up data to populate
such things as a drop-down list box. This form allowed real-time email
look-ups by using the Apps Script’s Contacts service.  First efforts
included per character look-ups in a list box, but since they have over
1,000 users, it was best to enter the first and/or last name of their
supervisor before initiating the look-up (see code snippet below).

var byName = ContactsApp.getContactsByName(searchKey);
for (var i in byName) {
  var emailStr  = byName[i].getPrimaryEmail();
  // If there is no 'primary' email, try again for the next email
  if (emailStr == null)
     var emailStr  = byName[i].getEmails()[0].getAddress(); 
  // If emailStr is still null, try again by getting the next email
  if (emailStr == null) 
     var emailStr  = byName[i].getEmails()[1].getAddress();

Another dynamic field was the “activity type”.  Depending on the
selection more form fields are displayed. For example, if the activity
type is “Meals”, display a list box to select lunch or dinner.

3. Approve or Reject directly in Gmail

When an associate submits his/her review request by using the
custom form within a spreadsheet, their supervisor receives an email
with easy-to-read HTML formatted results.  The approval decision, as
well as a comment field (e.g. decline reason), is made within the
email. This is more productive and prevents unnecessary back and forth
into the spreadsheet.

If the request is declined by the supervisor, the associate who
submitted the review request receives an email and can review the
details. The email also contains a “Continue” button which opens the
form in a new browser tab. After corrections are submitted, the
supervisor receives another email and the workflow repeats itself.

When approved, the Ethics Disclosure Committee is notified by
sending a group email within the script.

4. Saving Workflow History

Since history records existed in their original spreadsheet form
and they wanted to insert these records into the new work flow
spreadsheet as a one-time task, an Apps Script was used to copy the
data.  Of course their columns did not match the new spreadsheet.  By
using a mapping approach and a “read once” and “write once” technique,
the Apps Script quickly made the changes.

function myFunction() {
  var ss           = SpreadsheetApp.getActiveSpreadsheet();
  var sheet        = ss.getSheetByName('Sheet 1');
  var rowsWithData = sheet.getRange(2, 1, sheet.getLastRow(), 
  var sheet1Data = []; 
  var sheet2Data = []; 
  for (var i = 0; i < rowsWithData.length; i++) {
    switch (rowsWithData[i][4])   // This is the activity type
      case "Gift":
            sheet1Data.push([rowsWithData[i][12], rowsWithData[i][13], 
  sheet.getRange(2, 6,  sheet1Data.length, 3).setValues(sheet1Data);
  sheet.getRange(2, 12, sheet2Data.length, 1).setValues(sheet2Data);

Google Apps Script is very powerful and Dito uses it to build
interesting solution for its customers. If you are using Google Apps
then be sure to use Google Apps Script. You’ll be amazed with what you
can build with it.

Steve Webster

Google Sites and Scripts expert from Dito specializing in training
and application development. When not busy finding solutions to
enhance customer capability in Google Apps, Steve shares examples
of his work in the Google Apps Developer Blog.

Google Apps Developer Blog

Welcome, Google Apps users!

Google Apps recently launched an improvement that made dozens of exciting Google services available to Google Apps users for the first time. As part of this launch, Google Website Optimizer is now available to our Google Apps users for free with their Apps accounts.
Google Apps is Google’s suite of cloud-based messaging and collaboration apps, including Gmail, calendar, documents, spreadsheets, and more, specifically optimized for use in organizations. These services, which run entirely in the cloud, are used by more than 30 million users in small and large businesses, educational institutions, government agencies, and non-profit organizations around the world. You can learn more about how Google Apps can lower IT costs and improve productivity and collaboration at your organization at
For those users who have a Google Apps account, if your administrator has already transitioned your organization to the new infrastructure, you can get started using Google Website Optimizer at with your existing Apps account.
For more details, read the complete post on the Google Enterprise blog and follow all the updates on other newly available services for Google Apps users.

Google Website Optimizer Blog

New: Google Apps Calendar Interop for Microsoft® Exchange

Designed for organizations in which some users use Google Calendar and other users manage their calendars in Microsoft® Exchange, Calendar Interop enables you to sync the free/busy status of users in both calendar systems.

This enables users in one calendar system to view the availability of users in the other system before scheduling a meeting.

Editions included:
Google Apps for Business

Languages included:
All supported languages

For more information:
Get these product update alerts by email
Subscribe to the RSS feed of these updates

Google Apps update alerts

Integrating Google Docs with using Apps Script

Editor’s Note: Ferris Argyle is going to present Salesforce Workflow Automation with Google Spreadsheet and Apps Script at Cloudforce. Do not miss Ferris’s talk – Saurabh Gupta

As part of Google’s Real Estate and Workplace Services (REWS) Green Team, the
Healthy Materials program is charged with ensuring Google has the href=””>healthiest
workplaces possible. We collect and review information for thousands of
building materials to make sure that our offices are free of formaldehyde,
heavy metals, PBDEs and other toxins that threaten human health and reduce our

A Case for using Google Docs and

My team, as you might imagine, has a great deal of data to collect and manage.
We recently implemented class=”c9″
href=””>Salesforce class=”c9″
href=””>.com to manage that data, as it can
record attributes of an object in a dynamic way, is good at tracking
correspondence activity and allows for robust reports on the data, among many
other functions.

We needed to integrate with our processes in Google Apps. We
wanted to continue collecting data using a Google Docs form but needed it
integrated with because we:

  1. Liked the way the form looked and functioned
  2. Wanted to retain continuity for our users, including keeping the same
  3. Wanted a backup of submissions

And this is where Google Apps Script came to our rescue. We found that we
could use Google Apps Script to create a new Case or Lead in
when a form is submitted through our Google Docs form. This allowed us to
continue using our existing form and get our data directly and automatically

Google Docs + Apps Script + = Integrated Goodness! has two built-in options for capturing data online – Cases and
Leads. Google Docs Forms can capture data for both of them. Set up your Case
or Lead object with the desired fields in The next step is to
generate the HTML for a form. You will use the IDs in the HTML when writing your Google Apps script.


A) Getting the HTML in

1. Login to and go to Your Name > Setup > Customize > Leads or
Self-Service (for Cases) > Web-to-Lead or Web-to-Case

2. Make sure Web-to-Lead/Web-to-Case is enabled. Click on Edit (Leads) or
Modify (Cases) and enable if it is not.

3. Click on the ‘Create Web to Lead Form’ button (for Leads) or the ‘Generate
the HTML’ link (for Cases)

4. Select the fields you want to capture and click ‘Generate’. Save the HTML
in a text file. You can leave ‘Return URL’ blank



B) Setting up Google Apps Form/Spreadsheet:

Create your form and spreadsheet (or open up the one you already have and want
to keep using). This is very easy to do. Go to your class=”c9″
href=””>Docs and click on ‘Create’ to open a new
form. Use the form editor to add the desired fields to your form- they’ll show
up as column headings in the corresponding spreadsheet. When someone fills out
your form, their answers will show up in the right columns under those


C) Writing the Google Apps Script:

The script is set up to take the data in specified cells from the
form/spreadsheet and send it into designated fields in your
instance (identified by the org id in the HTML generated above). For example,
the form submitter’s email is recorded through the form in one cell, and sent
into the email field in either the Lead or Case object in

1. Create a new script (Tools > Script Manager > New).

2. Write the script below using the pertinent information from your code (shown further down).

function SendtoSalesforce() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var row = sheet.getLastRow();
  var firstname = sheet.getRange(row, 2).getValue();
  var lastname = sheet.getRange(row, 3).getValue();
  var email = sheet.getRange(row, 4).getValue();
  var company = sheet.getRange(row, 5).getValue();
  var custom = sheet.getRange(row, 6).getValue();
  var resp = UrlFetchApp
            method: 'post',
            payload: {
              'orgid' : '00XXXXXXXX',
              'first_name' : firstname,
              'last_name' : lastname,
              'email' : email,
              'company' : company,
              '00YYYYYYYY' : custom,
              'external' : '1'

Define your variables by directing the script to the correct cell (row, column
number). Then in the payload section, match the field id from your HTML (red) to the variable you defined (blue). For example, the
email address of the submitter is defined as variable ’email’, can be found in
the 4th column of the last row submitted, and the id for that field in is ’email’.



Note that any custom fields you’ve created will have an alpha-numeric id.

3. Save your script and do a test run.


D) Wiring Script to a Form Submission.

To send your data automatically into, you need to set a trigger
that will run the script every time a form is submitted. To do this, go to
your script and click Resources>Current script’s triggers.

1. Create a Trigger for your function so that it runs when a form is



2. Post the link to your form on your website, send it in an email, link to it
on G+, etc. Get it out there!

That’s it! Now when someone submits a form, the information will come into
your spreadsheet, and then immediately be sent into You can
adjust your settings to create tasks when the information comes
in, send out an auto-response to the person filling out the form and set up
rules for who is assigned as owner to the record. You’ll also have the
information backed up in your spreadsheet.

This has been a great solution for our team, and we hope others find it useful
as well!


width=”154″>Beth Sturgeon

Beth Sturgeon is a member of Google’s Green Team in Mountain
View, which makes sure that Google’s offices are the healthiest, most
sustainable workplaces around. Prior to Google, she had a past life as
a wildlife researcher.



Google Apps Developer Blog

Create a Spreadsheet User Directory with Apps Script

As a consultant helping companies move to the Google cloud, I receive many
feature requests before, during, and after each migration. Often I’m asked
about re-creating small and specific solutions that support particular
business needs not fully covered by Google Apps out of the box. In many
cases, a simple Google Apps Script solution satisfies the business requirement.

What is the Google Spreadsheet User Directory?

The “Google Spreadsheet User Directory” is a solution I’m frequently asked about. Google Apps Domain administrators can use a simple Apps Script that can be saved into a Google Spreadsheet and then set to run on a schedule, via a “time-driven” trigger. By using the Google Profiles API (available only for domain administrators), domain administrators can create a Google Spreadsheet which contains Google Apps domain user information.The user profile data can then be consumed and used by other business logic code, either in the spreadsheet itself or elsewhere.

Using Apps Script to provide this kind of solution was an obvious choice for
the following reasons.

  1. Apps Script makes the Google Spreadsheet User Directory a simple, flexible solution that the customer can quickly understand and extend. The JavaScript syntax is easy to learn and program in, and there is no need to compile and deploy code.
  2. The Apps Script code is conveniently integrated into Google Spreadsheets, so there is no need to use any other software. Advanced
    functions can be exposed to end users for data manipulation through the spreadsheet menu, and scheduling an Apps Script to run at a regular interval is trivial via the Spreadsheet “Triggers” mechanism.
  3. Google Apps Script provides services for accessing Google Profiles, Contact Info, and Google Groups plus Google Docs, Google Sites, Google Charts, and more.  The Google Spreadsheet User Directory script makes use of both the new Apps Script Domain Services API and the GData Profiles API, via the “UrlFetch” service.
  4. The Apps Script code can be easily shared through Google Spreadsheet templates and through the Google Script gallery.

Using the Google Spreadsheet User Directory

The Google Spreadsheet User Directory code consists of a primary scanUserProfiles() function and some supporting “utility” functions. The three steps for setting up the code to run are:
1. Set up the “Consumer_Key” and “Consumer_Secret” ScriptProperties and run the scanUserProfiles() function in the Apps Script integrated development environment to get the first “Authorization Required” screen. (I’ve included an illustration below… Choose “Authorize.”).

2. Since scanUserProfiles() uses OAuth with UrlFetch to get User Profile information via the GData API, it needs to be run at least
one more time inside of the Apps Script IDE, so that the OAuth “Authorize” prompt can be shown to the programmer and accepted.

3. After authorization, the scanUserProfiles() script is free to make authorized requests to the Google User Profiles feed, as long as the
developer who saved it has “domain admin” rights.

Design of the Google Spreadsheet User Directory

The following snippets show the OAuth setup, the user profiles Url setup,
and the initial UrlFetch.

var oAuthConfig1 = UrlFetchApp.addOAuthService("googleProfiles");
var options1 = {
    oAuthServiceName : "googleProfiles",
    oAuthUseToken : "always",
    method : "GET",
    headers : {
      "GData-Version" : "3.0"
    contentType : "application/x-www-form-urlencoded"
var theUrl = "";
if (nextUrl == "") {
  theUrl =
    "" + domain +
      "/full?v=3&max-results=" + profilesPerPass + "&alt=json";
} else {
  theUrl = nextUrl;
if (theUrl != "DONE") {
  var largeString = "";
  try {
    var response = UrlFetchApp.fetch(theUrl, options1);
    largeString = response.getContentText();
  } catch (problem) {
    recordEvent_(problem.message, largeString, ss);
var provisioningJSONObj = null;
    var jsonObj = JSON.parse(largeString);
    var entryArray = jsonObj.feed.entry;  

The “nextUrl” variable above (line 74) is being pulled from a cell in the
spreadsheet, where I’m saving the “next” link from the fetched data. (If
there’s no “next” link, I save “DONE” to the same spreadsheet cell.) To
fetch JSON, I’m appending the parameter &;alt=json on lines 75 and 76.

After I’ve got my JSON object, I create an array to store the data that I
will be writing out to the spreadsheet. I set the array default values and
make liberal use of try-catch blocks in this code, since there’s no telling
which of these fields will be populated, and which will not.

for (var i=0; i<entryArray.length; i++) {
    var rowArray = new Array();
    rowArray[0] = "";
    rowArray[1] = "";
    rowArray[2] = "";
    try { rowArray[0] = entryArray[i].gd$$  fullName.$  t; } catch (ex) {} //fullname
    try { rowArray[1] = entryArray[i].gd$$  givenName.$  t; } catch (ex) {} //firstname
    try { rowArray[2] = entryArray[i].gd$$  familyName.$  t; } catch (ex) {} //lastname

At the end of the data collection process for a single record/row, I add the rowArray to another single-element array called valueArray (line 207), to create a 2-D array that I can use with range.setValues to commit my data to the spreadsheet in one shot (line 209).

var updateRow = getNextRowIndexByUNID_(rowArray[3],4,stageSheet);
var valueArray = new Array();
var outputRange = stageSheet.getRange(updateRow, 1, 1, 12);

The function getNextRowIndexByUNID (line 205) just finds the next available
row on the “staging” sheet of the spreadsheet, so I can write data to it.
The code is inside of a “for” loop (starting on line 106) that executes once
for each entry in the current JSON object (created lines 96 and 97).

} else {
    var endTime = new Date();
    if (parseInt(getSettingFromArray_("StagingCopiedToProduction",settingsArray)) == 0) {
     var copied = copySheet_(ss,"Staging","Employees");
     if (copied == "SUCCESS") {
       var sortRange = empSheet.getRange(2,1,empSheet.getLastRow(),empSheet.getLastColumn());
       sortRange.sort([3,2]); // SORT BY COLUMN C, THEN B
} // end if "DONE"


If the script finds “DONE” in the “NextProfileLink” cell of the spreadsheet,
it will skip doing another UrlFetch to the next feed link (line 81).
Instead, it will copy all records from the “staging” sheet of the
spreadsheet to the “production” one, via a utility function called
“copySheet” (line 273). Then it will sort the range, reset the copy
settings, and it will mark another designated cell,
“StagingCopiedToProduction” as “1” in the spreadsheet, to stop any further
runs that day.

Scheduling the Google Spreadsheet User Directory Script to Run

Below are the triggers I typically set up for the Spreadsheet User
Directory. I recommend setting scanUserProfiles() to run on an interval of
less than 30 minutes, since the Google-provided token in each
“NextProfileLink” url lasts about that long. I also recommend running the
WipeEventLog() utility function at the end of each day, just to clear data
from prior runs from the EventLog tab of the spreadsheet.


Above I’ve outlined how to create a basic User Directory out of a Google Spreadsheet and Apps Script that will always keep itself current. Since Google Spreadsheets support the Google Visualization API and a query language for sorting and filtering data, all kinds of possibilities open up for creating corporate “directory” gadgets for Google Sites (see the image at right) and for enabling business processes that require workflows, role lookups, or the manipulation of permissions on content in the various Google Apps.

Using Apps Script made this solution quick and easy to produce and flexible
enough to be extended and used in many different ways. The code is easy to
share as well. If you’d like to give the Google Spreadsheet User Directory a
try, then please copy this
spreadsheet template
, and modify and re-authorize it to run in your own


Shel Davis

Guest author Shel Davis is a senior consultant with Cloud Sherpas, a company recently named the Google Enterprise 2011 Partner of the Year. When Shel is not working on solutions for customers, he’s either teaching classes on Google Apps and Apps Script (Google Apps Script Training), or he’s at home, playing with his kids.

Google Apps Developer Blog

Come Learn About Apps Script in Washington, DC

Editor’s note: This has been cross-posted from the Google Code blog — Jan Kleinert

Google Apps Script is a JavaScript cloud scripting language that provides easy ways to automate tasks across Google products and third party services. If you want to learn more about Google Apps Script, collaborate with other developers, and meet the Apps Script team, here’s your chance! We will be holding an Apps Script hackathon in Washington, DC on Wednesday, March 7 from 2pm – 8pm.

After we cover the basics of Apps Script, you can code along with us as we build a complete script, or you can bring your own ideas and get some help and guidance from the team. There will be food, power, and Apps Script experts available to help throughout the day. Just bring your laptop, ideas, enthusiasm, and basic knowledge of JavaScript. Check out out the details of the event and be sure to RSVP to let us know you’re coming.

Jan Kleinert profile | twitter

Jan is a Developer Programs Engineer based in NYC, focusing on helping developers get the most out of Google Apps Script. Prior to Apps Script, she worked on Commerce, helping merchants integrate with Google Checkout and on Chrome, helping developers build great web apps.


Google Apps Developer Blog