“缺少结束时间”使用Google日历和Racket Google软件包 [英] "Missing End Time" with Google Calendar and Racket Google Package

查看:107
本文介绍了“缺少结束时间”使用Google日历和Racket Google软件包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为 Google API 资料库http://racket-lang.orgrel =nofollow noreferrer>球拍尝试更新Google日历。 (这个API是不完整的,所以我正在扩展它。)



我似乎无法使用events.insert put call将事件添加到日历。这样做的代码看起来像:

 (define(insert-events calendar-id 
event
#:token [t#f]
#:max-attendees [max-attendees #f]
#:send-notifications [send-notifications #f]
#:supports-attachments [支持附件#f])
(json-api-post(字符串 - > url
(格式
https://www.googleapis.com/calendar/v3/calendars / $ a $ events
(form-urlencoded-encode calendar-id)))
event
#:token t))


define(json-api-post ub
#:token [t #f]
#:headers [headers'()])
(define b *(jsexpr-> bytes b) )
(let retry([tt]
[retry-counter 0])
(parse-json-response
(POST-string ub *(if t(cons(token - >一种)
重试
t
retry-counter)))

(define(POST-string ub headers)
(port-> string(post-pure-port ub headers)))

然而,无论如何我如何使用该通话,我总是回复400错误信息:Missing End Time。我检查了这个问题,以确保我正确地发送了我的请求。我似乎是。作为参考,我发送的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 
主机:localhost
用户代理:Racket / 6.5.0.5(net / http-client)
内容长度:116
授权:承载< Key-节录>

{
end:{
dateTime:2016-05-30T14:00:00-04:00
},
开始:{
dateTime:2016-05-30T13:00:00-04:00
}
}

我似乎在做一切正确的事情。即使我的Racket代码中存在一个错误,通过Google的开发人员Web控制台发送完全相同的JSON对象似乎按预期工作。那么为什么发送这个特定的POST不起作用呢?

解决方案

关闭。但是您实际上在POST请求的标题字段中缺少一个重要数据。即:

  Content-Type:application / json 

使您的整个请求成为:

  POST /<日历-ID-节录> HTTP / 1.1 
主机:localhost
用户代理:Racket / 6.5.0.5(net / http-client)
内容长度:116
授权:承载< Key-节录>
Content-Type:application / json

{
end:{
dateTime:2016-05-30T14:00:00-04: 00

开始:{
dateTime:2016-05-30T13:00:00-04:00
}
}

由于某些原因,如果您错过了Google,它不会给您一个很好的错误讯息,但如果如果你运行这个命令,你可以更清楚地看到这一点,如果你像这样运行它(你在哪里有一个名为 data.txt 的文件,其中包含您的json对象:

  curl -X POST -d @ data.txt https://www.googleapis.com/calendar/v3/calendars/<Calendar-Id-Redacted> /events --header'授权:持票人<按键编辑>> ;'

它会失败,但是如果你添加标题 - 头文件Content-Type:application / json,API将按预期工作:

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

将这个头文件添加到库中只需要对生成您的发布请求的函数进行一次修改:

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



<除了我们修改了headers字段以包含(默认情况下)包含字符串的列表:Content-Type:application / json之外,它与前一个完全相同。 code>。有了这个改变,谷歌应该接受你的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 ub
#:token [t #f]
#:headers [headers'(Content-Type:application / json)])
(定义b *(jsexpr->字节b))
(let retry([tt]
[retry-counter 0])
(parse-json-response
(POST-string ub *(if t(cons(token-> authorization-header t)headers)headers))
retry
t
retry-counter)))
$ b $(define(POST-string ub headers)
(port-> string(post-pure-port ub headers)))

希望有所帮助。


I am using a Google API library for Racket to try to update a Google Calendar. (The API is incomplete so I'm extending it as I go.)

I seem to have trouble with adding events to a calendar using the events.insert put call. The code that does the put looks like:

(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)))

However, no matter how I use the call, I always get back an error 400 with the message: "Missing End Time". I checked out this question to ensure that I was sending my request correctly. Which I appear to be. For reference, the JSON object I am sending is:

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

Also, to make sure I was properly accessing the correct key and calendar id, I setup up an echo server for my local machine, and changed the url from google.com to localhost, my response seems normal:

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"
 }
}

I seem to be doing everything correct. And even if there was a bug in my Racket code, sending in the exact same JSON object via Google's developer web console seems to work as intended. So why does sending this particular POST not work?

解决方案

Close. But you are actually missing one piece of important data in the headers field of your POST request. Namely, the line:

Content-Type: application/json

Making your entire request to be:

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"
 }
}

For some reason Google doesn't give you a nice error message if you are missing it, but if you do have it, Google will follow the API call.

This can be seen more clearly when you run the command in curl, if you run it like this (where you have a file called data.txt that has your json object in it:

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

It will fail. But if you add the header with --header "Content-Type: application/json", the API will work as expected:

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"

Adding that header to the library you have just requires one modification to the function that generates your post request:

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

It is exactly the same as your previous one, except we've modified the headers field to contain (by default), the list containing the string: "Content-Type: application/json". With this change, google should accept your API. (Note that there are many other ways to modify the headers function, this is just a simple way to do it.)

Putting it all together, your final code should look something like:

(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)))

Hope that helps.

这篇关于“缺少结束时间”使用Google日历和Racket Google软件包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆