Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a new calendar using the Google Calendar API insert method in Javascript returns error 400 "Missing title"

I am trying to create a new calendar in my Google account using Javascript (through the Google Apps Script editor).

First, to make sure my Oauth2 is working with the Calendar API, I make a GET request to get my primary calendar:

var email = '[email protected]';

var fetchArgs = {};
fetchArgs.headers = {'Authorization': 'Bearer '+ calendarOauth2Service.getAccessToken() };
fetchArgs.method = 'GET';
fetchArgs.muteHttpExceptions = true;

var url = 'https://www.googleapis.com/calendar/v3/calendars/' + email;

var response = UrlFetchApp.fetch(url, fetchArgs);

The request is successful and returns this response:

{
 "kind": "calendar#calendar",
 "etag": "\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"",
 "id": "[email protected]",
 "summary": "[email protected]",
 "timeZone": "America/New_York"
}

Now I want to use the insert method to add a calendar to my account:

var calendarResource = {
       "summary": "test calendar title"
      };

var fetchArgs = {};
fetchArgs.headers = {'Authorization': 'Bearer '+ calendarOauth2Service.getAccessToken() };
fetchArgs.method = "POST";
fetchArgs.data = calendarResource;
fetchArgs.muteHttpExceptions = true;

var url = 'https://www.googleapis.com/calendar/v3/calendars';

var response = UrlFetchApp.fetch(url, fetchArgs);

The calendar is not created, and this is the response:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "required",
    "message": "Missing title."
   }
  ],
  "code": 400,
  "message": "Missing title."
 }
}

I've been working on this for almost 20 hours straight now (not an exaggeration) and I can't figure it out. I've tried the following things:

  1. Changing fetchArgs.data = calendarResource; to fetchArgs.body = calendarResource;
  2. Changing fetchArgs.data = calendarResource; to fetchArgs.resource = calendarResource;
  3. Changing fetchArgs.data = calendarResource; to fetchArgs.payload = calendarResource;
  4. Changing fetchArgs.data = calendarResource; to fetchArgs.summary = calendarResource;
  5. Changing fetchArgs.data = calendarResource; to fetchArgs.title = calendarResource;
  6. Moving fetchArgs.data = calendarResource; in to the fetchArgs.header object
  7. Moving fetchArgs.method = "POST"; in to the fetchArgs.header object
  8. Adding fetchArgs.contentType = 'application/json; to both the fetchArgs object and the fetchArgs.header object
  9. And many other things, can't think of them all right now

There aren't that many questions related to this on SO. These are the ones I've been trying things from:

Google Calendar REST API errors

Google Calendar.Insert API returning 400 'required'

Here is my original question in which I was trying to do this for another calendar on my Google Apps domain, but since I wasn't able to get that to work, I decided to create this question to remove the domain-wide delegation issue from the equation and just focus on the API call.

Also, one more thing worth mentioning: I am able to successfully create the calendars using the APIs Explorer on the Google Calendar API Calendars: insert documentation page.

It shows me that the request was this:

POST https://www.googleapis.com/calendar/v3/calendars
{
 "summary": "test calendar title"
}

And the response was this:

200 OK
- HIDE HEADERS -
cache-control:  no-cache, no-store, max-age=0, must-revalidate
content-encoding:  gzip
content-length:  193
content-type:  application/json; charset=UTF-8
date:  Sat, 22 Aug 2015 14:34:05 GMT
etag:  "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
expires:  Fri, 01 Jan 1990 00:00:00 GMT
pragma:  no-cache
server:  GSE
vary:  Origin, X-Origin
{

 "kind": "calendar#calendar",
 "etag": "\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"",
 "id": "[email protected]",
 "summary": "test calendar title"
}

Any ideas?

Update with the working code based on luc's answer below:

The resource needs to be stringified (the Google Apps Script debugger was showing that it is an object, not a string).

var calendarResource = {
       "summary": "test calendar title"
      };

var fetchArgs = {};
fetchArgs.headers = {'Authorization': 'Bearer '+ calendarOauth2Service.getAccessToken() };
fetchArgs.method = "POST";
fetchArgs.payload = JSON.stringify(calendarResource);
fetchArgs.muteHttpExceptions = true;

var url = 'https://www.googleapis.com/calendar/v3/calendars';

var response = UrlFetchApp.fetch(url, fetchArgs);
like image 421
Employee Avatar asked Jun 04 '26 15:06

Employee


1 Answers

First of all, I suspect you should be setting the payload, not data. Second of all the passed in object won't be interpreted as JSON unless you tell it to (JSON.stringify(calendarResource)).


For users working with JavaScript in a Browser environment:

When debugging you should try printing the request that ends up sent (or look at it in the browser through the developer tools) and compare it to the one from the explorer.

Also using the JavaScript client library could save you some troubles. Have you seen this tutorial? https://developers.google.com/google-apps/calendar/quickstart/js

like image 136
luc Avatar answered Jun 07 '26 22:06

luc