Google Calendar API – getting events from a specific calendar

I recently had to integrate a simple calendar of events into a site I was building in Umbraco CMS. Since it’s almost always such a common piece of functionality, i thought I’d post some code snippets. After looking at some options, I decided to go with Google Calendar.

I won’t lie, I’m a huge Google fan and this was my first option anyway. Just like many other awesome tools from Google, it is incredibly powerful and by far the easiest calendar to manage for the end user. The most appealing part about it is the easy, slick, clean and down-to-business front end which is essentially what you users will see when they browse through events.

There are a few options to do this. You could make your calendar public and work with the feed or you can use Google Data API to query the calendar service. I have never done anything with Google’s API, so i decided to go with this option. The developer guide seemed very straight-forward, but there are a few small gotchas to watch out for. Anyway, let’s jump to some code.

The first thing we must do is authenticate with the Calendar Service. Obviously, we authenticate with a Google account, so make sure you have one handy.

using Google.GData.Calendar;  
using Google.GData.Client;  
...    
string username = ConfigurationManager.AppSettings["GoogleCalendarUser"];  
string password = ConfigurationManager.AppSettings["GoogleCalendarPass"];

CalendarService calService = new CalendarService(CalendarApplicationName);  
calService.setUserCredentials(username, password);  

We are now ready to select the calendar we want to work with. The only thing required for this is to specify whether you want to work with all calendars the user has access to or just the ones where the user has “owner” access, which is what I’m after. If you notice, this is specified by owncalendars in the feed URI.

CalendarQuery calQuery = new CalendarQuery();  
calQuery.Uri = new Uri("https://www.google.com/calendar/feeds/default/owncalendars/full");  
CalendarFeed calFeed = (CalendarFeed)calService.Query(calQuery);  

The calendar service will return CalendarFeed object containing all user-owned calendars. We now want to find the one we want to work with and proceed retrieving events.

var activeCalendar = calFeed.Entries.Where(x => x.Title.Text == "My Calendar").FirstOrDefault();

if (activeCalendar != null)  
{
    EventQuery evtQuery = new EventQuery(GetCalendarFeed(activeCalendar));
    evtQuery.StartTime = DateTime.Now;
    evtQuery.EndTime = DateTime.Now.AddDays(14);
    evtQuery.SortOrder = CalendarSortOrder.ascending;
    evtQuery.FutureEvents = false;

    EventFeed evtFeed = calService.Query(evtQuery);

    foreach (EventEntry entry in evtFeed.Entries)
    {
        if (!entry.Status.Value.Contains("event.canceled"))
        {
              // Read event data
        }
    }
}

...    

private static string GetCalendarFeed(AtomEntry calendarEntry)  
{
    string feedstring = calendarEntry.Id.AbsoluteUri.Substring(63);
    return string.Format("http://www.google.com/calendar/feeds/{0}/private/full", feedstring);
}

The most interesting part about the code snippet above is building the feed URI for the calendar we want to query for events. This is done by parsing AbsoluteUri property to get calendar Id as shown in GetCalendarFeed() method.

Another gotcha is EventQuery.FutureEvents, which when set to true will override your date ranges and return only future events. Even though it is set to “false” by default, i wanted to explicitly point it out in code.

The last issue i ran across occurred after deleting an event. Apparently while it appeared to be deleted from the calendar, it was still returned by the API, but with “canceled” status code.

I don’t want to show canceled events, so we omit these with a simple if statement shown above. And that’s it! Next time I might come back to this and show how to incorporate it into an Umbraco macro.