问题
I managed to do the API POST request through Postman but once modified for Google App Script it doesn't work. I think it might be related to the body
format, I can't replicate the new URLSearchParams()
object in GAS (I'm sending a JSON I believe).
Thanks.
Postman (working) - JavaScript Fetch
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("client_id", "XXXX");
urlencoded.append("client_secret", "XXXX");
urlencoded.append("grant_type", "client_credentials");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
};
fetch("https://apigateway.criteo.com/oauth2/token", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
CURL
curl --location --request POST 'https://apigateway.criteo.com/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=XXXX' \
--data-urlencode 'client_secret=XXXX' \
--data-urlencode 'grant_type=client_credentials'
My faulty GAS version :(
function getCostAU() {
var myHeaders = {"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded"};
var myPayload = {"client_id" : "XXXX",
"client_secret" : "XXXX",
"grant_type" : "client_credentials"};
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: myPayload,
redirect: 'follow',
};
var url = "https://apigateway.criteo.com/oauth2/token";
var result = JSON.parse(UrlFetchApp.fetch(url, requestOptions).getContentText());
var access_token = result.access_token;
};
回答1:
Issues:
body
is not a valid key in options argument. You should usepayload
instead.redirect
is not a valid key inoptions
argumentCurrently, URLSearchParams is not supported in apps script.
Solution:
Change
body
topayload
Re-create the
payload
object as a query string. For example,payload:{x:1,y:2}
should be changed tox=1&y=2
.
Snippet:
- Payload object to query params:
function objectToQueryParams(obj) {
return (
Object.entries(obj)
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&')
);
}
const myPayload = {"client_id" : "XXXX",
"client_secret" : "XXXX",
"grant_type" : "client_credentials"};
console.log(objectToQueryParams(myPayload));
- Valid
requestOption
:
const requestOptions = {
/**@see https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object)*/
method: 'POST',
headers: myHeaders,
payload: objectToQueryParams(myPayload),//modified
//or just payload: myPayload will work as mentioned in the comments below
//redirect: 'follow',//removed
followRedirects: true
};
- Full script:
/**Mock UrlFetchApp library*/
const UrlFetchApp = {
fetch: () => ({
getContentText: () =>
'{"access_token":"jghlfdjlfwqwXjogsfshbkgetrwuguerjyrcyfxuux=="}',
}),
};
getCostAU(); //call function
//Mock end
function getCostAU() {
const myHeaders = {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
};
const myPayload = {
client_id: 'XXXX',
client_secret: 'XXXX',
grant_type: 'client_credentials',
};
function objectToQueryParams(obj) {
return Object.entries(obj)
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&');
}
const requestOptions = {
/**@see https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object)*/
method: 'POST',
headers: myHeaders,
payload: objectToQueryParams(myPayload), //modified
//or just payload: myPayload will work as mentioned in the comments below
//redirect: 'follow',//removed
followRedirects: true,
};
const url = 'https://apigateway.criteo.com/oauth2/token';
const result = JSON.parse(
UrlFetchApp.fetch(url, requestOptions).getContentText()
);
const access_token = result.access_token;
console.log(access_token);
}
回答2:
Answer: just changing the body
to payload
was enough.
function objectToQueryParams(obj) {
return (
Object.entries(obj)
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&')
);
}
const myPayload = {"client_id" : "XXXX",
"client_secret" : "XXXX",
"grant_type" : "client_credentials"};
console.log(objectToQueryParams(myPayload));
来源:https://stackoverflow.com/questions/64382781/api-post-request-in-google-app-script-not-working