删除谷歌日历条目/事件时,为什么entry.delete()为400?

时间:2014-01-15 16:24:49

标签: c# mono google-calendar-api

对Google日历进行身份验证,搜索和添加事件/输入正在按预期工作,但删除会导致400错误请求错误。

代码主要是从google's documentation复制的。

googleUri以下是日历条目的链接(由同一个应用程序/用户创建,标题为“要删除的事件”),应该删除,ConfigurationManager.AppSettings包含身份验证信息。

调试输出显示找到日历条目,但删除不成功。

这使用了Google Calendar API v2,它应该在10/2014之前一直运行。迁移到v3会很不错,但据我所知,无法使用已知用户+密码进行身份验证(而是使用需要手动输入Google凭据(?)的过期令牌)。

Debug.Write ("want to remove: " + googleURI);

// autheticate and get service
CalendarService svc = new CalendarService(ConfigurationManager.AppSettings["GoogleCalendarName"]);
svc.setUserCredentials(ConfigurationManager.AppSettings["GoogleCalendarUsername"], ConfigurationManager.AppSettings["GoogleCalendarPassword"]);
svc.QueryClientLoginToken();

// find the event(s) -- should only be one that can match the googleuri
EventQuery evtquery = new EventQuery(ConfigurationManager.AppSettings["GoogleCalendarPostURI"]);
evtquery.Uri = new Uri(googleURI);
EventFeed evtfeed = svc.Query (evtquery);

//should only be one event in the query
if (evtfeed == null || evtfeed.Entries.Count != 1) {
Debug.Write ("No match or too many matches for " + googleURI); // if this is less than 1, we should panic
    return;
}

// we found the right one
EventEntry entry = (EventEntry)(evtfeed.Entries[0]);
Debug.Write ("Title: " + entry.Title.Text);

//hangs here until "The remote server returned an error: (400) Bad Request.
entry.Delete(); 

输出结果为:

[0:] want to remove: https://www.google.com/calendar/feeds/default/private/full/77e0tr0e3b4ctlirug30igeop0
[0:] Title: Event To Delete

我也尝试过将批处理方法用于无法实现

// https://developers.google.com/google-apps/calendar/v2/developers_guide_dotnet?csw=1#batch
// Create an batch entry to delete an the appointment
EventEntry toDelete = (EventEntry)calfeed.Entries[0];
toDelete.Id = new AtomId(toDelete.EditUri.ToString());
toDelete.BatchData = new GDataBatchEntryData("Deleting Appointment", GDataBatchOperationType.delete);


// add the entry to batch

AtomFeed batchFeed = new AtomFeed(calfeed);

batchFeed.Entries.Add(toDelete);


// run the batch

EventFeed batchResultFeed = (EventFeed)svc.Batch(batchFeed, new Uri(ConfigurationManager.AppSettings["GoogleCalendarPostURI"]  ));


// check for succses

Debug.Write (batchResultFeed.Entries [0].BatchData.Status.Code);

if (batchResultFeed.Entries [0].BatchData.Status.Code != 200) {
   return;
}

1 个答案:

答案 0 :(得分:0)

无法弄清楚v2发生了什么,但我能够使用服务帐户转移到API的v3进行验证。

using System;

using Google.Apis.Calendar.v3;
using Google.Apis.Calendar.v3.Data;
// for BaseClientService.Initializer
using Google.Apis.Services;
// provides ServiceAccountCredential
using Google.Apis.Auth.OAuth2; 
// read in cert
using System.Security.Cryptography.X509Certificates;


namespace LunaIntraDBCalTest
{
    public class Program
    {
        public static string calendarname = "xxxx@gmail.com"; //address is default calendar
        public static string serviceAccountEmail = "yyyy@developer.gserviceaccount.com";

        public static CalendarService getCalendarService(){



            // certificate downloaded after creating service account access at could.google.com
            var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable);

            // autheticate
            ServiceAccountCredential credential = new ServiceAccountCredential(
                new ServiceAccountCredential.Initializer(serviceAccountEmail)
                {
                    Scopes = new[] { CalendarService.Scope.Calendar }
                }.FromCertificate(certificate));

            // Create the service.
            var service = new CalendarService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "LunaIntraDB",
                });

            return service;
        }

        // create event object that will later be inserted
        public static Event createEvent(string Summary, string Location, string Description, DateTime ApptDateTime, double duration ){
            // create an event
            Event entry= new Event
            {
                Summary = Summary,
                Location = Location,
                Description = Description,
                Start = new EventDateTime { DateTime = ApptDateTime },
                End = new EventDateTime { DateTime = ApptDateTime.AddHours(duration) },
            };

            return entry;
        }

        // capture event ID after inserting
        public static string insertEvent(Event entry){
            var service = getCalendarService ();
            EventsResource.InsertRequest insert = service.Events.Insert (entry, calendarname);
            // TODO: try catch here; will be throw exception if bad datetime
            return insert.Execute().Id;
        }

        public static void deleteEvent(string id){
            // TODO CATCH IF NOT FOUND
            // to have access to this calendar, serviceAccountEmail needed permission set by ownner in google calendar
            //Calendar cal1 = service.Calendars.Get (calnedarname).Execute();
            var service = getCalendarService ();
            service.Events.Delete (calendarname, id).Execute ();
        }

        public static void Main(string[] args)
        {

            // create event
            var entry = createEvent ("TEST", "here", "this is a test", DateTime.Now, 1.5);

            string id = insertEvent (entry);
            Console.WriteLine("Run to your calendar to see that this event was created... (any key after checking)");
            Console.ReadKey();

            deleteEvent (id);
            Console.WriteLine("Should now be deleted!... (any key to close)");
            Console.ReadKey();
        }
    }
}