Why is fetch not working propely using Google Apps Script? - javascript

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)

Related

Spotify API returning data with Javascript/ React

I'm currently trying to incorporate Spotify's API into my project but I'm having problems fetching the data.
My token is returned in the console which is great but my call to return some data doesn't work.
I'm getting an error :
error:
message: "Only valid bearer authentication supported"
status: 400
[[Prototype]]: Object
[[Prototype]]: Object
Here's what I have so far. Maybe its a simple fix.
// Token
const CLIENT_ID = 'HIDDEN';
const CLIENT_SECRET = 'HIDDEN';
let authParameters = {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'grant_type=client_credentials&client_id=' + CLIENT_ID + '&client_secret=' + CLIENT_SECRET
}
async function getToken() {
let myToken = await fetch('https://accounts.spotify.com/api/token', authParameters)
let tokenReturn = await myToken.json()
console.log(tokenReturn.access_token)
}
// Request
async function searchData() {
const baseUrl = 'https://api.spotify.com/v1/browse/new-releases';
let ArtistParameters = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + tokenReturn
},
}
let artistID = await fetch(baseUrl, ArtistParameters)
let artistList = await artistID.json()
console.log(artistList);
}
useEffect(() => {
getToken()
searchData()
}, [])

Error when using multiple fetch requests in Zapier

I tried to find a solution online and on stackoverflow but i think the answers from the other posts focus on other things.
My problem is the error when i try to fetch more then 1 Hubspot api call.
The error message:
body used already for: https://api.hubapi.com/crm/v3/objects/deals?limit=100&archived=false
(returns list of deals)
var data = [];
let Timestamp = new Date().toISOString();
let Webhook = inputData.Webhook.trim();
let Method = inputData.Method.trim();
let JSONObject = {}
let Options = {
method: Method,
headers: {
'Authorization': `Bearer Hidden Key`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(JSONObject)
}
const Request = await fetch(Webhook, Options); // HTTP POST Request
const Response = await Request.json() // HTTP POST Response
data.push(Response);
Response.push(await Request.json());
let Webhook2 = Response.paging.next.link;
if ('paging' in Response) {
for (let i = 0; i < 10; i++) {
if (Webhook2 != "") {
let Options2 = {
method: Method,
headers: {
'Authorization': `Bearer Hidden Key`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(JSONObject)
}
const Request2 = await fetch(Webhook2, Options2); // HTTP POST
const Response2 = await Request2.json();
data.push(Response2);
if ('paging' in Response2) {
let Webhook2 = Response2.paging.next.link;
} else {
let Webhook2 = "";
}
}
}
}
output = data;
If someone could help me with this error i would really appriciate it.
Thanks in advance people.

Query for Spotify's Web API Client Credentials Flow

I'm trying to make a http request based on the documentation at https://developer.spotify.com/documentation/general/guides/authorization-guide/#client-credentials-flow Client Credentials Flow.
I've written
const BASE_URL = 'https://accounts.spotify.com/api/token';
fetch(BASE_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + base64(clientID) + ':' + base64(clientSecret)
},
body: JSON.stringify({'grant_type:client_credentials'})
})
Does this follow what it says to do? I'm confused how to write the body of the post request.
What I ended up doing which works:
async authorize(){
let myHeaders = new Headers();
myHeaders.append("Authorization", `Basic ${my_clientID:clientSecret}`);
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("grant_type", "client_credentials");
const requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
}
let res = await fetch("https://accounts.spotify.com/api/token", requestOptions);
res = await res.json();
return res.access_token;
}
async search(){
const access_token = await this.authorize();
this.setState({access_token});
const BASE_URL = 'https://api.spotify.com/v1/search';
let FETCH_URL = `${BASE_URL}?q=${this.state.query}&type=artist&limit=1`;
const ALBUM_URL = 'https://api.spotify.com/v1/artists';
let myHeaders = new Headers();
myHeaders.append("Authorization", `Bearer ${access_token}`);
const requestOptions = {
method: 'GET',
headers: myHeaders
}
let res = await fetch(FETCH_URL, requestOptions);
res = await res.json();
console.log("ARTIST", res);
}
From the link you have shared, the client credential flow is a client (server-side) that makes a request to the spotify API server. Thus, it is a server-to-server authentication flow (not authorization). You are using the fecth API which is client-side so that means that your implementation should be server-side. If you are using a node.js runtime server-side framework, just look up the http.request API to make a request server-side.
For example, this would be a pure node.js implementation:
const options = {
hostname: 'https://accounts.spotify.com/api/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + base64(clientID) + ':' + base64(clientSecret)
}
};
const req = http.request(options, (res) => {
res.setEncoding('utf8');
// process the data bit by bit or in chunks...
res.on('data', (chunk) => {});
// ...and do something with it when there is no more data in response
res.on('end', () => {
console.log('No more data in response.');
});
});
// handle the error explicitly
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
req.end();
For me, I'm not sure if this is the case for anyone else, but the spotify api was refusing base64(clientID) + ":" + base64(clientKey), but accepting base64(clientID + ":" + clientKey)

FormData in React Native throws blank object

In my React Native project i'm using react-native-image-picker for image upload. Here, i am using formData to upload image. Image URL is there, but when i console the formData it shows {}. I don't know why this is happening. Here's the code :
uploadImageAsync = async (imgUri, token) => {
let apiUrl = 'url';
let formData = new FormData();
let uriParts = imgUri.split('.');
let fileType = uriParts[uriParts.length - 1];
//generate some random number for the filename
var randNumber1 = Math.floor(Math.random() * 100);
var randNumber2 = Math.floor(Math.random() * 100);
formData.append('image', {
uri: imgUri,
name: `photo-${randNumber1}-${randNumber2}.${fileType}`,
type: `image/${fileType}`,
});
console.log('formData :', formData);
let options = {
method: 'POST',
body: formData,
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + token,
'Content-Type': 'multipart/form-data',
'Cache-Control': 'no-cache',
},
};
const response = await fetch(apiUrl, options);
const json = await response.json();
}
};
Console of formData shows no data but imgUri consists image path. Why formData is showing no data?
The value property of FormData.append() can be either a USVString or a Blob.
Therefore, you can try stringifying your object and then optionally parse the string data.
const imageData = {
uri: imgUri,
name: `photo-${randNumber1}-${randNumber2}.${fileType}`,
type: `image/${fileType}`,
};
const formData = new FormData();
formData.append("image", JSON.stringify(imageData));
const formImageData = formData.get("image");
const parsedFormImageData = JSON.parse(formImageData);
console.log(parsedFormImageData );

nodejs https request throws error when using Content-Type

The following code is with the Dropbox API, it worked during testing but when I added the "Content-Type":"application/json" in the parameters it broke.
https.request(options, function(resp){
let creds = [];
let ts = "";
resp.on('data', function(body){
creds.push(body);
let jsonarray = Array.prototype.slice.call(creds, 0).toString().split(",");
let token = "Bearer " + jsonarray[0].substring(jsonarray[0].indexOf(':') + 3, jsonarray[0].length - 1);
ts = token;
});
resp.on('end', function(){
let connectfilelist = {
hostname: 'api.dropboxapi.com',
path: '/2/files/list_folder',
method: 'POST',
headers: {Authorization: ts,
"Content-Type", "application/json"}
};
https.request(connectfilelist, function(resp){
let flist = [];
resp.on('data', function(chunk){
flist.push(chunk.toString());
});
resp.on('end', function(){
console.log(flist);
res.render('mydropbox', flist);
});
}).end(bodyParams);
});
}).end(bodyParams);
This is the error I get when i omit that parameter:
[ 'Error in call to API function "files/list_folder": This function requires its argument in the HTTP request body, but your request body is empty.' ]
When I include the Content-Type, it throws this:
[ 'Error in call to API function "files/list_folder": request body: could not decode input as JSON' ]
I think that the way I am stating the parameters might be in a string and not JSON format, but I am not sure where I would change something.

Categories