https://www.google.com/calendar/feeds/default/freebusy/busy-times/userID
userID
https://www.google.com/calendar/feeds/default/freebusy/busy-times/batch
<feed xmlns='http://www.w3.org/2005/Atom'xmlns:app='http://www.w3.org/2007/app'xmlns:batch='http://schemas.google.com/gdata/batch'xmlns:gCal='http://schemas.google.com/gCal/2005'xmlns:gd='http://schemas.google.com/g/2005'> <batch:operation type='query'/> <entry> <id>http://www.google.com/calendar/feeds/default/freebusy/busy-times/liz%40example.com</id> </entry> <entry> <id>http://www.google.com/calendar/feeds/default/freebusy/busy-times/bob%40example.com</id> </entry> <entry> <id>http://www.google.com/calendar/feeds/default/freebusy/busy-times/luke%40example.com</id> </entry></feed>
<feed xmlns="http://www.w3.org/2005/Atom" …> <id>https://www.google.com/calendar/feeds/default/freebusy/batch/1234</id> <updated>2010-03-13T00:00:00.000Z</updated> <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/gCal/2005#freebusy"/> <title>Batch Feed</title> <entry xmlns:batch="http://schemas.google.com/gdata/batch" …> <id>http://www.google.com/calendar/feeds/default/freebusy/liz%40example.com</id> … updated, category, self link, author and batch info … <gCal:timeRange> <gd:when startTime='2010-03-13T00:00:00Z' endTime='2010-03-14T00:00:00Z'/> <gCal:timeRange> <gCal:busy> <gd:when startTime='2010-03-13T14:00Z' endTime='2010-03-13T14:30Z'/> </gCal:busy> <gCal:busy> <gd:when startTime='2010-03-13T16:00Z' endTime='2010-03-13T16:30Z'/> </gCal:busy> </entry> <entry …> <id>http://www.google.com/calendar/feeds/default/freebusy/bob%40example.com</id> … Free-busy entry content for Bob … </entry> <entry …> <id>http://www.google.com/calendar/feeds/default/freebusy/luke%40example.com</id> … Free-busy entry content for Luke … </entry></feed>
https://www.google.com/calendar/feeds/default/freebusy/group/groupID/busy-times
groupID
Posted by Alain Vongsouvanh and Nicolas Garnier, Google Calendar API Team
Want to weigh in on this topic? Discuss on Buzz
"The results have been fantastic. Since the launch of the Google Apps Marketplace in March, we’ve been signing up as many as 1000 new businesses per week ... and that’s with no sales or marketing people in our company. These customers are finding us on their own in the Google Apps Marketplace, adding the app and getting engaged with it.""Google Apps Marketplace customers upgrade to a premium edition of Manymoon at a 30% higher rate than non-Google Apps Marketplace customers. The best part, however, is that our monthly registrations increased by 150% since the launch of Google Apps Marketplace. And that’s where the Marketplace really excels, it provides large enough volumes to make the Freemium business model work."
Posted by Don Dodge, Google Apps Marketplace Team
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!
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.
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.
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
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!
Posted by Steven Bazyl, Google Apps Marketplace Team
<?xml version="1.0" encoding="UTF-8" ?><ApplicationManifest xmlns="http://schemas.google.com/ApplicationManifest/2009"> <Name>[ApplicationName]</Name><Description>[Description]</Description> <!-- Administrators and users will be sent to this URL for application support --><Support><!-- URL for application setup as an optional redirect during the install --><Link rel="setup" href="[ApplicationSetupUrl]?domain=${DOMAIN_NAME}" /> <!-- URL for application configuration, accessed from the app settings page in the control panel --><Link rel="manage" href="[ApplicationAdminUrl]?domain=${DOMAIN_NAME}" /> <!-- URL explaining how customers get support. --><Link rel="support" href="[ApplicationHelpUrl]" /> <!-- URL that is displayed to admins during the deletion process, to specify policies such as data retention, how to claim accounts, etc. --><Link rel="deletion-policy" href="[ApplicationPolicyUrl]" /></Support> <!-- Show this link in Google's universal navigation for all users --><Extension id="navLink" type="link"> <Name>[ApplicationName]</Name> <Url>[ApplicationLoginUrl]?domain=${DOMAIN_NAME}</Url> <!-- Used API's --> <Scope ref="contactFeed"/> <Scope ref="spreadsheetFeed"/> <Scope ref="doclistFeed"/></Extension> <!-- Declare our OpenID realm so our app is white listed --><Extension id="realm" type="openIdRealm"> <Url>[ApplicationRealm]</Url></Extension> <Scope id="doclistFeed"> <Url>https://docs.google.com/feeds/</Url> <Reason>[Reason]</Reason></Scope> <Scope id="contactFeed"> <Url>https://www.google.com/m8/feeds/</Url> <Reason>[Reason]</Reason></Scope> </ApplicationManifest>
def login # The domain needs to be set. For example with params[:domain]authenticate_with_open_id(params[:domain]), { :required => ["http://axschema.org/contact/email"], :return_to => '/login'}) do |result, identity_url, registration| if result.successful? # Succesfully logged in, retrieve email address email = get_email(registration) else # Failed to login endend end def get_email(registration) ax_response = OpenID::AX::FetchResponse.from_success_response( request.env[Rack::OpenID::RESPONSE]) ax_response.data["http://axschema.org/contact/email"].first end
CONSUMER_KEY = "Your-consumer-key"CONSUMER_SECRET = "Your-consumer-secret" def get_contacts # Retrieve contacts email = "user@email.com" url = "https://www.google.com/m8/feeds/contacts/default/full?xoauth_requestor_id=#{email}" contacts = gdata_request(url, :get)end def gdata_request(url, method, headers = {}, data = "") uri = URI.parse(url) # Setting up two-legged-oauth consumer = OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET) oauth_params = {:consumer => consumer, :method => method, :request_uri => uri.to_s} # Set Net:HTTP connection http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = (uri.port == 443) if method == :post req = Net::HTTP::Post.new(uri.request_uri) req.body = data else req = Net::HTTP::Get.new(uri.request_uri) end # Set authorization header oauth_helper = OAuth::Client::Helper.new(req, oauth_params) req.initialize_http_header(headers.merge({'Authorization' => oauth_helper.header})) # Execute request response = http.request(req) response.body end
def submit_csv_to_gdocs email = 'user@email.com' url = 'https://docs.google.com/feeds/default/private/full?xoauth_requestor_id=#{email}' # Create new CSV csv = StringIO.new CSV::Writer.generate(csv, ',') do |line| line << ["Example 1", "Example 2"] end csv.rewind # Send request gdata_request(url, :post, { 'Content-Type' => 'text/csv', 'Slug' => 'test.csv', 'GData-Version' => '3.0' }, csv.read)end
Posted by Rui Jiang, Google Apps Marketplace Team
We just released version 1.7 of the .NET GData client library which adds support for two extensions of the Google Apps Provisioning API: Organization Units and Multiple Domains. It also adds a default retry count for failed HTTP requests and fixes a set of issues, including one on the implementation of the ResumableUploader component introduced in the previous version.
For the complete list of changes, check the Release Notes: http://google-gdata.googlecode.com/svn/trunk/clients/cs/RELEASE_NOTES.HTML
The new version of the .NET GData client library can be downloaded from http://code.google.com/p/google-gdata/downloads/list and, as usual, you are invited to report issues of file feature requests at http://code.google.com/p/google-gdata/issues/list.
Posted by Claudio Cherubino, Developer Relations Team