C Hall
C Hall

Reputation: 303

Google Calendar API V3 FreeBusy request receives Bad Request Error

I'm trying to fetch FreeBusy data from my Google calendar using the .NET client API V3.

The following code allows me to login using a service authentication and fetch the calendar list and calendar settings. I can also fetch the events as shown.

To make this work I have shared my calendar with my development Id:

<my-id>@developer.gserviceaccount.com

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Google.Apis.Calendar;
using Google.Apis.Calendar.v3;
using Google.Apis.Authentication;
using Google.Apis.Authentication.OAuth2;
using Google.Apis.Authentication.OAuth2.DotNetOpenAuth;
using DotNetOpenAuth.OAuth2;
using System.Diagnostics;
using Google.Apis.Calendar.v3.Data;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Discovery;
using Google.Apis.Drive.v2;
using Google.Apis.Util;

namespace consoleGoogleResearch
{
    class Program
    {
        private const string SERVICE_ACCOUNT_EMAIL = "<your-value>@developer.gserviceaccount.com";
        private const string SERVICE_ACCOUNT_PKCS12_FILE_PATH = @"<path-to\<your-value>-privatekey.p12";

        /// <summary>
        /// Build a Calendar service object authorized with the service account.
        /// </summary>
        /// <returns>Drive service object.</returns>
        static CalendarService BuildCalendarService()
        {
            AssertionFlowClient client = new AssertionFlowClient(
                GoogleAuthenticationServer.Description, new X509Certificate2(SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret", X509KeyStorageFlags.Exportable))
            {
                Scope = CalendarService.Scopes.Calendar.GetStringValue(),
                ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
            };
            OAuth2Authenticator<AssertionFlowClient> authenticator = new OAuth2Authenticator<AssertionFlowClient>(client, AssertionFlowClient.GetState);
            return new CalendarService(authenticator);
        }

        public static void Main(string[] args)
        {
            var service = BuildCalendarService();

            // Get the calendar service
            Google.Apis.Calendar.v3.CalendarListResource.ListRequest clrq = service.CalendarList.List();
            var result = clrq.Fetch();

            // Prove we can get the settings.
            SettingsResource.ListRequest slr = service.Settings.List();
            var sr = slr.Fetch();

            try
            {
                Console.WriteLine("Calendars: ");
                foreach (CalendarListEntry calendar in result.Items)
                {
                    Console.WriteLine("{0}", calendar.Id);
                    Console.WriteLine("\tAppointments:");
                    Google.Apis.Calendar.v3.EventsResource.ListRequest elr = service.Events.List(calendar.Id);
                    var events = elr.Fetch();
                    if (events.Items != null)
                    {
                        foreach (Event e in events.Items)
                        {
                            Console.WriteLine("\tSummary: {0}, Location: {1}", e.Summary, e.Location);
                            if (e.IsAllDayEvent())
                            {
                                Console.WriteLine("\t\tAll Day: {0}", e.Start.GetDateTime().ToLongDateString());
                            }
                            else
                            {
                                Console.WriteLine("\t\tFrom: {0}", e.Start.GetDateTime());
                                Console.WriteLine("\t\tTo: {0}", e.End.GetDateTime());
                            }
                            if (e.Attendees != null)
                            {
                                foreach (var att in e.Attendees)
                                {
                                    Console.WriteLine("Attendee:\t\t\t{0}<{1}>", att.DisplayName, att.Email);
                                }
                            }
                            Console.WriteLine();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                log.DebugFormat("Error: {0}", ex.Message);
            }

            // Attempt to get free busy data.
            FreebusyResource.QueryRequest fbq = service.Freebusy.Query(new FreeBusyRequest());

            FreeBusyRequestItem c = new FreeBusyRequestItem();
            c.Id = "<your calendar id>";
            fbq.Body.Items = new List<FreeBusyRequestItem>();
            fbq.Body.Items.Add(c);
            fbq.Body.TimeZone = "Europe/London";
            fbq.Body.TimeMin = "2013-01-101T00:00:00.000Z";
            fbq.Body.TimeMax = "2013-01-301T00:00:00.000Z";

            // This call fails with global bad request
            var fbres = fbq.Fetch();

            Console.ReadKey();
        }
    }

    static internal class Extensions
    {
        static internal DateTime GetDateTime(this EventDateTime edt)
        {
            if (String.IsNullOrEmpty(edt.DateTime))
            {
                if (String.IsNullOrEmpty(edt.Date))
                {
                    return DateTime.MinValue;
                }
                else
                {
                    return DateTime.Parse(edt.Date);
                }
            }
            else
            {
                return DateTime.Parse(edt.DateTime);
            }
        }

        static internal Boolean IsAllDayEvent(this Event e)
        {
            return (e.Start.DateTime == null && e.Start.Date != null);
        }
    }
}

However the code that attempts to fetch free busy information always receives a "bad request" error.

I have checked the request sent using fiddler and as far as I can see it is correct.

POST https://www.googleapis.com/calendar/v3/freeBusy?alt=json&prettyPrint=true HTTP/1.1
Authorization: Bearer <removed>
Content-Type: application/json; charset=utf-8
User-Agent: ConsoleApplication1 google-api-dotnet-client/ Win32NT/6.1.7601.65536 (gzip)
Host: www.googleapis.com
Content-Length: 144
Accept-Encoding: gzip, deflate

{"items":[{"id":"[email protected]"}],"timeMax":"2013-01-301T00:00:00.000Z","timeMin":"2013-01-101T00:00:00.000Z","timeZone":"Europe/London"}

Can anyone tell me why I'm receiving the bad request error and more importantly how to fix it?

Many thanks

Chris.

Upvotes: 0

Views: 3235

Answers (1)

C Hall
C Hall

Reputation: 303

The answer is in the comment above, I made a mistake with the dates.

Upvotes: 2

Related Questions