Add to iAuditor Response Set (Invalid request payload JSON format) - javascript

Using https://developer.safetyculture.io/?shell#add-a-response
I have the following:
function addResponse(){
var url = 'https://api.safetyculture.io/response_sets/responseset_id/responses';
var myBody = {"label": "String To Add"};
var headers = {"Authorization" : 'Bearer ' + 'api_key'};
var params = {
'method': 'POST',
//'muteHttpExceptions': true,
'headers': headers,
'contentType': 'application/json',
'payload': myBody
};
UrlFetchApp.fetch(url, params);
}
I am able to get the responseset (https://developer.safetyculture.io/?shell#get-a-global-response-set) so I know the URL, Responseset_ID and key are correct.
Bad Request","message":"Invalid request payload JSON format"
How should I be correctly formatting myBody?

Related

nodejs - AxiosError: Request failed with status code 500

I am trying to convert the below code which is using request module to axios module to send the POST request.
request module code:
const imageFile = fs.createReadStream('image.jpeg');
const imgName = "image" + ".jpeg";
var options = {
'method': 'POST',
'url': url,
'headers': {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'Accept': 'application/json'
},
formData: {
'image': {
'value': imageFile,
'options': {
'filename': imgName,
'contentType': null
}
}
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log("SUCCESS");
});
The above code works fine and the image is posted successfully with the request module. But when I convert the same to axios, I am getting a 500 Error. (AxiosError: Request failed with status code 500)
axios module code:
const FormData = require('form-data')
const imageFile = fs.createReadStream('image.jpeg');
const imgName = "image" + ".jpeg";
const bodyFormData = new FormData();
bodyFormData.append("image['value']", imageFile);
bodyFormData.append("image['options']['filename']", imgName)
// bodyFormData.append("image['options']['contentType']", null)
console.log(bodyFormData)
const formHeaders = bodyFormData.getHeaders();
axios.post(url, bodyFormData, {
headers: {
...formHeaders,
'Cache-Control': 'no-cache',
'Accept': 'application/json',
}
}).then(function (response) {
console.log('SUCCESS');
}).catch(function (error) {
throw new Error(error);
});
Can anyone find out what I am doing wrong here?
Is there any other way to post the image using axios other than using form-data?
See the documentation for FormData#append(). You can provide extra data like the file name as the 3rd options parameter
const bodyFormData = new FormData();
// Pass filename as a string
bodyFormData.append("image", imageFile, imgName);
// or to specify more meta-data, pass an object
bodyFormData.append("image", imageFile, {
filename: imgName,
contentType: "image/jpeg",
});
axios.post(url, bodyFormData, {
headers: {
Accept: "application/json",
"Cache-Control": "no-cache",
...bodyFormData.getHeaders(),
},
});
Under the hood, request() does something very similar with the exact same form-data library. See request.js

Request for JavaScript works, but not for GoogleScreen. What's the difference?

Please, help. I can't find the error and I don't understand why the request is not working. It seems to me that it's just Google's IP blocked by the site I'm making a request to. The same request for JavaScript works.
function pleaseWork() {
var myHeaders = {
'contentType': 'application/json',
'Authorization': 'Bearer 5cd4ac65-f71b-3eaa-93af-78610a7aa320',
}
var raw = ["1111111111111"]
var requestOptions = {
'method': 'POST',
'headers': myHeaders,
'payload': JSON.stringify(raw)
};
result = UrlFetchApp.fetch("https://www.ukrposhta.ua/status-tracking/0.0.1/statuses/last", requestOptions)
Logger.log(result)
}
Working Javascript request:
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer 5cd4ac65-f71b-3eaa-93af-78610a7aa320");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify([
"1111111111111"
]);
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
};
fetch("https://www.ukrposhta.ua/status-tracking/0.0.1/statuses/last", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
How to do it right?
In your Google Apps Script, the data is sent as form by default. When I saw your Javascript, it seems that the data is required to be sent as data with application/json. So you'll need to modify the script as follows.
From:
var requestOptions = {
'method': 'POST',
'headers': myHeaders,
'payload': JSON.stringify(raw)
};
To:
var requestOptions = {
'method': 'POST',
'headers': myHeaders,
'payload': JSON.stringify(raw),
'contentType': 'application/json',
};
Reference:
fetch(url, params)
Note:
I think that this modification is the same as the request of your Javascript. But, if an error occurs, please confirm your values of raw and your access token, again.
Added 1:
Your showing script was modified for testing. Please set your access token and the value of raw and test it again.
function modified_pleaseWork() {
var myHeaders = { 'Authorization': 'Bearer ###' };
var raw = ["1111111111111"];
var requestOptions = {
'method': 'POST',
'headers': myHeaders,
'payload': JSON.stringify(raw),
'contentType': 'application/json',
};
var result = UrlFetchApp.fetch("https://www.ukrposhta.ua/status-tracking/0.0.1/statuses/last", requestOptions);
Logger.log(result.getContentText())
}
Added 2:
From your following reply,
but the solution doesn't work for me. I saw you added a modified script. You can also test it with the parameter "Bearer ###" Error 403. But it is not in the JavaScript code. I don't understand what's wrong?
I confirmed the status code 403 from your reply. In this case, it is considered that the site cannot be directly accessed from the Google side. Ref I think that the reason for your issue is due to this.
But, in the case of this situation, there is a workaround. Here, I would like to propose using this workaround. Ref
Sample script:
In this case, the request is run on the custom function. By this, I thought that the status code 403 might be able to be avoided. Actually, when I tested this script using your provided access token, the result value could be obtained.
In this script, the custom function is used. So, please copy and paste the following script to the container-bound script of Google Spreadsheet. And run main(). By this, the request is run on the custom function. And, the returned value can be retrieved with the script.
function modified_pleaseWork() {
var myHeaders = { 'Authorization': 'Bearer 5cd4ac65-f71b-3eaa-93af-78610a7aa320' };
var raw = ["1111111111111"];
var requestOptions = {
'method': 'POST',
'headers': myHeaders,
'payload': JSON.stringify(raw),
'contentType': 'application/json',
};
var result = UrlFetchApp.fetch("https://www.ukrposhta.ua/status-tracking/0.0.1/statuses/last", requestOptions);
return result.getContentText();
}
// Please run this function.
function main() {
const sheet = SpreadsheetApp.getActiveSheet();
const range = sheet.getRange("A1");
range.setFormula("=modified_pleaseWork()");
SpreadsheetApp.flush();
const value = range.getValue();
range.clearContent();
console.log(value)
}

Why is fetch not working propely using Google Apps Script?

I've been trying to modify an item related value using a store's API and although it returns success, the raw object is not bring the values correctly and I can't find out why.
The Script Editor logs show:
Raw data: {"tipo":3,"quantidade":10} ...which is correct.
The response I get is: "code":"010","message":"success","responseCode":200,
The destination log shows:
{"erp_id":"","peso":"","gtin":"","ativo":"","tipo":"","quantidade":"", ...where tipo and quantidade are empty - thus, incorrect.
Here's the piece of code I'm working on:
function addToStock() {
try {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('Estoque PA');
const id = sheet.getRange(2, 3).getValue();
let quantidade = sheet.getRange(2, 5).getValue();
const variacao = sheet.getRange(2, 6).getValue();
const raw = JSON.stringify({
'tipo': 3,
'quantidade': quantidade
});
const headers = {
'Content-Type': 'application/json',
'Authorization': "Bearer " + API_KEY
};
const requestOptions = {
"method": 'PUT',
"headers": headers,
"body": raw,
"redirect": 'follow'
};
Logger.log('Raw data: ' + raw)
const url = `https://api.wwwww.com.br/v1/product/stock/${id}/${variacao}`;
Logger.log('URL: ' + url)
const response = UrlFetchApp.fetch(url, requestOptions);
const getText = response.getContentText();
Logger.log('GetText: ' + getText);
} catch (err) {
Logger.log('Error: ' + err)
}
}
Any idea as to why raw data is not going through all the way?
Thank you!
In the UrlFetchApp options, the request body is indicated by payload rather than body:
const requestOptions = {
"method": 'PUT',
"headers": headers,
"payload": raw, // change this line
'followRedirects': true // and this one
};
Reference: https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object)

"Failed: There was an error while trying to create this media item."

I'm trying to upload a photo on Google Photos, with google api, but i always get this error:
"status":{"code":3,"message":"Failed: There was an error while trying to create this media item."}}
I think that the problem is in the way i take the binary data of photo.
In this code i follow google photo api developers documentation, and it says, after take authorization, to:
1- Upload the raw bytes to a Google Server: to take upload-token
2- Use the upload token to create the media item.
This my node js code:
const photo = fs.readFileSync("fbimages/"+req.session.id_client+"/Prague/2020-05-30T17:29:14+0000_0.png", {
'encoding': 'binary',
'flag' : 'r'
});
var url= 'https://photoslibrary.googleapis.com/v1/uploads';
var headers= {
'Authorization': 'Bearer '+token,
'Content-type': 'application/octet-stream',
'X-Goog-Upload-Content-Type': 'image/png',
'X-Goog-Upload-Protocol': 'raw',
'X-Goog-Upload-File-Name': "2020-05-30T17:29:14+0000_0.png",
};
var body= photo
request({
url: url,
method:'POST',
headers: headers,
rejectUnauthorized: false,
body: JSON.stringify(body)
}, function(error, response, body1){
if(error)
{
console.log(error);
}
else
{
var upToken = body1.toString();
console.log(upToken);
var url= 'https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate';
var headers= {
'Authorization' : 'Bearer '+token,
'Content-type': 'application/json',
};
var body= {
'newMediaItems': [
{
'description': 'Prague',
'simpleMediaItem': {
'fileName': 'prova',
'uploadToken': upToken,
}
}
]
};
request({
url: url,
method: 'POST',
headers: headers,
rejectUnauthorized: false,
body: JSON.stringify(body),
}, function(error, response, body){
if(error)
{
console.log(error);
}
else
{
res.send(JSON.parse(body));
}
});
}});
Please help me, if anyone has any idea!!
How about this modification?
Modification points:
I think that encoding: "binary" is not required.
In this case, ``const photo = fs.readFileSync("fig1.png", { flag: "r" });andconst photo = fs.readFileSync("fig1.png");` can be used.
Please modify body: JSON.stringify(body) to photo of const photo = fs.readFileSync("fig1.png", { flag: "r" });.
When above points are reflected to your script, it becomes as follows.
Modified script:
From:
const photo = fs.readFileSync("fbimages/"+req.session.id_client+"/Prague/2020-05-30T17:29:14+0000_0.png", {
'encoding': 'binary',
'flag' : 'r'
});
var url= 'https://photoslibrary.googleapis.com/v1/uploads';
var headers= {
'Authorization': 'Bearer '+token,
'Content-type': 'application/octet-stream',
'X-Goog-Upload-Content-Type': 'image/png',
'X-Goog-Upload-Protocol': 'raw',
'X-Goog-Upload-File-Name': "2020-05-30T17:29:14+0000_0.png",
};
var body= { 'media-binary-data': photo }
request({
url: url,
method:'POST',
headers: headers,
rejectUnauthorized: false,
body: JSON.stringify(body)
}, function(error, response, body1){
To:
const photo = fs.readFileSync("fbimages/"+req.session.id_client+"/Prague/2020-05-30T17:29:14+0000_0.png", { flag: "r" });
var url = "https://photoslibrary.googleapis.com/v1/uploads";
var headers = {
Authorization: "Bearer " + token,
"Content-type": "application/octet-stream",
"X-Goog-Upload-Content-Type": "image/png",
"X-Goog-Upload-Protocol": "raw",
"X-Goog-Upload-File-Name": "2020-05-30T17:29:14+0000_0.png",
};
request(
{
url: url,
method: "POST",
headers: headers,
rejectUnauthorized: false,
body: photo,
},
function (error, response, body1) {
Note:
In this modification, it supposes that your token can be used for this API. Please be careful this.
When you want to directly put the uploaded image to an alubmn, please include albumId for requesting to https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate.
Reference:
Upload media

I am trying to do a GET/POST request and defined the options variable twice. The second definition overrides the first

I am trying to do a GET/POST request and defined the options variable twice. The second definition overrides the first, and my authorization token is only in the first.
Therefore when I make the request, I’m not passing the authorization token, which causes the "Login Required" error.
How do I fix this?
function DBMdownload() {
var url = "https://www.googleapis.com/doubleclickbidmanager/v1/query/000000000";
var options = {
'method': 'get',
'headers': {'Authorization': ('Bearer ' + ScriptApp.getOAuthToken())}
};
var options = {
'method' : 'post',
'contentType' : 'application/json',
};
var response = UrlFetchApp.fetch(url, options);
var responseData = JSON.parse(response.getContentText());
}
UPDATE
function DBMdownload() {
var url = "https://www.googleapis.com/doubleclickbidmanager/v1/query/608174710";
var options = {
'method': 'get',
'headers': {'Authorization': ('Bearer ' + ScriptApp.getOAuthToken())}
};
var response = UrlFetchApp.fetch(url, options);
function DBMdownload2() {
var options2 = {
'method' : 'post',
'contentType' : 'application/json',
};
var response2 = UrlFetchApp.fetch(url, options);
var responseData = JSON.parse(response2.getContentText());
}
}
Bryan,
Your current approach is overriding the options object, that's why your call is not sending the token.
You can either split these functions to have a get and a post function sending the URL and other properties as parameters or remove the first declaration of the options object and add the headers to the last one.

Categories