Question

I'm trying to POST to a web service that is expecting to get JSON as payload using Google Apps Script. I'm using the following code:

var options =
{
  "method" : "post",
  "contentType" : "application/json",
  "headers" : {
    "Authorization" : "Basic <Base64 of user:password>"  
  },
  "payload" : { "endDate": "2012-06-03" }
};

var response = UrlFetchApp.fetch("http://www.example.com/service/expecting/json", options);

On the server side I'm getting the following error:

WARN [facade.SettingsServlet] 04 Jun 2012 15:30:26 - Unable to parse request body: endDate=2012-06-03
net.liftweb.json.JsonParser$ParseException: unknown token e

I'm assuming that the server is expecting to get

{ "endDate": "2012-06-03" }

instead of

endDate=2012-06-03

but I don't know how to make the UrlFetchApp do it.

Was it helpful?

Solution

I do not understand the server side error but the 'payload' parameter must be a string as specified here: https://developers.google.com/apps-script/class_urlfetchapp?hl=fr-FR#fetch.

try:

var options =
{
  "method" : "post",
  "contentType" : "application/json",
  "headers" : {
    "Authorization" : "Basic <Base64 of user:password>"  
  },
  "payload" : '{ "endDate": "2012-06-03" }'
};

OTHER TIPS

  • If you set payload as a String, it will be passed directly (as a UTF-8 string).
  • If you set payload as an Object, it will be sent like an HTML form (which means either 'application/x-www-form-urlencoded' if the fields are simple, or 'multipart/form-data' if the Object includes a blob/file).

For your use case (the server is expecting to receive JSON), it sounds like Utilities.jsonStringify() is the way to go.

Something like this worked for me in a similar situation:

Instead of creating payload and adding to options, I built the parameters into a string to append to the URL:

var params = "id=2179853&price=62755";

then, I appended params to the url string:

var result = UrlFetchApp.getRequest(url + '?' + params, options);

So, my options was passed containing only the header.

For my project, this worked like a charm.

Here goes the code that should work with some important comments:

function testMe() {
    var products_authkey = "------------";
    try {
        var url = "https://app.ecwid.com/api/v1/---------/product?id=----------&secure_auth_key=" + products_authkey;
        //url= "http://requestb.in/----------"; // you can actually debug what you send out with PUTs or POSTs using Requestb.in service
        var payload = {
            id: "21798583", // id is necessary and should be a string, or it might be sent in scientific representation (with E)
            price: 62755
        }; 

        payload = JSON.stringify(payload); // the payload needs to be sent as a string, so we need this
        var options = {
            method: "put",
            contentType: "application/json", // contentType property was mistyped as ContentType - case matters
            payload: payload
        }; 
        var result = UrlFetchApp.getRequest(url, options);
        Logger.log(result) // a better way to debug
        var result = UrlFetchApp.fetch(url, options); // works perfectly in my case
        Logger.log(result)
    } catch (e) {
        Logger.log(e)
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top