"Missing End Time"与谷歌日历和球拍谷歌包



我正在使用Racket的Google API库来尝试更新Google日历。(API是不完整的,所以我正在扩展它。)

我似乎在使用events.insert put调用将事件添加到日历时遇到问题。执行看跌期权的代码看起来像:

(define (insert-events calendar-id
event
#:token [t #f]
#:max-attendees [max-attendees #f]
#:send-notifications [send-notifications #f]
#:supports-attachments [supports-attachments #f])
(json-api-post (string->url
(format
"https://www.googleapis.com/calendar/v3/calendars/~a/events"
(form-urlencoded-encode calendar-id)))
event
#:token t))

(define (json-api-post u b
#:token [t #f]
#:headers [headers '()])
(define b* (jsexpr->bytes b))
(let retry ([t t]
[retry-counter 0])
(parse-json-response
(POST-string u b* (if t (cons (token->authorization-header t) headers) headers))
retry
t
retry-counter)))
(define (POST-string u b headers)
(port->string (post-pure-port u b headers)))

然而,无论我如何使用呼叫,我总是会返回一个错误400,并显示消息:"缺少结束时间"。我勾选了这个问题,以确保我发送的请求是正确的。作为参考,我发送的JSON对象是:

{
"end": {
"dateTime": "2016-05-30T14:00:00-04:00"
},
"start": {
"dateTime": "2016-05-30T13:00:00-04:00"
}
}

此外,为了确保我正确访问了正确的密钥和日历id,我为本地机器设置了一个echo服务器,并将url从google.com更改为localhost,我的响应似乎很正常:

POST /<Calendar-Id-Redacted> HTTP/1.1
Host: localhost
User-Agent: Racket/6.5.0.5 (net/http-client)
Content-Length: 116
Authorization: Bearer <Key-Redacted>
{
"end": {
"dateTime": "2016-05-30T14:00:00-04:00"
},
"start": {
"dateTime": "2016-05-30T13:00:00-04:00"
}
}

我似乎做的每件事都是正确的。即使我的Racket代码中有一个错误,通过谷歌的开发者网络控制台发送完全相同的JSON对象似乎也能正常工作。那么,为什么发送这个特定的POST不起作用呢?

关闭。但是在POST请求的headers字段中,您实际上缺少了一条重要的数据。即线路:

Content-Type: application/json

让你的整个请求成为:

POST /<Calendar-Id-Redacted> HTTP/1.1
Host: localhost
User-Agent: Racket/6.5.0.5 (net/http-client)
Content-Length: 116
Authorization: Bearer <Key-Redacted>
Content-Type: application/json
{
"end": {
"dateTime": "2016-05-30T14:00:00-04:00"
},
"start": {
"dateTime": "2016-05-30T13:00:00-04:00"
}
}

出于某种原因,如果你错过了,谷歌不会给你一个很好的错误消息,但如果你确实有,谷歌会遵循API调用。

当你在curl中运行命令时,如果你像这样运行它(你有一个名为data.txt的文件,里面有你的json对象:

curl -X POST -d @data.txt https://www.googleapis.com/calendar/v3/calendars/<Calendar-Id-Redacted>/events --header 'Authorization: Bearer <Key-Redacted>'

它会失败的。但是如果添加带有--header "Content-Type: application/json"的头,API将按预期工作:

curl -X POST -d @data.txt https://www.googleapis.com/calendar/v3/calendars/<Calendar-Id-Redacted>/events --header 'Authorization: Bearer <Key-Redacted>' --header "Content-Type: application/json"

将该头添加到库中只需要对生成post请求的函数进行一次修改:

(define (json-api-post u b
#:token [t #f]
#:headers [headers '("Content-Type: application/json")])
....)

它与上一个完全相同,只是我们修改了headers字段以包含(默认情况下),该列表包含字符串:"Content-Type: application/json"。有了这个改变,谷歌应该接受你的API。(请注意,还有许多其他方法可以修改头函数,这只是一种简单的方法。)

把所有这些放在一起,你的最终代码应该看起来像:

(define (insert-events calendar-id
event
#:token [t #f]
#:max-attendees [max-attendees #f]
#:send-notifications [send-notifications #f]
#:supports-attachments [supports-attachments #f])
(json-api-post (string->url
(format
"https://www.googleapis.com/calendar/v3/calendars/~a/events"
(form-urlencoded-encode calendar-id)))
event
#:token t))

(define (json-api-post u b
#:token [t #f]
#:headers [headers '("Content-Type: application/json")])
(define b* (jsexpr->bytes b))
(let retry ([t t]
[retry-counter 0])
(parse-json-response
(POST-string u b* (if t (cons (token->authorization-header t) headers) headers))
retry
t
retry-counter)))
(define (POST-string u b headers)
(port->string (post-pure-port u b headers)))

希望能有所帮助。

相关内容

  • 没有找到相关文章

最新更新