【发布时间】:2017-08-28 05:03:16
【问题描述】:
我已经实现了一个使用日历 API 创建日历事件的 c# 应用程序。
为了使日历与我们的本地数据库保持同步,我在日历上创建了一个手表。以下代码执行此操作,据我所知,创建了一个手表。
Channel watchChannel = new Channel()
{
Id = ConfigurationManager.AppSettings["GOOGLE_CALENDAR_WATCH_NAME"],
Type = "web_hook",
Address = ConfigurationManager.AppSettings["GOOGLE_CALENDAR_SYNC_TRIGGER_CALLBACK_URL"],
Expiration = (unixTimestamp + NINETY_DAYS_IN_SECONDS) * 1000 //milliseconds
};
try
{
logger.Debug("Creating calendar watch with the name " +
ConfigurationManager.AppSettings["GOOGLE_CALENDAR_WATCH_NAME"] + " for calendar with id " + remoteCalendarId);
Channel returnChannel = service.Events.Watch(watchChannel, remoteCalendarId).Execute();
我的问题是回调 URL 没有被调用(我已经确认了域的所有权并为用户验证了它,这不应该是问题)。
- 如何调试它?有没有什么地方可以查看谷歌的尝试 调用回调URL?
- 我说,据我所知,一切都创建好了,但也许我错了,哪个属性在 returnChannel 我应该看吗?
- 有没有办法列出为特定日历创建的所有手表/频道?如果是这样,是通过哪个 API 公开的?
04.04 - 更多信息:
这些是在呼出(watchChannel)和返回对象(returnChannel)上设置的参数。
watchChannel
- 地址“https://a.domain.com/api/schedule/syncDbAndSchedule”
- ETag = null
- 过期 = 1491309746000
- Id = "my_id_watch_dev"
- 种类 = null
- 参数__ = null
- 有效载荷 = null
- ResourceId = null
- ResourceUri = null
- 令牌 = null
- Type = "web_hook"
returnChannel
- 地址=空
- ETag = null
- 过期 = 1491309746000
- Id = "my_id_watch_dev"
- 种类 = "api#channel"
- 参数__ = null
- 有效载荷 = null
- ResourceId = "t6uxfXzXXXXXXXXXXsC9ZEqMdzU"
- ResourceUri = "https://www.googleapis.com/calendar/v3/calendars/a.domain.com_nsqpp2XXXXXX93olf0ul40sphg@group.calendar.google.com/events?maxResults=250&alt=json"
- 令牌 = null
- 类型=空
再看一遍,我还有几个问题:
- 我可以确定上面返回了 HTTP-200 响应吗?客户端库似乎抽象出了实际的请求/响应,我在我正在查看的对象中找不到它的任何痕迹。由于我收到的 4xx 响应已转换为异常,这是我对任何非 200 响应的预期,但我可以确定吗?
- 真的没有办法跟踪谷歌在调用回调 URL 时所做的尝试吗?由于似乎没有办法获得已创建的手表,因此令我感到惊讶的是,没有可以跟踪它的 GUI。让寻找错误变得非常困难。
验证码
我使用以下代码对系统用户进行身份验证,然后使其伪装成“普通”非系统帐户(因为如果您真的想查看纯系统帐户似乎是一种棘手的方法)日历也是)。
ServiceAccountCredential credential =
GoogleCredential.FromJson(GOOGLE_SYSTEM_USER_AUTH_INFORMATION)
.CreateScoped(Scopes)
.UnderlyingCredential as ServiceAccountCredential;
var userField =
typeof(ServiceAccountCredential).GetField("user", BindingFlags.NonPublic | BindingFlags.Instance);
userField?.SetValue(credential, GOOGLE_CALENDAR_USERNAME); //Act in the guise of the normal user GOOGLE_CALENDAR_USERNAME
service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
我一时兴起访问了返回的 ResourceURI。它给了我
{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
}
}
是
- 这是手表的状态?如果是这样,为什么我在创建它时没有得到 403?
- 我真的是未经身份验证,还是只是我通过浏览器的请求是?
【问题讨论】:
-
您尝试对日历事件进行哪些更改?
unixTimestamp的值是多少? (如果您提供minimal reproducible example 会有所帮助。)我看不到任何列出手表的方式......以及确认所有权,您是否将域添加到您的项目列表中,根据@987654324 @? -
我用更多信息更新了我的问题。回答你的问题。 Unixtimestamp - 见上文。域被添加到项目的列表中(这就是我确认所有权的意思,尽管这有点不精确)。我没有办法为您提供可验证的示例,因为这意味着我必须发布我们使用的密钥。
-
谢谢 - 会看一下,如果我想不通,会在内部提出:(
-
哇,说说快速反应吧。请告诉我是否可以向您提供任何对您有帮助的信息。如您所见,我特意删除了可以唯一识别手表的信息。我还应该提到,呼叫是通过具有域范围权限的服务帐户进行的。并且使用相同的帐户,我之前能够启动并运行它,尽管 PoC 中的参数略有不同(我已经尝试运行之前再次工作的 PoC,但现在它没有,所以我遇到了这样的问题似乎是呼叫限制)。
-
这本身就是有用的信息。要么有限制,要么可能有什么东西被破坏了。我怀疑我能否直接解决,但我会确保有人这样做:)
标签: c# calendar google-calendar-api google-api-dotnet-client