Contact Sharing using Google Apps Script

Wednesday, March 23, 2011 | 1:56 PM

Labels: , ,

Editor's Note: This article is written by Steve Webster and Vinay Thakker who work at Dito. Dito has developed applications such as Dito Directory which is available in the Google Apps Marketplace.

You just created your own contact group in Google Apps Contact Manager and now you want to share this contact group with a few other coworkers (not the entire company). Over the last couple of years, our team at Dito often got this request from our customers. We decided to leverage Google Spreadsheets & Google Apps Script to allow sharing of user’s “personal contact group” with only a select group of coworkers.

How does it work?

The Apps Script implements a three step wizard. Upon completion of the wizard, the script sends the sharing recipients a link to open the spreadsheet to import the user’s recently shared contact group. The three steps in the wizard are.
  • Step 1 lists all the current contact groups in user’s account. The user can select the group he/she wants to share.
  • Step 2 allows user to select the colleagues with whom the user wants to share his/her personal contact group with.
  • Step 3 lets the user submit the sharing request.

Designing using Apps Script Services

Apps Script has various services which can be used to build the user interface, access the user’s contact list and send emails without the need to compile and deploy any code.

1. Security (guide)

Before a script can modify a user’s contacts, it needs to be authorized by that user. The authorization process takes place when a user executes the script for the first time. When a user makes a request to share his/her contacts, our script sends a link to the intended recipients by email. Upon clicking this link and the “Run Shared Contact Groups” button in the spreadsheet, the recipient will first need to grant authorization to execute the script. By clicking the “Run Shared Contacts Groups” button again, the script will proceed with creating the shared contact group.

2. Spreadsheet Service

In developing this script, there was a fair amount of data that needed to be exchanged between different users. We used Apps Script’s Spreadsheet Service for temporarily storing this data.

// grab the group titled "Sales Department"
var group = ContactsApp.getContactGroup("Sales Department");
// from that group, get all of the contacts
var contacts = group.getContacts();
// get the sheet that we want to write to  
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Contact Data");
// iterate through contacts
for (var i in contacts) {
//save each of the values into their own columns
sheet.getRange(i, 1, 1, 1).setValue(contacts[i].getGivenName());
sheet.getRange(i, 2, 1, 1).setValue(contacts[i].getFamilyName());
sheet.getRange(i, 13, 1, 1).setValue(contacts[i].getWorkFax());     
sheet.getRange(i, 14, 1, 1).setValue(contacts[i].getPager());       
sheet.getRange(i, 15, 1, 1).setValue(contacts[i].getNotes());       

3. Ui Service

Ui Services in Google Apps Scripts have an underlying Google Web Toolkit implementation. Using Ui Services in Apps Script, we easily built the user interface consisting of a 3 step wizard. In designing Ui using Ui Services, we used two main types of Ui elements - Layout Panels and Ui widgets. The layout panels, like FlowPanel, DockPanel, VerticalPanel, etc., allow you to organize the Ui widgets. The Ui widgets (TextBoxes, RadioButtons, etc.) are added to layout panels. Ui Services make it very easy to assemble and display a Ui interface very quickly.

We built each of the components on their own, and then nested them by using the “add” method on the desired container. The UI widgets in the screenshot above were constructed by the code below:

// create app container, chaining methods to set properties inline.
var app = UiApp.createApplication().setWidth(600).setTitle('Share The Group');
// create all of the structural containers
var tabPanel   = app.createTabPanel();
var overviewContent = app.createFlowPanel();
var step1Content = app.createFlowPanel();
var step2Content = app.createFlowPanel();
var step3Content = app.createFlowPanel();
// create u/i widgets
var selectLabel = app.createLabel("Select one of your Contact Groups you want to share with others.");
var contactGroupDropdown = app.createListBox().setName('groupChooser');
// add all children to their parents
tabPanel.add(step1Content,"Step 1");
tabPanel.add(step2Content,"Step 2");
tabPanel.add(step3Content,"Step 3");
// tell the spreadsheet to display the app we've created.

Continuing with this pattern, we created a pretty complex design using the UI Services. The next step in building a useful user interface is actually building in event handlers for the UI Widgets. Event Handlers let Apps Script know which function you want to run when your script needs to respond to a given user interaction. The code below is an example of a DropDownHandler that we used in our script in Step 1 of the wizard.

// create a function to execute when the event occurs. the
// callback element is passed in with the event.
function changeEventForDrowdown(el) {
 Browser.msgBox("The dropdown has changed!");
// create event handler object, indicating the name of the function to run
var dropdownHandler = app.createServerChangeHandler('changeEventForDrowdown');  
// set the callback element for the handler object.
// add the handler to the "on change" event of the dropdown box

4. Contacts Service

When a user of the script chooses to share a specific group, the script saves that group contact data into a spreadsheet. When a sharing recipient clicks on the run button to accept the contacts share request, the script fetches the contact group data from the spreadsheet and uses the Contacts Service to create contacts for the share recipients.

var group = ContactsApp.createContactGroup(myGroupName);
for (var i = 0; i < sheet.getLastRow(); i++) {
 var firstName = sheet.getRange(i, 1, 1, 1).getValue();
 var lastName = sheet.getRange(i, 2, 1, 1).getValue();
 var email = sheet.getRange(i, 3, 1, 1).getValue();
 var myContact = ContactsApp.createContact(firstName, lastName, email);
 // ...
 // set other contact details
 // ...

As this application shows, Apps Script is very powerful. Apps Script has the ability to create applications which allow you to integrate various Google and non-Google services while building complex user interfaces.

You can find Dito’s Personal Contact Group Sharing Script here. Click here to view the video demonstration of this application. You can also find Dito Directory on the Google Apps Marketplace.

Want to weigh in on this topic? Discuss on Buzz


Curtis said...

Thank you for sharing how you implemented "Shared Contacts" with Google Scripts.
Quick question: Do you have to "re-share" contacts whenever there is a change in the contact information?
Thank you

Jim said...

hi curtis,

this script will do a 1 time, 1 way sync, so yes, you would need to re-share the contacts if you update them and wish for others to receive that update. we are building full contact sync abilities into our next version of dito directory. this is just a preview.

hope you enjoy the script!

Steve said...

Hi Curtis,

Yes. This script performs a one-time sync to other co-workers. You will need to rerun the application if you update your personal contact group.

Soon the Dito Directory product will have greater functionality than this script so stay tuned :)

Steve Webster,

James Ferreira said...

Nice use of the list box to work like a suggest box. Great interaction well done!

Steven said...

Thanks for sharing this script , although it looks very promising I get the error'' Service error: Contacts : Entry does not have any fields set'' .

Could you guys help me out ?

Steve said...

Hi Stephen,

Any questions or issues should be posted on the Google Apps Script forum at:

Learner said...

Hi Steve and Vinay,

I think the code like


should generate an error when i=0, which is the case in your code here as you have mentioned
for( i=0 ; i < sheet.getLastRow() ; i++ )...

Shouldn't it be like the following?
for( i = 1 ; i< = sheet.getLastRow() ; i++ )...

I mean getRange() method can never have 0 in the arguments.