Google कैलेंडर API v3 हमेशा ईवेंट बनाते समय BadRequest लौटाता है

Aug 18 2020

मैंने एक साझा कैलेंडर बनाया और कैलेंडर में ईवेंट जोड़ना चाहता हूं।

मैंने एक परियोजना बनाई और एक सेवा खाता स्थापित किया [email protected]

फिर मैंने मालिक के रूप में सेवा खाते को कैलेंडर साझा किया ।

फिर मैंने गौर किया

सेवा खाते को स्वयं साझा कैलेंडर जोड़ना होगा

जैसा यहाँ वर्णित है https://stackoverflow.com/a/62232361/298430 तथा https://issuetracker.google.com/issues/148804709

इसलिए मैंने एक कोड लिखा:

 @Test
  fun addCalendarToServiceAccount() {

    val calList1: CalendarList = calendar.calendarList().list().execute()
    logger.info("calList1 = {}", calList1)

    val inserted = calendar.calendarList().insert(CalendarListEntry().setId(calendarId)).execute()
    logger.info("inserted = {}", inserted)

    val calList2: CalendarList = calendar.calendarList().list().execute()
    logger.info("calList2 = {}", calList2)
  }

यह पूरी तरह से काम करता है। जब पहली बार बुलाया जाता है, तो मैं देख सकता हूं calList1कि खाली है, और calList2इसमें कुछ है।

फिर मैं मैन्युअल रूप से एक ईवेंट कैलेंडर में सम्मिलित करता हूं (Google कैलेंडर WEB UI के साथ), मैं यह देखना चाहता हूं कि क्या मैं इस घटना को पुनः प्राप्त कर सकता हूं:

@Test
  fun listEvents() {
    val events: Events = calendar.events().list(calendarId).execute()
    logger.info("events = {}", events)
    events.items.forEachIndexed { index, e ->
      logger.info("Event [index = {}] , event = {}", index, e)
    }
  }

यह भी काम करता है।

{
   "accessRole":"owner",
   "defaultReminders":[

   ],
   "etag":"\"xxx\"",
   "items":[
      {
         "created":"2020-08-17T17:51:21.000Z",
         "creator":{
            "email":"[email protected]"
         },
         "end":{
            "date":"2020-08-20"
         },
         "etag":"\"xxx\"",
         "htmlLink":"https://www.google.com/calendar/event?eid=xxx",
         "iCalUID":"[email protected]",
         "id":"xxx",
         "kind":"calendar#event",
         "organizer":{
            "displayName":"xxx",
            "email":"[email protected]",
            "self":true
         },
         "reminders":{
            "useDefault":false
         },
         "sequence":0,
         "start":{
            "date":"2020-08-19"
         },
         "status":"confirmed",
         "summary":"xxx  test1",
         "transparency":"transparent",
         "updated":"2020-08-18T01:07:54.441Z"
      }
   ],
   "kind":"calendar#events",
   "nextSyncToken":"xxx",
   "summary":"xxx",
   "timeZone":"Asia/Taipei",
   "updated":"2020-08-18T01:07:54.688Z"
}

फिर मैं कुछ प्रोग्राम सम्मिलित करना चाहता हूं, जैसे एपीआई उदाहरण दिखाता है:

@Test
  fun testInsertEvent() {
    val now = LocalDateTime.now().withSecond(0).withNano(0)
    val zoneId = ZoneId.of("Asia/Taipei")
    val fromDate = Date.from(now.atZone(zoneId).toInstant())
    val endDate = Date.from(now.plusMinutes(60).atZone(zoneId).toInstant())

    val event = Event()
      .setSummary("Google I/O 2015")
      .setLocation("800 Howard St., San Francisco, CA 94103")
      .setDescription("A chance to hear more about Google's developer products.")
      .setStart(EventDateTime().setDate(DateTime(fromDate, TimeZone.getTimeZone(zoneId))))
      .setEnd(EventDateTime().setDate(DateTime(endDate, TimeZone.getTimeZone(zoneId))))

    logger.info("before insert event : {}", event)

    val eventResult: Event = calendar.events().insert(calendarId, event).execute()
    logger.info("eventResult = {}", eventResult)
  }

मैं ग्राहक को वास्तव में google के समापन बिंदु पर देख सकता हूं:

शरीर है:

{
   "description":"A chance to hear more about Google's developer products.",
   "end":{
      "date":"2020-08-18T11:32:00.000+08:00"
   },
   "location":"800 Howard St., San Francisco, CA 94103",
   "start":{
      "date":"2020-08-18T10:32:00.000+08:00"
   },
   "summary":"Google I/O 2015"
}

लेकिन गूगल ने बिना किसी और विवरण के, केवल 400 बैडर्सपेस्ट का जवाब दिया:

2020-08-18 10:32:15.974 [main] INFO  c.g.a.c.h.HttpResponse - -------------- RESPONSE --------------
HTTP/1.1 400 Bad Request
Transfer-Encoding: chunked
Alt-Svc: h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
Server: ESF
X-Content-Type-Options: nosniff
Pragma: no-cache
Date: Tue, 18 Aug 2020 02:32:15 GMT
X-Frame-Options: SAMEORIGIN
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Encoding: gzip
Vary: Referer
Vary: X-Origin
Vary: Origin
Expires: Mon, 01 Jan 1990 00:00:00 GMT
X-XSS-Protection: 0
Content-Type: application/json; charset=UTF-8

2020-08-18 10:32:15.980 [main] INFO  c.g.a.c.u.LoggingByteArrayOutputStream - Total: 171 bytes
2020-08-18 10:32:15.980 [main] INFO  c.g.a.c.u.LoggingByteArrayOutputStream - {
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "badRequest",
    "message": "Bad Request"
   }
  ],
  "code": 400,
  "message": "Bad Request"
 }
}

मैं एक ही कैलेंडर उदाहरण का उपयोग कर रहा हूं , सफलतापूर्वक addCalendarToServiceAccount()(as owner) और कर सकता हूं listEvents()। लेकिन किसी घटना को सम्मिलित करते समय क्या गलत होता है? क्या मैं कुछ भूल गया?

अन्य क्षेत्र इस प्रकार हैं:

  @Value("\${google.calendar.id}") private lateinit var calendarId: String @Value("\${google.calendar.apiKey}")
  private lateinit var apiKey : String

  private val httpTransport: HttpTransport by lazy {
    GoogleNetHttpTransport.newTrustedTransport()
  }

  private val jacksonFactory: JsonFactory by lazy {
    JacksonFactory.getDefaultInstance()
  }

  private val saCredentials: GoogleCredentials by lazy {
    javaClass.getResourceAsStream("/chancer-d1de03c4c25a.json").use { iStream ->
      ServiceAccountCredentials.fromStream(iStream)
        .createScoped(listOf(
          "https://www.googleapis.com/auth/cloud-platform",
          *CalendarScopes.all().toTypedArray()
        ))
    }.apply {
      refreshIfExpired()
    }
  }


  private val requestInitializer: HttpRequestInitializer by lazy {
    HttpCredentialsAdapter(saCredentials)
  }

  private val calendar: Calendar by lazy {
    Calendar.Builder(httpTransport, jacksonFactory, requestInitializer)
      .build()
  }

वातावरण:

    <java.version>1.8</java.version>
    <kotlin.version>1.4.0</kotlin.version>


    <dependency>
      <groupId>com.google.api-client</groupId>
      <artifactId>google-api-client</artifactId>
      <version>1.30.10</version>
    </dependency>
    <dependency>
      <groupId>com.google.apis</groupId>
      <artifactId>google-api-services-calendar</artifactId>
      <version>v3-rev20200610-1.30.10</version>
    </dependency>
    <dependency>
      <groupId>com.google.auth</groupId>
      <artifactId>google-auth-library-oauth2-http</artifactId>
      <version>0.21.1</version>
    </dependency>

जवाब

2 RafaGuillermo Aug 18 2020 at 17:14

उत्तर:

आपको उपयोग करने की आवश्यकता है start.dateTimeऔर end.dateTimeइसके बजाय start.dateऔरend.date

ठीक कर:

प्रलेखन के अनुसार :

end.date: दिनांक, प्रारूप में "yyyy-mm-dd", यदि यह एक पूरे दिन की घटना है।

end.dateTime: समय, एक संयुक्त दिनांक-समय मान के रूप में (RFC3339 के अनुसार स्वरूपित)। एक समय क्षेत्र ऑफसेट की आवश्यकता है जब तक कि एक समय क्षेत्र स्पष्ट रूप में निर्दिष्ट किया जाता है समयक्षेत्र

start.date: दिनांक, प्रारूप में "yyyy-mm-dd", यदि यह एक पूरे दिन की घटना है।

start.dateTime: समय, एक संयुक्त दिनांक-समय मान के रूप में (RFC3339 के अनुसार स्वरूपित)। एक समय क्षेत्र ऑफसेट की आवश्यकता है जब तक कि एक समय क्षेत्र स्पष्ट रूप में निर्दिष्ट किया जाता है समयक्षेत्र

इसलिए, आपको अपनी तिथि और समय सेटिंग विधि को बदलने की आवश्यकता है:

EventDateTime().setDate(DateTime(fromDate, TimeZone.getTimeZone(zoneId))))

सेवा:

EventDateTime().setDateTime(DateTime(fromDate, TimeZone.getTimeZone(zoneId))))

जो अनुरोध निकाय को इसमें परिवर्तित करेगा:

{
  "description": "A chance to hear more about Google's developer products.",
  "end": {
      "dateTime": "2020-08-18T11:32:00.000+08:00" // modified
  },
  "location": "800 Howard St., San Francisco, CA 94103",
  "start": {
    "dateTime": "2020-08-18T10:32:00.000+08:00" // modified
  },
  "summary": "Google I/O 2015"
}

आप इस विधि के लिए दस्तावेज़ यहाँ देख सकते हैं ।

मैं उम्मीद करता हूँ यह आप के लिए उपयोगी है!

संदर्भ:

  • घटनाक्रम: डालें | कैलेंडर एपीआई | Google डेवलपर्स
  • RFC 3339 - इंटरनेट पर दिनांक और समय: टाइमस्टैम्प
  • EventDateTime (कैलेंडर API v3-Rev20200610-1.30.10)