Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web

Using Google Calendar with VB.NET and ASP.NET

5.00/5 (13 votes)
1 Jan 2012CPOL3 min read 115K   6.6K  
How to use the Google Calendar API from VB.NET.

Introduction

CalendarThumb.gif

I searched and searched, but I couldn't find any complete examples which showed how to directly work with the Google Calendar API, so after piecing together my solution from many many different examples, I decided to publish this small project as much for my own needs to cement the methodologies in my own mind as to help others who may also need to do the same.

Background

There are several similar articles that I draw from, one of those is here on The Code Project: Using Google Calendar with ASP.NET by Igor Alekseev.

In fact, up to the point when I found his article, I'd been having a very hard time getting my events to go into the particular calendar where I wanted them to go, and Igor's code was the first that I'd come across that clearly defined out which URIs were which for the Google service.

I've sort of mimicked Igor's method of passing the CalendarService object ByRef to subsequent functions, because this is key in avoiding getting smacked by the Google Ban Hammer, which can provide some interesting errors in the middle of your testing!

Most importantly of all, however, might have been his intuition about this line of code:

VB
calFeed.Entries(x).Id.AbsoluteUri.Substring(63) 

Up until I discovered "substring(63)" I was having a helluva time getting reliable calendar IDs!

Thanks Igor!

Using the Code

I strived to maintain two different methodologies with this code, one being a single call, and the other being a compound call... the single call is used in my own application when, for instance, a new row is added to a table of our database. I can make one call and push that data to the calendar... that method also makes it very well suited for Web Service calls. The other method is nice when you need to perform multiple steps from your client code, it allows you to get your CalendarService object in one call, and then continually reuse it in your subsequent actions so that your login is not repeated against Google for each call.

A single call will usually look like this:

VB
Dim g As New GoogleCalSvc, str as String
str = g.A1ListMyCalendars

While a multiple or compound call might look like this:

VB
Dim g As New GoogleCalendar_KellyTours, str as string
str = str & g.FindEvent(g.GetCalendarService, "123")

Or maybe even like this, where the service object, s, is used repeatedly:

VB
Dim g As New GoogleCalSvc
Dim s = g.GetCalendarService
Dim out As String = g.FindEvent(s, "Primary", "123")
out = out & g.FindEvent(s, "Primary", "456")
out = out & g.FindEvent(s, "Primary", "789")
Me.output.InnerHtml = out

Points of Interest

Once you get over the fact that most of the code and documentation on the internet is for projects in C#, with a little work, you end up finding that the API is actually pretty easy to work with. With continued development, this project could easily progress into a full featured wrapper interface for all calendar access.

In my own usage, I also have extra database code right within this file, so I can just pass a record ID to some functions, and they automatically publish, update, etc., the needed record to/from the calendar in a pretty much real time fashion.

Code Listing

VB
Imports System.IO
Imports System.Data.SqlClient

Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel

'Imports Google.GData.AccessControl
Imports Google.GData.Calendar
Imports Google.GData.Client
Imports Google.GData.Extensions

' To allow this Web Service to be called from script,
' using ASP.NET AJAX, uncomment the following line.
' <System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://localhost/GoogleCalendarInVBNET/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
Public Class GoogleCalSvc
    Inherits System.Web.Services.WebService

    Private Const userName As String = "SomeUser@GMailOrGoogleAppsDomain.com"
    Private Const userPassword As String = "SomeStrongPassword"

    '' Here's the feed to access events on the users' private/primar calendar:
    Private feedUri As String = _
      "https://www.google.com/calendar/feeds/default/private/full?max-results=9999"
    '' Here's the feed that lists all calendars that this user has access to:
    Private Const feedOwnCalendars As String = _
      "https://www.google.com/calendar/feeds/default/owncalendars/full"
    '' This is a feed for non-primary calendars that requires an ID field,
    '' taken from enumerating the users' calendars...
    Private Const CALENDAR_TEMPLATE As String = _
       "https://www.google.com/calendar/feeds/{0}/private/full?max-results=9999"

#Region "Single Call Public Functions"
     <WebMethod()> _
    Public Function A1ListMyCalendars() As String
        Dim str As String
        str = ListAllCalendars()
        Return str
    End Function

    <WebMethod()> _
    Public Function A1CreateEvent(ByVal stCalName As String, ByVal strWhere As String, _
           ByVal strStart As String, ByVal strEnd As String, _
           ByVal strSubject As String, ByVal strBody As String, _
           ByVal strRecurData As String) As String
        Return CreateEvent(GetCalendarService, stCalName, strWhere, _
               strStart, strEnd, strSubject, strBody, strRecurData)
    End Function

    <WebMethod()> _
    Public Function A1DeleteEvent(ByVal intTripNo As Integer, ByVal stCalName As String) As String
        Return DeleteEvent(GetCalendarService, intTripNo, stCalName)
    End Function

    <WebMethod()> _
    Public Function A1ListUsersCalendars() As String
        Dim Service As CalendarService = GetCalendarService()
        Dim query As New FeedQuery
        query.Uri = New Uri(feedUri) ' Private feedUri 'cause for users calendars

        Dim calFeed As AtomFeed
        calFeed = Service.Query(query)

        Dim str As String = ""
        For x As Integer = 0 To calFeed.Entries.Count - 1
            str = str & calFeed.Entries(x).Title.Text
            If calFeed.Entries.Count > 1 And x < (calFeed.Entries.Count - 1) Then
                str = str & ", " & calFeed.Title.Text & vbCrLf
            End If
        Next

        Return str
    End Function

#End Region

#Region "Public GET Functions"
     Public Function GetCalendarService() As CalendarService
        Dim Service As CalendarService = New CalendarService("My-exampleApp-1")
        Service.setUserCredentials(userName, userPassword)
        Return Service
    End Function

    <WebMethod()> _
    Public Function GetCalendarID(ByRef Service As CalendarService, ByVal strCalName As String) As String
        Dim query As New FeedQuery
        Dim str As String = ""

        query.Uri = New Uri(feedOwnCalendars)

        Dim calFeed As AtomFeed
        calFeed = Service.Query(query)

        For x As Integer = 0 To calFeed.Entries.Count - 1
            If calFeed.Entries(x).Title.Text = strCalName Then
                str = calFeed.Entries(x).Id.AbsoluteUri.Substring(63)
            End If
        Next

        Return str
    End Function

    <WebMethod()> _
    Public Function GetCalendarURI(ByRef Service As CalendarService, ByVal stCalName As String) As String
        Dim stURI As String = String.Format(CALENDAR_TEMPLATE, GetCalendarID(Service, stCalName))
        '' Easy override to go back to the users' primary calendar!!!
        If stCalName = "Primary" Then
            stURI = feedUri
        End If
        Return stURI
    End Function
#End Region

    <WebMethod()> _
    Public Function ListAllCalendars() As String
        Dim Service As CalendarService = GetCalendarService()
        Dim query As New FeedQuery
        query.Uri = New Uri(feedOwnCalendars)

        Dim calFeed As AtomFeed
        calFeed = Service.Query(query)

        Dim str As String = ""
        For x As Integer = 0 To calFeed.Entries.Count - 1
            str = str & calFeed.Entries(x).Title.Text & "|" & _
                  calFeed.Entries(x).Id.AbsoluteUri.Substring(63) & vbCrLf
        Next

        Return str
    End Function

    <WebMethod()> _
    Public Function DeleteAllEvents(ByVal strCalName As String) As String

        Dim str As String = ""

        Dim Service As CalendarService = GetCalendarService()
        Dim query As New FeedQuery
        query.Uri = New Uri(GetCalendarURI(Service, strCalName))

        Dim calFeed As AtomFeed
        calFeed = Service.Query(query)

        If calFeed.Entries.Count > 0 Then
            For x As Integer = 0 To calFeed.Entries.Count - 1
                str = str & calFeed.Entries(x).Title.Text & vbCrLf
                calFeed.Entries(x).Delete()
            Next
        End If

        Return str

    End Function

    Public Function DeleteEvent(ByRef Service As CalendarService, _
           ByVal strSearchFor As String, ByVal stCalName As String) As String

        Dim str As String = ""

        Dim query As New FeedQuery
        query.Uri = New Uri(GetCalendarURI(Service, stCalName))
        query.Query = strSearchFor

        Dim sFeed As EventFeed = Service.Query(query)
        Dim Exists As Boolean = False

        If sFeed.TotalResults > 0 Then
            Exists = True

            Dim calFeed As AtomFeed
            calFeed = Service.Query(query)

            If calFeed.Entries.Count > 0 Then
                For x As Integer = 0 To calFeed.Entries.Count - 1
                    str = str & calFeed.Entries(x).Title.Text
                    calFeed.Entries(x).Delete()
                Next
            End If
        End If

        Return str

    End Function

    Private Function CreateEvent(ByRef Service As CalendarService, _
                                        ByVal strCalName As String, _
                                        ByVal strWhere As String, _
                                        ByVal strStart As String, _
                                        ByVal strEnd As String, _
                                        ByVal strSubject As String, _
                                        ByVal strBody As String, _
                                        ByVal strRecurData As String) As String

        Dim entry As New EventEntry
        entry.Title.Text = strSubject
        entry.Content.Content = strBody

        Dim eventLocation As New Where
        eventLocation.ValueString = strWhere
        entry.Locations.Add(eventLocation)

        Dim eventTime As New [When](strStart, strEnd)
        entry.Times.Add(eventTime)

        Dim postUri As Uri = New Uri(GetCalendarURI(Service, strCalName))
        Dim insertedEntry As AtomEntry = Service.Insert(postUri, entry)

        Return insertedEntry.ToString

    End Function

    Public Function FindEvent(ByRef Service As CalendarService, _
           ByVal strCalName As String, ByVal strSearchFor As String) As String
        Dim strOut As String = ""
        Dim query As EventQuery = New EventQuery

        query.Uri = New Uri(GetCalendarURI(Service, strCalName))
        query.Query = strSearchFor.ToString

        Dim calFeed As EventFeed = Service.Query(query)
        Dim feedEntry As EventEntry
        If calFeed.TotalResults > 0 Then

            For Each feedEntry In calFeed.Entries
                strOut = strOut & (feedEntry.Title.Text) & vbCrLf
            Next
        Else
            strOut = "No Results found"
        End If

        Return strOut
    End Function

    <WebMethod()> _
    Public Function ListUserEvents() As String
        Dim strOut As String = ""
        Dim query As EventQuery = New EventQuery
        Dim service As CalendarService = GetCalendarService()

        query.Uri = New Uri(GetCalendarURI(service, "Primary"))

        Dim calFeed As EventFeed = service.Query(query)
        Dim feedEntry As EventEntry

        For Each feedEntry In calFeed.Entries
            strOut = strOut & (feedEntry.Title.Text) & vbCrLf
        Next

        Return strOut

    End Function

    <WebMethod()> _
    Public Function ListEvents(ByVal strCalName As String) As String
        Dim strOut As String = ""
        Dim query As EventQuery = New EventQuery
        Dim Service As CalendarService = GetCalendarService()

        query.Uri = New Uri(GetCalendarURI(Service, strCalName))

        Dim calFeed As EventFeed = Service.Query(query)
        Dim feedEntry As EventEntry

        For Each feedEntry In calFeed.Entries
            strOut = strOut & (feedEntry.Title.Text) & vbCrLf
            ' list the event title in a messagebox...
        Next

        Return strOut

    End Function

    <WebMethod()> _
    Public Function DeDupeEvents(ByVal strCalName As String) As String
        Dim strOut As String = "", strVal As String = ""
        Dim vals As New Collection
        ' list all the events....
        Dim query As EventQuery = New EventQuery
        Dim service As CalendarService = GetCalendarService()
        query.Uri = New Uri(GetCalendarURI(service, strCalName))

        Dim calFeed As EventFeed = service.Query(query)
        Dim feedEntry As EventEntry

        For Each feedEntry In calFeed.Entries
            strVal = (feedEntry.Title.Text)

            If Not vals.Contains(strVal) Then
                strOut = strOut & strVal
                vals.Add(strVal, strVal)
            Else
                feedEntry.Delete()
            End If

        Next

        Return strOut

    End Function
End Class

History

  • 12/31/2011 - This is my first publishing of this article and code, and I'm sure there'll need to be some updates as this is the first time that I've separated it from the rest of my application.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)