Today we’re introducing the Google Apps extensions console, a new tool to help IT departments and in-house applications developers integrate with Google Apps.

In-house developers can now access the same Google Apps extension points first introduced in the ...

Today we’re introducing the Google Apps extensions console, a new tool to help IT departments and in-house applications developers integrate with Google Apps.

In-house developers can now access the same Google Apps extension points first introduced in the Google Apps Marketplace. Applications can create links in the navigation bar (alongside “Calendar” and “Documents”), share a single sign-on with Google accounts, and run inside Gmail using rich contextual gadgets.

The extensions console helps in-house developers create new projects, manage team permissions, retrieve OAuth credentials, and upload their application manifest. Once the app is ready to deploy, administrators can install the app to their domain control panel for wider release.

You can get started with the console documentation to learn more.

Want to weigh in on this topic? Discuss on Buzz

As part of the launch of Gmail contextual gadgets, Google released a set of predefined extractors that developers could use. These extractors allow developers to match content within a single part of an email message, such as the subject, and use that content to display relevant information to the current user.
As part of the launch of Gmail contextual gadgets, Google released a set of predefined extractors that developers could use. These extractors allow developers to match content within a single part of an email message, such as the subject, and use that content to display relevant information to the current user.

Many Gmail contextual gadget developers have expressed a desire to match on more complex patterns than is possible with the predefined extractors. Today, with the launch of the Google Apps extensions console, these complex patterns, known as custom extractors, are now available to drive contextual gadgets.

Custom extractors allow developers to trigger their gadget when a series of conditions are met. For example, a developer could write an extractor that triggered a gadget only when “Hello world” appeared in the subject and “john@example.com” was the sender of the email. This allows developers to more finely tune their gadgets, and provide even more relevant contextual information.

If you’re interested in writing a custom extractor you can get started by reading our documentation. If you have questions, please post them in the forum.

Want to weigh in on this topic? Discuss on Buzz

This article is written by Stuart Keeble and Gwyn Howell who work at Appogee. Appogee is a UK based reseller of Google Apps and has also developed applications such as Domain Management Studio, Docmail Connect, and Bookmarks, which are available in the ...
Editor's Note: This article is written by Stuart Keeble and Gwyn Howell who work at Appogee. Appogee is a UK based reseller of Google Apps and has also developed applications such as Domain Management Studio, Docmail Connect, and Bookmarks, which are available in the Google Apps Marketplace.


The days of the paperless office are not yet upon us, with physical mail delivery still popular for many types of communication including marketing information, financial documents and greetings cards. Over 5000 companies in the UK now use CFH Docmail to print, stuff, and deliver their mail, resulting in over 6 million documents being sent every month. By creating Docmail Connect for Google Apps, we at UK Google focused systems integrator, Appogee, have made it simple for Google Apps users to personalize, print and mail their Google documents..

As well as allowing users to send snail mail from the Google Apps menu, we made the code library for Docmail Connect for Google Apps available in project hosting. Other Google Apps Marketplace providers, such as CRM and ERP applications, can now benefit from being able to easily integrate their applications with Docmail services.

The Challenge

In order to implement the solution we needed to take the Docmail web services and create a Python interface to them. To achieve that we needed a simple Python to Web Services layer we could rely on which would allow us to build the bridge between Google App Engine and Docmail’s API, and then we needed to make the bridge work from Google Docs to the CFH Docmail service. The final challenge we faced was achieving a seamless experience for the user which meant focusing on performance each step of the way.

The Solution (in 3 easy steps)

Step 1: Invoke a SOAP Web Service from App Engine using Python

Our development language of choice is Python. To invoke a SOAP web service we chose to use the SUDs library rather than create a web service interface from scratch. We tested it locally and seemed to work fine. When we uploaded it to App Engine with some sample code, we found some errors due to limitations in App Engine for using sockets and accessing the file system. To get around this, we extended the SUDS library so that it didn’t use the sockets module, and instead of using the file system we used the App Engine memcache API. This worked very well and we were able to send and receive soap requests from App Engine via the Docmail API. Developers may be interested in additional details:
  1. The HttpTransport class has a u2open method which uses python’s socket module to set the timeout. This is not allowed on App Engine, and the timeout setting can be set later using App Engines urlfetch module. The timeout line was removed in a new method:
    def u2open_appengine(self, u2request):
    tm = self.options.timeout
    url = self.u2opener()
    # socket.setdefaulttimeout(tm) can't call this on app engine
    if self.u2ver() < 2.6:
    return url.open(u2request)
    else:
    return url.open(u2request, timeout=tm)
    transport.http.HttpTransport.u2open = u2open_appengine
  2. The SUDs library has an extensible cache class. The SUDs library provides various implementations of this, however we wanted to use the App Engine memcache for performance. To do this, we implemented a new class to use memcache, as shown below:
    class MemCache(cache.Cache):
    def __init__(self, duration=3600):
    self.duration = duration
    self.client = memcache.Client()

    def get(self, id):
    return self.client.get(str(id))

    def getf(self, id):
    return self.get(id)

    def put(self, id, object):
    self.client.set(str(id), object, self.duration)

    def putf(self, id, fp):
    self.put(id, fp)

    def purge(self, id):
    self.client.delete(str(id))

    def clear(self):
    self.client.flush_all()
    This was then plugged into the SUDs client class by overriding the __init__ method.

  3. We can now use the modified SUDs client class to make SOAP calls on App Engine! The full source code for this is available in project hosting.

Step 2: Google Docs to Docmail

CFH publish a full API to allow developers to integrate their applications with Docmail, a subset of which needed to be used by Appogee to create the interface for users to create mailings from Google Docs. Not every Docmail function is enabled in the wrapper, but the principles used can easily be extrapolated to any other function, and the key to it is getting a satisfactory link from Google Docs to Docmail.

The Docmail API can accept documents in a variety of formats including doc, docx, PDF and RTF. In order to use the API, we would need to extract Google Docs content in one of these formats. The Google Docs API has support for exporting in doc, RTF and PDF. We experimented with each before settling on RTF, which, although large in file size, did work. However the Google App Engine urlfetch library has a 1MB request limit, so we were not able to send files larger than 1MB. We evaluated a number of workarounds such as cutting the files up into chunks and sending them separately, bouncing the files off another platform but our only option was to simply prevent files larger than 1 MB from being uploaded. To achieve this we used Ajax calls to check (compute) the file size in real time as they are selected and provide appropriate feedback to the user. The file size cut off is a configurable parameter, so if Google increase the limit we can adjust the app without redeploying the code.

Breaking this integration down, we used the Google Docs API together with the Docmail SOAP API, via our modified implementation of the SUDs library as described in step 1.

The Docmail API must be used in a logical order, to coincide with the wizard pages on the Docmail website. We can illustrate these steps in order:
  1. Create an instance of the Docmail client, which is an extension to the SUDs client class. The client contains the methods we need for further communication with the Docmail API:
    docmail_client = client.Client(USERNAME, PASSWORD, SOURCE)
  2. Create / Retrieve a mailing. To create a new mailing, we create an instance of the Mailing class, and pass it into the create_mailing method:
    mailing = client.Mailing(name='test mailing')
    mailing = docmail_client.create_mailing(mailing)
    To retrieve an existing mailing, we need to know the mailing guid:
    mailing = docmail_client.get_mailing('enter-your-mailing-guid')
  3. Upload a template document. Since we are retrieving documents from Google Docs to be used as the template, we need to download it first. We do this using the Google Docs API:
    docs_client = gdata.docs.client.DocsClient()
    # authenticate client using oauth (see google docs documentation for example code)
    We now need to extract the document. There are various formats you can do this in, but we found by experimenting that RTF worked best, despite being the largest in file size.
    file_content = docs_client.GetFileContent(uri=doc_url + '&exportFormat=rtf')
    And finally upload the template file to docmail:
    docmail_client.add_template_file(mailing.guid, file_content)
  4. Upload a Mailing List Spreadsheet. This is similar code to uploading a template:
    docs_client = gdata.docs.client.DocsClient()
    file_content = docs_client.GetFileContent(uri=doc_url + '&exportFormat=csv')
    docmail_client.add_mailing_list_file(mailing.guid, file_content)
  5. Submit the mailing for processing. The mailing needs to be submitted for processing. Once this has been done, a proof is available for download.
    docmail_client.process_mailing(mailing.guid, False, True)
  6. Finally, we approve and pay for the mailing:
    docmail_client.process_mailing(mailing.guid, True, False)

Step 3 - Performance

When creating a system like Docmail Connect for Google Apps, overall acceptability of the system will be driven as much by performance as by functionality, so we paid particular attention to the key components driving this.

We were conscious that some Google Apps users may have a lot of Google documents, so presenting all of them for selection to a user wasn’t an option. Instead, we load 100 at a time (the default), and send them to the browser using XHR calls so it all happens without the user having to do anything and works quite fast - the user can now select from 1000s of documents within a few seconds.

Next we had to address the connection to the Docmail API, where care must be taken to achieve acceptable throughput. Queries to the API had to be minimized and we didn't want the page submits to be slow - the user should be able to go from one page to the next as quickly as possible. To achieve this, we used the App Engine Task Queue. When a user submits a page which requires communication with the Docmail API we fire off a Task Queue to do the work for us, and then simultaneously navigate the user to the next page in the process. This means that the server is working while the user progresses the workflow. This also means handling timeout errors is easier, as the Task Queue can catch the errors and reinstate another task. But it requires some extra planning as some tasks will not complete until others finish, and process checking needs to ensure new tasks only get fired off when the appropriate time has come.

We hope the wrapper, together with the key learnings written up here will encourage others to have a go at wiring their applications to the Docmail delivery services.

Want to weigh in on this topic? Discuss on Buzz


Editor’s Note: Stephanie Obodda oversees Computer Training and Communications for Brown University's central IT department. She was on the project team that helped Brown "go Google" in 2010.

In our 170-person IT department at ...

Editor’s Note: Stephanie Obodda oversees Computer Training and Communications for Brown University's central IT department. She was on the project team that helped Brown "go Google" in 2010.

In our 170-person IT department at Brown University, we had a less-than-ideal way of sharing sick/vacation time among coworkers: sending an email to a Listserv. This was inefficient - mails were not written in a standard format, so it was difficult to determine who would be out on a certain date. Some teams would notify each other of time off by sending personal invites to their vacation events, but this resulted in cluttered calendars.

The Solution

Since most of my coworkers were already creating events on their calendar to indicate their vacations, a calendar-based solution seemed most convenient. The script I wrote simply requires them to perform one additional step: when creating their vacation event, they invite a specific email address as a guest.



The script:
  • Aggregates events from the invited ‘out’ calendar, keeping only the relevant information: person, date, and type of event (from keywords like vacation, sick/doctor, or conference)
  • Creates a single daily event on another calendar with the day’s “who is out” list. We can overlay this calendar onto our own without having an overwhelming amount of individual “out” events.
  • Each morning around 9am, the daily Out list is automatically posted on a Google Site.

A single daily event on a shared calendar contains the list of who is out that day.

Code snippet - function which determines the type of event based on keywords in the event title. The keywords were chosen with the help of our HR Manager and several co-workers.


Something that streamlined the process was using up a dedicated email address for the calendar and script. This allows people to invite a simple, easy-to-remember email address to their vacation events and gave us a neutral place to store the script (not a personal account).

One issue I ran into while writing the script was that the user who created the event wasn't always the person who was out of the office because assistants often put these events on calendars. I received great feedback from the Apps Script forum. This is essential because we do delegated calendaring, and assistants put vacation events on the calendars they manage.

I’m not employed as a programmer - I’m a trainer with some self-taught ActionScript, JavaScript and PHP skills, and I found it very easy to wrap my head around Google Apps Script.

Want to weigh in on this topic? Discuss on Buzz

This is cross-posted from the Google Code Blog because we think it will be of interest to Google Apps developers

Almost every developer has an idea and might want to start a company. Where do you start? Entrepreneurs ...
This is cross-posted from the Google Code Blog because we think it will be of interest to Google Apps developers

Almost every developer has an idea and might want to start a company. Where do you start? Entrepreneurs Paul Buchheit, Joe Kraus, and Seth Priebatsch explained how to go from hacking on the nights and weekends to building an investor funded startup. We also discussed how to find co-founders, attract investors, and focus on the key decisions. You can watch the complete Google I/O session on YouTube. Here are some highlights.



Should I have a co-founder? Having strong co-founders join you in transforming your idea into a real company is critical to success. There is a positive correlation between the number of co-founders and successful outcomes up to about four co-founders. Beyond four co-founders there isn’t much data. But having more co-founders on your team definitely improves your chances of success.

What are important characteristics of a co-founder? It helps if you have worked together before, know each other well, have complimentary expertise, and can communicate openly and honestly. Joe Kraus said you should be able to settle arguments with great answers, not the compromise middle position. What else should you look for in a co-founder?
  1. Experience starting a company
  2. Domain experience and an understanding of the market
  3. Balance and different experience than your own
  4. Passion about the company vision
How do you get started? Paul Buchheit knew he wanted to start a company but didn’t know how. So, he decided to join a startup to get some experience. That startup was Google. Paul learned how startups grow, and worked with some great people who would later become his co-founders at FriendFeed. Having experience at a startup earns you credibility with potential co-founders, employees, and investors.

What matters most; team, traction, idea, or market segment? They all matter, but the people on the team are the number one consideration. The founding team shapes the product vision and sets the direction for the company. Potential employees and investors are attracted...or not, by the members of the founding team. The idea matters, but will probably change significantly over time, so most investors don’t fixate on the idea. The market segment is important, but only as a gauge of the range of successful outcomes. Traction from early users or customers makes it much easier to raise money.

How do you find investors? People invest in businesses they understand, or people they know. Look for investors that have started companies in your area, or have invested in similar companies in the past. Talk to everyone you know about your idea. Joe Kraus, co-founder of Excite, tells the story of how he read a book about starting companies, called the author, got introduced to other people, who introduced him to other people, and finally ended up with a $3M investment from Kleiner Perkins, one of the top VCs in the world.

Should you raise money from VCs or Angels? The first consideration is who can help you most. You want more than just money from investors. You want help, advice, introductions to other people who can help, and maybe access to press. Aside from help, it depends on how much money you need to raise. Friends and Family is the best place to start to raise small amounts of money. Angel investors can fund anywhere from $100K to $1M or more. Venture Capitalists (VCs) usually invest $1M to $3M in a first round Series A investment.

Incubators, Angels, and VCs - Seth Priebatsch, founder of SCVNGR.com did all three in starting his company. Seth entered a business plan competition at Princeton...and won. He used that to get the initial product built, and then applied to DreamIT, a startup incubator. That experience at the incubator allowed him to build and refine the product. Next he raised a small amount of money from Angels and brought on advisers to help him grow the company. That led to a small round from VCs. Seth believes the more investors you have, the more help, advice, and experience you get.

How do you arrive at a valuation for the company? Joe Kraus says it is an art, not a science. It depends on the stage of the company, the competition, and how fast the market segment is growing. Most early stage startups don’t have revenue and don’t have many users so the valuation is typically between $1M and $3M, and depends on the experience of the founding team, how much progress you have made on the product, and the relative success of competitors. The best way to determine a fair valuation is by having several competing investors give you proposals.

Do I need a business plan? No, but you do need a good slide deck that explains what you want to do, what problem it solves, why it will be successful, and how your team can execute on the vision. Here is a link to a post that explains how to pitch your company to investors. A good pitch deck and a product demo are what most investors are looking for. Business plans might be useful for helping you refine your ideas and vision, but most investors will never read it.

Are patents, IP, and trademarks important? Paul Buchheit says in most cases they don’t matter for early stage startups. Joe Kraus added, patents might be of some value to a potential acquirer, but probably just as a defense against patent infringement cases. Patents are very expensive to obtain (legal bills) and they take two to four years, sometimes longer, to actually get issued. By that time most startups are out of business, acquired, or moving on to something else. Even if you have a patent, most startups can’t afford to defend them in court against potential infringers. The legal expense of defending a patent, and time lost away from your business, make it nearly impossible for a small startup.

Want to weigh in on this topic? Discuss on Buzz



Don Dodge profile | twitter | blog | events

Don Dodge is a Developer Advocate at Google helping developers build new applications on Google platforms and technologies. Prior to joining Google Don was a startup evangelist at Microsoft. He is also a veteran of five start-ups including Forte Software, AltaVista, Napster, Bowstreet, and Groove Networks.

Hard to believe it’s been only two short weeks since Google I/O 2011! There was fantastic energy at the event, and developers had their choice of over 100+ sessions on topics ranging from Google Apps to Android to App Engine to HTML5 to Cloud Robotics.
Hard to believe it’s been only two short weeks since Google I/O 2011! There was fantastic energy at the event, and developers had their choice of over 100+ sessions on topics ranging from Google Apps to Android to App Engine to HTML5 to Cloud Robotics.

Here are the highlights from the Google Apps track:

Sessions

In the Google Apps track, we had 8 sessions on a variety of topics of interest to Google Apps Marketplace developers, systems integrators and customers alike. All of the sessions are available in HD on YouTube and we’ve also posted many of the session slides and notes.

Google Apps Marketplace:

  • Launch and Grow your Business App on the Google Apps Marketplace provided an intro to the Apps Marketplace, but most of the session was third-party developers telling the story of their businesses, demoing their integrations and providing guidance for other developers looking for success on the Marketplace. Teaser: 30% free->paid conversion rates from GQueues on the Google Apps Marketplace.
  • Apps Marketplace: Best Practices and Integrations covered a wealth of best practices for business app development and Google Apps integrations based on experience working with hundreds of developers building applications for the Google Apps Marketplace.

Google Apps Script:

  • Enterprise Workflow with Apps Script showed how Google Apps Script can be used to build complex workflows using simple server-side JavaScript code. The speakers built on several examples for document publishing approval, showing lots of code for how it’s done.
  • Developing Apps, Add-Ins and More stepped through building Add-Ins with deep integration into the Google Apps UI and full applications. The team announced the Apps Script GUI Builder to drag and drop UI components and full Apps Script APIs for Gmail and Google Docs.

Application APIs:

Solutions and Administration:

  • Developing Innovative Custom Business Solutions with Google Apps covered how web solution providers are driving us towards the goal of 100% web. Included many real-world examples from a variety of companies who are extending Google Apps using Apps Script, Google Sites, gadgets, Data APIs, App Engine, GWT and more.
  • Compliance and Security in the Cloud talked about the suite of APIs and tools available for Google Apps customers to handle policy compliance, audit, incident response and more. Very helpful session for IT administrators, CTOs and CIOs using Google Apps, with much of the session diving into several examples using real-world use cases.

Developer Sandbox

We had 24 fantastic companies in our Developer Sandbox this year, showcasing the applications they built for the Google Apps Marketplace and the services they provide Google Apps customers as system integrators or VARs. We were excited to see many of the companies talking about new integrations they have recently built with Google Apps.

Parties and Fun

The official After Hours event celebrated technical and artistic innovation and included robots, games and transforming vehicles in addition to a live performance from Jane’s Addiction. Many Google teams and companies attending I/O also threw plenty of great parties at nearby bars and restaurants.

Thanks to all the developers who attended Google I/O and made it such an enormous success. Our team loved the chance to chat with many of you and learn more about your businesses and technical challenges.

Hope to see you all at Google I/O 2012!

Want to weigh in on this topic? Discuss on Buzz



Ryan Boyd profile | twitter | events

Ryan is a Developer Advocate on the Google Apps Marketplace team, helping businesses build applications integrated into Google Apps. Wearing both engineering and business development hats, you'll find Ryan writing code and helping businesses get to market with integrated features.

When evaluating web apps, customers often ask for information about the vendor’s privacy policy and how their data is handled. To make it easier for customers to discover and understand this information, we’ve teamed up with ...
When evaluating web apps, customers often ask for information about the vendor’s privacy policy and how their data is handled. To make it easier for customers to discover and understand this information, we’ve teamed up with TRUSTe to offer TRUSTed Apps Data Privacy Certification for Marketplace Apps. This new program is designed specifically to help vendors of installable apps better communicate their data privacy and handling practices to potential customers.

Certified apps will have the TRUSTe logo displayed on their listing page, as well as in search and category results pages, similar to the screenshot below.


When a customers wants to see more details, they click on the TRUSTe logo to view a customized privacy policy report, hosted on TRUSTe.com:



All installable Marketplace apps are eligible to apply for free certification for the first year, and can choose to renew at $300 per year per app thereafter.

To learn more about the program, please see TRUSTe’s certification FAQ and program FAQ. We encourage all installable app vendors to apply today!

Want to weigh in on this topic? Discuss on Buzz

We just released version 1.8 of the .NET Library for Google Data APIs which adds brand new service classes and samples for the following three APIs:
We just released version 1.8 of the .NET Library for Google Data APIs which adds brand new service classes and samples for the following three APIs:The library also extends the Email Settings API service to implement new functionality to retrieve the existing settings, support new filter actions and manage email delegation.

In order to improve security and stability, SSL is now turned on by default for all APIs that support it and, since the previous major release (1.7.0.1), more than 30 issues have been Fixed.

For all details, please check the Release Notes:
http://google-gdata.googlecode.com/svn/trunk/clients/cs/RELEASE_NOTES.HTML

Want to weigh in on this topic? Discuss on Buzz

Google Tasks helps many of us to remember all those things that keep us busy. Towards the end of last year we asked our users what they wanted to see improved with Google Tasks ...
Google Tasks helps many of us to remember all those things that keep us busy. Towards the end of last year we asked our users what they wanted to see improved with Google Tasks and an overwhelming request was for the ability to access tasks from anywhere — be it on the move, on the desktop, or through their favorite Web apps.

Today, we’re checking off a big to-do from our list and are inviting you to try out the new Google Tasks API. Using the Google Tasks API, developers can — for the very first time — create rich applications which integrate directly with Google Tasks.

The Google Tasks API provides developers with a powerful set of API endpoints for retrieving and modifying Google Tasks content and metadata. It offers a simple, RESTful interface and supports all basic operations required to query, manage and sync a user’s tasks and task lists. The API uses JSON for data representation and works with multiple authentication mechanisms including OAuth 2.0.

Plain HTTP using JSONUsing Google API Client Library for Java
POST /tasks/v1/lists/<list-ID>/tasks
Content-Type: application/json
...
{ title: "Publish blog post" }
Task task = new Task();
task.setTitle(
"Publish blog post");
client.tasks.insert(
"list-ID",
task).execute();
Client libraries are provided for several major programming environments and should help you get up and running quickly.

The API is available in Labs and can be activated for your project through the API Console. Get started today by trying the Tasks API yourself using the API Explorer and taking a look at the documentation.


If you want to see the API in action check out the Google Tasks Chrome Extension. If you are at Google I/O we invite you to come along and hear the Google Tasks team talk about the new API today.

We thank the early adopters that have worked with us and built their own Google Tasks integrations over the last weeks. We’d like to highlight a few of them:
  • Producteev is a task management platform that lets teams and individuals access their to-dos from a lot of different locations (web, mobile, email, calendars...). You will now have all your Producteev's tasks available in Google Tasks and vice versa!
  • Mavenlink's project collaboration suite allows you to communicate, share files, track time, invoice, and make or receive payments in one place. With its Google Tasks integration, your Mavenlink project tasks & Google Tasks always stay in sync.
  • Manymoon is the top installed social task and project management app in the Google Apps Marketplace and makes it simple to get work done online with co-workers, partners, and customers. Manymoon's users can now create and view tasks with Gmail and Google Calendar through Google Tasks.
  • Zoho offers a suite of online business, collaboration and productivity applications for small businesses. So far they have integrated Zoho CRM & Zoho Projects with the Tasks API.


Get Started with the Google Tasks API today!

Want to weigh in on this topic? Discuss on Buzz




Posted by Fabian Schlup & Nicolas Garnier
Google Tasks API Team

On the first anniversary of the Google Apps Marketplace two months ago, I published a post Celebrating 1 year of Integrated Goodness. In that post, I discussed some of the deep integrations with Google Apps that impressed me the most because they can save me valuable time.
On the first anniversary of the Google Apps Marketplace two months ago, I published a post Celebrating 1 year of Integrated Goodness. In that post, I discussed some of the deep integrations with Google Apps that impressed me the most because they can save me valuable time.

Today we’re kicking off a new effort to highlight personal picks from the Marketplace team which we feel have a combination of great functionality, and ease of use due to their deep integrations with Google Apps.

We’ll highlight these apps a few times each month via Twitter using the hashtag #mpstaffpick. We’ll also be promoting staff picks on the Marketplace and sharing them internally amongst our sales teams. We hope this will help make it even easier for customers to find great apps on the Marketplace.

Our first staff pick

Our first staff pick is Mavenlink, a highly-rated app in the Marketplace. It is a custom-branded project management solution that allows teams to collaborate online, share files, track time, invoice, and make or receive payments, all inside one end-to-end App. Google Apps users can also easily share documents, access contacts, and track projects on their calendars.

If you happen to be at Google I/O next week, you can meet the Mavenlink team in our Developer Sandbox and ask them more about their app and integrations.

What can you do to become a staff pick?

Staff picks are subjectively chosen by members of the Google Apps Marketplace team. However, we’d like to provide a hint of some of the things we may look at:

How can you get your app on our radar?

We regularly review the apps in the Marketplace and keep an eye on blogs, twitter and other sources to hear about great apps. If you think your app should be a staff pick and want to be sure your app is on our radar, you can fill out this form. We’ll review all submissions, but may not respond directly. We may also choose apps which are not submitted via this form.

To stay up to date and hear about our next pick, follow us on twitter at GoogleAtWork and keep an eye out for the hashtag #mpstaffpick.

Want to weigh in on this topic? Discuss on Buzz



Ryan Boyd profile | twitter | events

Ryan is a Developer Advocate on the Google Apps Marketplace team, helping businesses build applications integrated into Google Apps. Wearing both engineering and business development hats, you'll find Ryan writing code and helping businesses get to market with integrated features.

Editor’s Note: Guest author Steve Webster works at Dito. Dito has developed applications such as Dito Directory which is available in the Google Apps Marketplace.

When composing Gmail conversations, the auto-complete feature allows us to see our matching personal contacts as we type and quickly make our contact selections. This time-saving feature can be duplicated when creating Google Apps Script applications. For instance, if you design an application that requires sending emails, you can leverage this auto-complete feature by using a personal contact list.
Editor’s Note: Guest author Steve Webster works at Dito. Dito has developed applications such as Dito Directory which is available in the Google Apps Marketplace.

When composing Gmail conversations, the auto-complete feature allows us to see our matching personal contacts as we type and quickly make our contact selections. This time-saving feature can be duplicated when creating Google Apps Script applications. For instance, if you design an application that requires sending emails, you can leverage this auto-complete feature by using a personal contact list.

Defining the Requirements

By observing the behavior while composing Gmail conversations, we can define the requirements of our application.

1. As the user begins typing, a list of matches based on first and last name and email address need to appear under the text box. In other words, the user can begin typing the contacts first name, last name, or their email address.

2. If the desired contact email is listed at the top of the matching list, the user can simply press the Enter key to select it.

3. Another option is to click on any of the contacts in the list.

4. Just in case the user would like to enter an email that is not in their contact list, they may enter the email and press the Enter key.

As an added feature if the email is not formatted correctly, then the invalid email is ignored and not selected. For our application when emails are selected, they will be compiled in a separate list on the right where only the email address is stored. If an email is selected by accident, the user can remove the email by clicking on it.

Designing the Application

The application was designed to mimic the behavior of composing Gmail messages. By doing so, the application avoided the use of buttons, providing an improved user experience.

1. Apps Script Services

The Apps Script’s Spreadsheet Service was used to store a user’s contact data. The Ui Service provided the application interaction with the user, and the Contacts Service was leveraged to gather all the user’s contacts. You may apply a Google Apps domain only filter for the contacts by changing the global variable to “true” in the script.

2. Visualize the Layout

Before writing code, the layout was sketched out to include a text box, some space beneath to list matches, and an area to the right to display the selected emails.

3. Choose your widgets

A text box widget was chosen to allow email entry, and two open list boxes were leveraged to display contact matches and selected emails. List boxes provided the use of click handlers to process email selections.

4. Challenges

To mimic the Gmail auto-complete behavior, the text box needed the ability to handle both keystrokes and a pressed Enter key. To accomplish this, a KeyUpHandler calls a function to identify contact matches via a search. The same function used an e.parameter.keyCode == 13 condition to determine when the enter key is pressed.

//create text box for auto-complete during email lookup in left grid
var textBox = app.createTextBox().setName('textBox')
.setWidth('330px').setId('textBox');
var tBoxHandler = app.createServerKeyHandler('search_');
tBoxHandler.addCallbackElement(textBox);
textBox.addKeyUpHandler(tBoxHandler);
...
function search_(e){
var app = UiApp.getActiveApplication();
app.getElementById('list').clear();
var searchKey = new RegExp(e.parameter.textBox,"gi");
if (searchKey == "") app.getElementById('textBox').setValue('');
var range = sheetOwner.getRange(1, 1, sheetOwner.getLastRow(), 2).getValues();
var listBoxCount = 0;
var firstOne = true;
for (var i in range){
// if first/last name available, display name and email address
if (range[i][0].search(searchKey) != -1 || range[i][1].search(searchKey) != -1){
if (range[i][0].toString()){
app.getElementById('list').addItem(range[i][0].toString()+
' .. '+range[i][1].toString(), range[i][1].toString());
var listBoxCount = listBoxCount + 1;
} else { // else just display the email address
app.getElementById('list').addItem(range[i][1].toString());
var listBoxCount = listBoxCount + 1;
}
if (firstOne) var firstItem = range[i][1].toString();
var firstOne = false;
}
}
// set the top listbox item as the default
if (listBoxCount > 0) app.getElementById('list').setItemSelected(0, true);
// if enter key is pressed in text box, assume they want to add
// the email that’s not in the list
if (e.parameter.keyCode==13 && listBoxCount < 1 && searchKey !== "") {
...

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

You can find Dito’s Email Auto-Complete Script here. To view a video demonstration click here. You can also find Dito Directory on the Google Apps Marketplace.

Want to weigh in on this topic? Discuss on Buzz

Over the next few days we will be rolling out an expansion to the feature set of the Google Documents List API. Third-party applications may now upload files of any type to any Google Account. Previously, this was only possible for Google Apps for Business users.
Over the next few days we will be rolling out an expansion to the feature set of the Google Documents List API. Third-party applications may now upload files of any type to any Google Account. Previously, this was only possible for Google Apps for Business users.

This feature allows developers to roll out their solutions to all Google Docs users. For instance, it’s now possible for developers to build applications that allow all users to back up files from their local hard drive to the cloud. There are a variety of other possible uses for this feature, and some examples include revision control and file distribution. Third-party applications (such as those on the Google Apps Marketplace) can also now use Google Docs as the primary place to store their data without the hassle of creating different solutions for customers of Google Apps for Business versus the free edition of Google Apps.

After they are uploaded, files are available in the Google Docs interface:


To enable uploads for all file types, developers must use the resumable upload feature of the API, and also pass in the ?convert=false URL parameter.

We have also added checksums to all files that are not converted to a native Google Docs format. This means that if you upload a file type we can't convert, or if you choose not to convert a file to a native format, a checksum is now available to help guarantee the integrity of the file between storage and retrieval.

We are also in the process of adding checksums to all previously uploaded unconverted files. Due to the popularity of uploading unconverted files, processing this backlog will take some time to complete.

We’ve recently made a lot of improvements to the documentation that should make implementing all of this easier. For further help, please have a look in the forum.

Want to weigh in on this topic? Discuss on Buzz