也许我是唯一认为Google的API文档很糟糕的人,但我花了更多时间在这个简单的任务上,而不是我想要的。
目前,我的项目正在使用GDATA实施来连接Google Calendar API v2。我遵循了这个指南:http://www.codeproject.com/Articles/565032/Google-Calendar-Integration-in-ASP-NET-Create-ed
但是我注意到谷歌今年秋天正在弃用其API的第2版。我试图弄清楚如何连接到他们的版本3 API似乎使用OAuth2。
阅读完他们的文档并在互联网上搜索> :( - 我遇到的问题是每个示例,教程或youtube视频我都会看到如何实现这一点,这涉及用户点击的Google同意屏幕“接受”。
我尝试过以下但真的不确定它是否是正确的方向?
// Register the authenticator. The Client ID and secret have to be copied from the API Access
// tab on the Google APIs Console.
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description);
provider.ClientIdentifier = "MY_CLIENT_ID";
provider.ClientSecret = "MY_CLIENT_SECRET";
// Create the service. This will automatically call the previously registered authenticator.
var service = new CalendarService();
我的应用程序不需要用户的帐户/同意(OAuth),我需要像我目前在代码隐藏中那样进行连接。
所以问题是我如何将当前的实现“升级”到v3?我是否使用OAuth,服务帐户?我发现大量示例显示了如何检索事件并插入事件的v3用法......但它们都通过前端的用户同意屏幕进行身份验证。
这是我目前的GData实施......
public class GoogleGateway : IGoogleGateway
{
private readonly IRepository<UserSetting> _settingsRepository;
private Service _googleService;
private CalendarService _googleCalendar;
private Uri _calendarUri;
public GoogleGateway(IRepository<UserSetting> settingsRepository)
{
_settingsRepository = settingsRepository;
}
public IEnumerable<EventEntry> GetAllEvents(DateTime? startDate)
{
if (!Connect()) return new List<EventEntry>();
// Create the query object:
EventQuery query = new EventQuery();
query.Uri = _calendarUri;
if (startDate != null)
query.StartTime = startDate.Value;
// Tell the service to query:
EventFeed calFeed = _googleCalendar.Query(query);
return calFeed.Entries.Cast<EventEntry>();
}
public bool Connect()
{
var calSettings = _settingsRepository.Get().Where(x => x.Setting == "Calendar");
if (calSettings.Any())
{
var username = calSettings.First(x => x.Meta == "GoogleUsername").Value;
var password = calSettings.First(x => x.Meta == "GooglePassword").Value;
var calendarUri = new Uri(calSettings.First(x => x.Meta == "CalendarFeed").Value);
var applicationName = calSettings.First(x => x.Meta == "ApplicationName").Value;
_calendarUri = calendarUri;
//FeedQuery feedQuery = new FeedQuery();
_googleService = new Service("cl", applicationName);
_googleCalendar = new CalendarService(applicationName);
// Set your credentials:
_googleService.setUserCredentials(username, password);
_googleCalendar.setUserCredentials(username, password);
return true;
}
return false;
}
public void AddEvent(string title, string contents, string location, DateTime startTime, DateTime endTime)
{
if (!Connect()) return;
EventEntry.EVENT_CATEGORY = new AtomCategory("Appointments");
EventEntry entry = new EventEntry
{
Title = { Text = title },
Content = { Content = contents },
};
// Set the title and content of the entry.
// Set a location for the event.
Where eventLocation = new Where();
eventLocation.ValueString = location;
entry.Locations.Add(eventLocation);
When eventTime = new When(startTime, endTime);
entry.Times.Add(eventTime);
Uri postUri = new Uri("http://www.google.com/calendar/feeds/default/private/full");
// Send the request and receive the response:
AtomEntry insertedEntry = _googleCalendar.Insert(postUri, entry);
}
public void DeleteEvent(string eventId)
{
if (!Connect()) return;
var events = GetAllEvents(null);
var appointment = events.First(x => x.EventId == eventId);
_googleService.Delete(appointment);
}
}
我在这一点上越来越绝望,任何帮助都会非常感激。在你的答案中包含你的推特手柄,我会给你买一杯咖啡!
已更新 我目前有以下内容,但我仍未进行身份验证...... :(
static CalendarService BuildService()
{
String serviceAccountEmail = "xxxxxxxxxxxxx-31xxxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com";
var certPath = HttpContext.Current.Server.MapPath("/xxxxxxxxxxxx.p12");
var certificate = new X509Certificate2(certPath, "notasecret", X509KeyStorageFlags.Exportable);
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, <<<<<< DOES NOT RESOLVE!
ApplicationName = "MyApplication",
});
var test = service.Calendars.Get("xxxxxxxxxxxxxxxxxx@group.calendar.google.com");
return service;
}
答案 0 :(得分:2)
问题是您以明文形式存储凭证。在Oauth2中,用户不会向您提供凭据(因此可以访问所有内容),而是让您的应用程序访问特定类型/范围的数据。
从您的描述中不清楚您是否只在控件中完全访问一个日历,或者您有多个用户。在第一种情况下,答案将是使用服务帐户(https://developers.google.com/accounts/docs/OAuth2ServiceAccount)。在第二种情况下,如果您是一个拥有许多用户的日历应用程序,则需要沿着用户同意的道路前进,您应继续阅读:)
对于脱机访问,您可以指定在首次检索凭据时access_type应处于脱机状态。与访问令牌一起,您还将获得刷新令牌,您可以使用该令牌在以后重新进行身份验证,而无需再点击用户(https://developers.google.com/accounts/docs/OAuth2WebServer#refresh)。但是,至少有一个同意屏幕。