400 Parser error with Google API POST call - json

I am trying to make POST call towards Search Console API. I got my example running under API Explorer, however when I try to make the same call from my meteor project, I am getting error:
Object {error: Object} error: Object code: 400 errors: Array[1]
message: "Parse Error"
My code:
function fetchSEOForWebsite(website) {
var call = 'webmasters/v3/sites/' + 'mdbootstrap.com' + '/searchAnalytics/query'
var params = {
"searchType": "web",
"dimensions": [
"query",
"date",
"page"
],
"startDate": "2016-02-06",
"endDate": "2016-02-08"
}
GoogleApi.post(call, {
params: params
}, function(error, answer) {
console.log(answer);
});
}
From Chrome console I can see POST payload:
searchType=web&dimensions=query%2Cdate%2Cpage&startDate=2016-02-06&endDate=2016-02-08
The same query works perfectly fine from API Explorer :
POST https://www.googleapis.com/webmasters/v3/sites/http%3A%2F%2Fmdbootstrap.com/searchAnalytics/query?key={YOUR_API_KEY}
{
"searchType": "web",
"dimensions": [
"query",
"date",
"page"
],
"startDate": "2016-02-06",
"endDate": "2016-02-08"
}
What am I doing wrong?
I am using Meteor Google Api
https://github.com/percolatestudio/meteor-google-api
UPDATE:
I also checked paylod sent via API Explorer and it's different:
{ "searchType": "web", "dimensions": ["query","date","page"
], "startDate": "2016-02-06", "endDate": "2016-02-08" }
So it looks like for some reason my params are not passed as a JSON object to call...

From percolate:google-api package Readme
GoogleApi is a Google OAuth authentication wrapper around HTTP, so it
takes the same arguments. For example, to pass a JSON body in
GoogleApi.post, use:
GoogleApi.post('/your/api/path', { data: jsonBody });
So I would try with data: instead of params:

Related

Migrating webRequest to declarativeNetRequest

Hi I was using webRequest in manifest V2 , I started getting below error
'webRequestBlocking' requires manifest version of 2 or lower.
So I am trying to convert my below existing code to declarativenetrequest
var responseListener = function (details) {
var rule = {
name: "Access-Control-Allow-Origin",
value: "*",
};
details.responseHeaders.push(rule);
var rule1 = {
name: "Access-Control-Allow-Methods",
value: "GET, PUT, POST, DELETE, HEAD, OPTIONS",
};
details.responseHeaders.push(rule1);
return { responseHeaders: details.responseHeaders };
};
chrome.webRequest.onHeadersReceived.addListener(
responseListener,
{
urls: [
"https://example.com/*",
"*://*.example1.com?test",
],
},
// extraInfoSpec
["blocking", "responseHeaders", "extraHeaders"]
);
So i tried replacing to chrome.declarativeNetRequest.onHeadersReceived.addListener(
And I got Uncaught TypeError: Cannot read properties of undefined (reading 'addListener').Can some one help me how the current function can be migrated to declarativeNetRequest.
The error you're seeing is because declarativeNetRequest provides a different API to webRequest and there are some additional steps for migration. You can learn more about the API in general here: https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest/
For your use case, you can actually setup a rule declaratively in the manifest without needing to call any APIs at all! This is one of the benefits of the new API in general, which tries to move towards declarative rules rather than giving extensions access to web requests in-flight.
To start with, add the following to your extension manifest:
Copyright 2023 Google LLC.
SPDX-License-Identifier: Apache-2.0
"declarative_net_request" : {
"rule_resources" : [{
"id": "ruleset_1",
"enabled": true,
"path": "rules_1.json"
}]
},
"permissions": [
"declarativeNetRequest"
],
"host_permissions": [
"https://example.com/*"
]
This defines a new "ruleset" and also adds the required API and host permissions.
You can then create the file rules_1.json and put the desired rule inside:
Copyright 2023 Google LLC.
SPDX-License-Identifier: Apache-2.0
[
{
"id" : 1,
"priority": 1,
"action": {
"type": "modifyHeaders",
"responseHeaders": [
{ "header": "Access-Control-Allow-Origin", "operation": "set", "value": "*" },
{ "header": "Access-Control-Allow-Methods", "operation": "set", "value": "GET, PUT, POST, DELETE, HEAD, OPTIONS" }
]
},
"condition" : {
"urlFilter": "||example.com"
}
}
]
This adds the two headers as required. You can then reload your extension and should be good to go!
As a note, you won't see these headers reflected in Dev Tools. This is a bug which will hopefully be fixed in the future: https://bugs.chromium.org/p/chromium/issues/detail?id=1247400
If you want to check it's working, going to https://example.com and running the following in the console will output a list of headers, including the ones added by your extension: [...(await fetch("https://example.com")).headers].

How do you pass parameters to a Deployed Google Apps Script API function?

I created a test function (doPost) in a Google Apps Script API using Google Cloud Platform (GCP). I am now trying to call that function from another script in the same project.
I know I am almost there, because this code works:
var token = ScriptApp.getOAuthToken();
var header = {
"Authorization": "Bearer " + token,
"function": "doPost",
"devMode": true,
};
var options = {
"method": "POST",
"headers": header,
"muteHttpExceptions": true,
"payload": {
"function": "doPost",
"devMode": true
}
};
var url = 'https://script.googleapis.com/v1/scripts/xxxxxxxxxxxxxxxxxxxx:run';
var response = UrlFetchApp.fetch(url, options);
However, when I try to include a parameter in payload above, it no longer works:
"payload": {
"function": "doPost",
"parameters": ['1'],
"devMode": true
}
Following other stackoverflow answers, I've tried using in the header:
"contentType": 'application/json',
And accordingly, for the payload:
"payload": JSON.stringify({
"function": "doPost",
"parameters": ['1'],
"devMode": true
})
Whenever I use "JSON.stringify", even without parameters (just like the situation I got to work), it errors out.
With JSON.stringify (and parameters in the payload), I get a worse error, which seems to say it doesn't like any of the payload:
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"{\"function\":\"doPost\",\"parameters\":[1007],\"devMode\":true}\": Cannot bind query parameter. Field '{\"function\":\"doPost\",\"parameters\":[1007],\"devMode\":true}' could not be found in request message.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"{\"function\":\"doPost\",\"parameters\":[1007],\"devMode\":true}\": Cannot bind query parameter. Field '{\"function\":\"doPost\",\"parameters\":[1007],\"devMode\":true}' could not be found in request message."
Without JSON.stringify (and with parameters in the payload), I get the error:
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"parameters\": Cannot bind query parameter. 'parameters' is a message type. Parameters can only be bound to primitive types.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"parameters\": Cannot bind query parameter. 'parameters' is a message type. Parameters can only be bound to primitive types."
Finally, it doesn't matter what I do with parameters. I'm pretty sure it should be in the format I put above, but I've also tried:
"parameters": [1]
"parameters": 1
"parameters": "1"
among others.
The doPost script is simple for now:
function doPost(parameters) {
Logger.log('parameters = ' + parameters);
return "Hello";
}
Here is the stackoverflow question that seems to be most like this: Apps Script API returning 404 error for existing project. Error returned as HTML rather than JSON, but doesn't seem to answer my problem.
I've studied the scripts.run page about parameters: https://developers.google.com/apps-script/api/reference/rest/v1/scripts/run#authorization-scopes, along with many other pages, including the URL Fetch Service: https://developers.google.com/apps-script/reference/url-fetch.
This is certainly not my first time using UrlFetchApp in Google Apps Script, but it is when calling my own GAS API.
Any help would be greatly appreciated!
Thanks!
Not long after I posted this, and after continuing to see post after post say that you should use JSON.stringify for the payload and contentType: application/json in the header, in the header I changed:
"contentType": "application/json"
to
"Content-Type": "application/json"
and it works now!

"errorCode":"UNSPECIFIED_ERROR","message":"Non-static method requires a target."

I am trying to create an envelope using E-signature post API from AppScript. I am able to Authenticate and call other Get API's like Status of Envelope and List of all envelopes successfully. But for this Post API I am facing below error.
"errorCode":"UNSPECIFIED_ERROR",
"message":"Non-static method requires a target."
here is the object which I am passing
var createEnvelopeObj =
{
"documents": [
{
"documentBase64": "JVBERi0----------DI0NGItMThmMzAtNS41LjEzLVNOQVBTSE9UCnN0YXJ0eHJlZgoxOTY2MDcKJSVFT0YK",
"documentId": "1323457",
"fileExtension": ".pdf",
"name": "sampledoc"
}
],
"emailSubject": "Please sign below Document ref: G654sfd238",
"recipients": {
"signers": [
{
"clientUserId": "xxxx#gmail.com",
"email": "xxxx#dddd.com",
"name": "xxxx",
"recipientId": "124",
"routingOrder": "1"
}
]
},
"status": "sent"
};
Below is the API call with above object
function DocusignPost(createEnvelopeObj){
var options = {
headers: {Authorization: 'Bearer eyJ0eXAiOiJNVCIsImFsZyI6IlJTMjU2Iiwia2lkIjoiNjgxO___xxxxx_VKdnH4FHUtI80s5xtZ9tusnP1DmYw '
},
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify(createEnvelopeObj),
'muteHttpExceptions': true};
try{
var response = UrlFetchApp.fetch("https://demo.docusign.net/restapi/v2.1/accounts/xxxxxxx/envelopes", options );
var postresponce = JSON.parse(response);
Logger.log("postresponce : " + JSON.stringify(postresponce));
return postresponce;}catch(exp){
Logger.log(exp); }}
I have referred both these 57258880, 35047127 but I am using latest Auth method and passing object as payload, but still facing an issue.
Request someone to look into this and shed some light on it. I got stuck here for a couple of days.
I don't see any error in your JSON. So the next step I recommend is to obtain the API trace from DocuSign to see exactly what is being received from DocuSign.
See https://support.docusign.com/en/guides/ndse-user-guide-api-request-logging
You should also carefully check how you're reading in the PDF file before base64 encoding it. PDF files are (almost always) binary, so you need to read them using a binary-clean method.

Posting data in a JSON file in AngularJS - (using django REST here to create that JSON file.)

I am using AngularJS along with Python & Django and Django REST API.
There is a JSON file created by the REST API and I need to post data into it using Angular $http.post().
I need to know if it is possible or not.
Im majorly getting 403(Forbidden) and 400(BAD REQUEST) errors on post..
$http({
method: 'POST',
url: '<JSON FILE URL>',
data: $scope.tmpDataSet,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}});
This is my .post() method. where im fetching the data from a form made in angular and storing it in 'tmpDataSet'. Its being created properly and im able to store into the array.
Im just not able to write it into the JSON file.
The structure of my JSON file is
{
"count": 6,
"next": null,
"previous": null,
"results": [
{
"name": "fff",
"mobile_no": "fff",
"email": "n#gmail.com",
"message": "dfdf",
"id": 1
},
{
"name": "asd",
"mobile_no": "0987654321",
"email": "asd#gmail.com",
"message": "no",
"id": 2
}
]
If any more code detail is needed please comment.
This issue was solved by adding CSRF tokens to the angular app and using the regular $http.post() function with all the parameters.
app.config(function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
});
and,
$http.post('<URL>', item).error(function(data,status,headers,config){
console.log('COULDNT POST!');
}).success(function(data, status, headers, config){
console.log('POSTED!');
});

Generate POSTMAN in webpage with JSON or something

I have a restAPI code from a programmer from JNE, company stands for delivery service.
They say that this API can be run in POSTMAN (Google Chrome Application)
It works fine in the POSTMAN, where in this application I just need to insert the request URL (which I have got from the JNE company) and two header of keys and values as follow;
KEY VALUE
----------------------------------------------
username mycompany
api key 4534645756864234523424
The method for this is POST and when I posted it, it gives me the results as how expected.
My problem now is, how can I run this code in my page, so that I don't need to run this in postman.
I am just this day going to learn JSON if anybody can help me out with this.
[UPDATE QUESTION 1]
{
"version":1,
"collections":
[
{
"id":"c8b12431-8586-cbdd-aef7-056ec177509a",
"name":"asdasdadasdasdasd",
"timestamp":1415593872130,
"requests":
[
{
"collectionId":"c8b12431-8586-cbdd-aef7-056ec177509a",
"id":"d1b2ed66-781d-d02e-c4eb-0416dd3e07a1",
"name":"http://api.jne.co.id:8889/tracing/mycompany/origin/key/jak",
"description":"",
"url":"http://api.jne.co.id:8889/tracing/mycompany/origin/key/jak",
"method":"POST",
"headers":"username: mycompany\napi_key:089a12ffb8cd5009bdfa4ba5bdb9ee26\n",
"data":
[
{
"key":"username",
"value":"mycompany",
"type":"text"
},
{
"key":"api_key",
"value":"dsfsdfsdfs98d98sdfsdf9898dsfs",
"type":"text"
}
],
"dataMode":"params",
"timestamp":0,
"responses":[],
"version":2
}
]
}
],
"environments":[],
"headerPresets":[],
"globals":[]
}
From the update question above; my first question is: ]
In what format I have to save this file: JSON? or WHAT?
Should I save this file in one file with my webpage? or Can I save it as external file?
From the code above, I get the result as follow:
{
"detail": [
{
"code": "CGK10000",
"label": "JAKARTA"
},
{
"code": "CGK10100",
"label": "JAKARTA BARAT"
},
{
"code": "CGK10300",
"label": "JAKARTA PUSAT"
},
{
"code": "CGK10200",
"label": "JAKARTA SELATAN"
},
{
"code": "CGK10500",
"label": "JAKARTA TIMUR"
},
{
"code": "CGK10400",
"label": "JAKARTA UTARA"
}
]
}
If you have a look to the "label" it is generated from the key of the last string in the: "name":"http://api.jne.co.id:8889/tracing/mycompany/origin/key/jak",
The result of the label from the last string of jak, is what I want to insert in a dropdown html tag, in where the user will choose that (the name of the location).
[Update with complete code]
POST /tracing/mycompany/origin/key/jak HTTP/1.1
Host: api.jne.co.id:8889
Content-Type: application/json
username: mycompany
api_key: 089a12ffb8cd5009bdfa4ba5bdb9ee26
{
"version":1,
"collections":
[
{
"id":"c8b12431-8586-cbdd-aef7-056ec177509a",
"name":"asdasdadasdasdasd",
"timestamp":1415593872130,
"requests":
[
{
"collectionId":"c8b12431-8586-cbdd-aef7-056ec177509a",
"id":"d1b2ed66-781d-d02e-c4eb-0416dd3e07a1",
"name":"http://api.jne.co.id:8889/tracing/mycompany/origin/key/jakarta",
"description":"",
"url":"http://api.jne.co.id:8889/tracing/mycompany/origin/key/jakarta",
"method":"POST",
"headers":"username: mycompany\napi_key:089a12ffb8cd5009bdfa4ba5bdb9ee26\n",
"data":
[
{
"key":"username",
"value":"mycompany",
"type":"text"
},
{
"key":"api_key",
"value":"089a12ffb8cd5009bdfa4ba5bdb9ee26",
"type":"text"
}
],
"dataMode":"params",
"timestamp":0,
"responses":[],
"version":2
}
]
}
],
"environments":[],
"headerPresets":[],
"globals":[]
}
I have saved this file as jne.json and jne.html but the browser just show the full code insted show the result as how the postman does. I think there are many things I am missing here.
The POST request would look something like the following
POST /tracing/mycompany/origin/key/jak HTTP/1.1
Host: api.jne.co.id:8889
Content-Type: application/json
username: mycompany
api_key: 089a12ffb8cd5009bdfa4ba5bdb9ee26
{
... your JSON ...
}
You can save JSON with the .json file extension. If your request is always the same you can save this file with your webpage, but normally an HTTP request is constructed before sending (that means you normally send different requests).
To fill the dropdown list you just have to parse the JSON response.