Editor's note: This post by Google Senior Product Manager Justin Smith has been cross-posted from the Google Code blog because we think it'll be of great interest to Google Apps developers. -- Ryan Boyd
In the coming weeks we will be making three changes to the experimental OAuth 2.0 endpoint. We expect the impact to be minimal, and we’re emailing developers who are most likely to be affected.
https://www.example.com/back?error=access_denied.
https://www.example.com/back?error=access_denied
https://www.example.com/back#error=access_denied
approval_prompt=force
access_type=offline
https://accounts.google.com/o/oauth2/auth? client_id=21302922996.apps.googleusercontent.com& redirect_uri=https://www.example.com/back& scope=https://www.google.com/m8/feeds/& response_type=code
https://accounts.google.com/o/oauth2/auth? client_id=21302922996.apps.googleusercontent.com& redirect_uri=https://www.example.com/back& scope=https://www.google.com/m8/feeds/& response_type=code& access_type=offline& approval_prompt=force
Just a few weeks ago, several members of our Google Apps Developer Relations team returned from Buenos Aires, Sao Paulo, Hyderabad and Bangalore where they met with many enthusiastic developers as part of Google Developer Day and DevFest events. We're now headed to the skies again and looking forward to talking with amazing Russian, Polish, Czech and French developers.
Whether you're building integrations with Google Apps into your products to connect users with their data, helping customers integrate Google Apps with other parts of their Enterprise IT systems, or are simply customizing your own Google Apps environment-- we want to meet you. Drop us a line on Google+ or Twitter and let us know where you'll be.
Here's our schedule:
Here's who's visiting:
“@FOOD”
“@WEIGH”
The Google Apps Marketplace is a storefront for Google Apps customers to discover, purchase, deploy and manage web applications which are integrated with Google Apps. These applications are typically used from desktops and laptops, but many vendors on the Apps Marketplace have also optimized the experience for their users who are on-the-go. There are several different strategies for enabling a mobile workforce, and each requires a different approach to authentication and authorization.
Google has written applications and synchronization clients to help ensure that the core Google Apps data is available to users on their mobile devices, whether they’re on their mobile phones or tablets. By storing contacts, dates and documents from your application in Google Apps using the application APIs, you can leverage these features to provide a mobile view for your users.
Since you’re only accessing the application APIs on your web application’s server, and the user has already linked up their mobile device to their Google account, there are no special techniques for authentication and authorization when using this lightweight approach.
With the latest advances in HTML5 web technologies such as offline and local storage, it’s possible to build mobile interfaces for business apps which are full-featured and accessible to users on many devices. The primary goal in building the mobile web application is to optimize the user experience for different input devices, form factors and limitations in network availability and bandwidth.
Because the application is in a web browser, most of the changes to implement are in the frontend-- HTML, JavaScript and CSS. User authentication and data authorization continue to use the same OpenID and OAuth technologies as are used for the desktop/laptop version of the application.
Does your application need access to hardware-specific APIs which are not available in a web browser, or do you feel a great user experience can only be achieved using native code? Several Apps Marketplace vendors have built native applications for popular mobile platforms like Android and iOS. Although it takes considerably more effort to build multiple native applications to cover the major platforms, these vendors can also take advantage of the additional distribution channels offered by mobile stores.
Authentication and authorization are often challenging for developers building native mobile applications because they cannot simply ask users for a password if their app supports single-sign on to Google with OpenID. We recently published an article describing a technique using an embedded webview for accomplishing OpenID authentication in mobile apps. This article includes references to sample code for Android and iOS.
Editor’s Note: This post written by Ferris Argyle. Ferris is a Sales Engineer with the Enterprise team at Google, and had written fewer than 200 lines of JavaScript before beginning this application. --Ryan Boyd
I started with Apps Script in the same way many of you probably did: writing extensions to spreadsheets. When it was made available in Sites, I wondered whether it could meet our needs for gathering roadmap input from our sales engineering and enterprise deployment teams.
At Google, teams like Enterprise Sales Engineering and Apps Deployment interact with customers and need to share product roadmap ideas to Product Managers. Product Managers use this input to iterate and make sound roadmap decisions. We needed to build a tool to support this requirement. Specifically, this application would be a tool used to gather roadmap input from enterprise sales engineering and deployment teams, providing a unified way of prioritizing customer requirements and supporting product management roadmap decisions. We also needed a way to share actual customer use cases from which these requirements originated.
This required bringing together the capabilities of Google Forms, Spreadsheets and Moderator in a single application: form-based user input, dynamically generated structured lists, and ranking.
This sounds like a fairly typical online transaction processing (OLTP) application, and Apps Script provides rich and evolving UI services, including the ability to create grids, event handlers, and now a WYSIWYG GUI Builder; all we needed was a secure, scalable SQL database backend.
One of my geospatial colleagues had done some great work on a demo using a Fusion Tables backend, so I did a little digging and found this example of how to use the APIs in Apps Script (thank you, Fusion Tables Developer Relations).
Full sample code for this app is available and includes a test harness, required global variables, additional CRUD wrappers, and authorization and Fusion REST calls. It has been published to the Script Gallery under the title "Using Fusion Tables with Apps Script."
/** * Read records * @param {string} tableId The Id of the Fusion Table in which the record will be created * @param {string} selectColumn The Fusion table columns which will returned by the read * @param {string} whereColumn The Fusion table column which will be searched to determine whether the record already exists * @param {string} whereValue The value to search for in the Fusion Table selectColumn; can be '*' * @return {string} An array containing the read records if no error; the bubbled return code from the Fusion query API if error */ function readRecords_(tableId, selectColumn, whereColumn, whereValue) { var query = ''; var foundRecords = []; var returnVal = false; var tableList = []; var row = []; var columns = []; var rowObj = new Object(); if (whereValue == '*') { var query = 'SELECT '+selectColumn+' FROM '+tableId; } else { var query = 'SELECT '+selectColumn+' FROM '+tableId+ ' WHERE '+whereColumn+' = \''+whereValue+'\''; } var foundRecords = fusion_('get',query); if (typeof foundRecords == 'string' && foundRecords.search('>> Error')>-1) { returnVal = foundRecords.search; } else if (foundRecords.length > 1 ) { //first row is header, so use this to define columns array row = foundRecords[0]; columns = []; for (var k = 0; k < row.length; k++) { columns[k] = row[k]; } for (var i = 1; i < foundRecords.length; i++) { row = foundRecords[i]; if( row.length > 0 ) { //construct object with the row fields rowObj = {}; for (var k = 0; k < row.length; k++) { rowObj[columns[k]] = row[k]; } //start new array at zero to conform with javascript conventions tableList[i-1] = rowObj; } } returnVal = tableList; } return returnVal; }
Now all I needed were CRUD-type (Create, Read, Update, Delete) Apps Script wrappers for the Fusion Tables APIs, and I’d be in business. I started with wrappers which were specific to my application, and then generalized them to make them more re-usable. I’ve provided examples above so you can get a sense of how simple they are to implement.
The result is a dynamically scalable base layer for OLTP applications with the added benefit of powerful web-based visualization, particularly for geospatial data, and without the traditional overhead of managing tablespaces.
I’m a Fusion tables beginner, so I can’t wait to see what you can build with Apps Script and Fusion Tables. You can get started here: Importing data into Fusion Tables, and Writing a Fusion Tables API Application.