Search code examples
google-apps-scripturlfetchwatson-discovery

Post JSON object to Watson Discovery from Google App Scripts


I'm trying to take my google calendar and post each day as a document to watson discovery through google scripts. My code looks like this.

    var headers={
            "User-Agent": "CreateCalendarListJson",
            "Authorization": "Basic " + Utilities.base64Encode( authdata.username+":"+authdata.password)
        };
        //headers.contentType="application/json";
        var parms={"headers":headers};
        url=newurl+"/v1/environments/"+discoveryData.environmentID+
          "/collections/"+discoveryData.collection_ID+"/documents/?version=2017-09-01";
        parms.method="POST";
        parms.file={
          'value':JSON.stringify(jsonEvent),
          'options':{
            'filename':jsonEvent.filename,
            'contentType':"application/json"
          }
        }
        console.info('discovery add document %s',JSON.stringify(parms));
        response=UrlFetchApp.fetch(url,parms);

However this gets an error 415 unsupported media type. Though application/json is a supported type and I've set contentType accordingly. Any suggestions?

The parms variable looks like this when UrlFetchApp.Fetch is run:

{"headers":
     {"User-Agent":"CreateCalendarListJson",
      "Authorization":"Basic ZTIyNTEwM............................tHcg=="},
      "method":"POST",
      "file":{"value":"{\"title\":\"Events 10/13/2017\",\"filename\":\"Events_10_13_2017\",\"text\":[{\"date\":\"10/13/2017\",\"summary\":\"assignment 1\"}]}",
      "options":{"filename":"Events_10_13_2017",
       "contentType":"application/json"}}}"   

Solution

  • The problem is that documents to Watson Discovery must be passed as a multipart/form-data type. The following function will write a json text (store in jsonEvent.text) as a discovery document. Put the api endpoint in the 'newurl' and store discovery username and password in 'authdata' (json object), give the filename for the discovery document in 'filename'

    function sendtodiscovery(url, jsonEvent, filename,authdata){
       var headers={
            "User-Agent": "CreateCalendarListJson",
            "Authorization": "Basic " + Utilities.base64Encode( authdata.username+":"+authdata.password)
        };
        var parms={"headers":headers};
        var boundary="xxxxxxxx";  
        parms.method="POST";
        var data="--"+boundary+"\r\n"
        data += "Content-Disposition: form-data; name=\"file\"; filename=\""+filename+"\"\r\n";
        data += "Content-Type: application/json\r\n\r\n";
        console.info("data=%s",data);
        console.info("event=%s",JSON.stringify(jsonEvent));
        var payload=Utilities.newBlob(data).getBytes()
        .concat(Utilities.newBlob(JSON.stringify(jsonEvent)).getBytes())
        .concat(Utilities.newBlob("\r\n--"+boundary+"--\r\n\r\n").getBytes());
    
        parms.contentType="multipart/form-data; boundary="+boundary;
        parms.payload=payload;
        //parms.muteHttpExceptions=true;
        console.info('discovery add document %s',JSON.stringify(parms));
        return UrlFetchApp.fetch(url,parms);
     }