'Google Apps Script: Connecting to Amazon Selling Partner API (Access Token)
I'm trying to connect to Amazon Selling Partner API using Google Apps Script.
The first step based on the documentation is to generate an access token if we don't have one valid at the moment (Access tokens expire one hour after they have been generated).
For that we would need the following inputs:
- grant_type (parameter)
- refresh_token (input)
- scope (parameter)
- client_id (input)
- client_secret (input)
I'm trying to generate an access token for an operation that requires seller authorization
Here is my code so far:
const REFRESH_TOKEN = "MyRefreshToken";
const CLIENT_ID ="MyClientID";
const CLIENT_SECRET = "MyClientSecret"
function AccessToken(){
var base_url = 'https://api.amazon.com/auth/o2/token';
var pointParams = "?grant_type=refresh_token&refresh_token=" + REFRESH_TOKEN + "&client_id=" + CLIENT_ID + "&client_secret=" + CLIENT_SECRET;
var query_string = base_url + pointParams;
var headers = {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
//'Host': 'api.amazon.com' (ignored since we already provided the url in the base_url var)
}
var options = {
'method' : 'POST',
'headers': headers,
//'muteHttpExceptions': true
};
var rawData = UrlFetchApp.fetch(query_string, options).getContentText();
Logger.log('rawData: ' + rawData)
}
Note: When we call an operation that requires seller authorization we will set the parameter grant_type = refresh_token
and in this case the scope
parameter should not be included
This is the example code provided by the website:
POST /auth/o2/token HTTP/l.l
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
grant_type=refresh_token
&refresh_token=Aztr|...
&client_id=foodev
&client_secret=Y76SDl2F
PROBLEM
I'm getting a 500 server error:
Exception: Request failed for https://api.amazon.com returned code 500. Truncated server response: {} (use muteHttpExceptions option to examine full response) AccessToken @ API.gs:30
Using 'muteHttpExceptions': true
only shows that the result of the UrlFetchapp is blank
QUESTIONS
Based on the documentation a 500 error is described as
There was an internal service failure.
However I would like to ask if there is some part of my code that I could improve or something else I could check since the response doesn't give me any leads.
UPDATE #1
Here are the formats of the const variables:
- REFRESH_TOKEN: Atzr|[a-zA-Z0-9-]*
- CLIENT_ID: amzn1.application-oa2-client.[a-z0-9]{32}
- CLIENT_SECRET: [a-z0-9]{64}
In the sample code provided by Amazon they do a POST to this address:
POST /auth/o2/token HTTP/l.l
However I'm not including HTTP/l.l
on my base_url
. I'm not sure if that would play a role in this problem.
UPDATE #2
I could generate an access token using the following curl command on my cmd terminal (Windows user) following this example:
curl -k -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=refresh_token&refresh_token=Atzr|IwE....&client_id=amzn1.application-oa2-client.d67...&client_secret=317dcd..." https://api.amazon.com/auth/O2/token
The response that I got was:
{"access_token":"Atza|IwEB...","token_type":"bearer","expires_in":3600}
As Tanaike points out its very likely that Google Apps Script might not be able to request to the endpoint.
Solution 1:[1]
Modification points:
- The default content type of
UrlFetchApp.fetch
isapplication/x-www-form-urlencoded
. And, UTF-8 is used. - I'm not sure whether the special characters are included in the values of
REFRESH_TOKEN
,CLIENT_ID
andCLIENT_SECRET
. So, how about reflecting the URL encode?
When above points are reflected to your script, it becomes as follows.
Modified script:
var base_url = 'https://api.amazon.com/auth/o2/token';
var pointParams = "?grant_type=refresh_token&refresh_token=" + encodeURIComponent(REFRESH_TOKEN) + "&client_id=" + encodeURIComponent(CLIENT_ID) + "&client_secret=" + encodeURIComponent(CLIENT_SECRET);
var query_string = base_url + pointParams;
var options = {
'method' : 'POST',
//'muteHttpExceptions': true
};
Note:
- Please confirm whether your values of
REFRESH_TOKEN
,CLIENT_ID
andCLIENT_SECRET
are the valid values again. - By the way, your question says
For that we would need the following inputs:grant_type (parameter) refresh_token (input) scope (parameter) client_id (input) client_secret (input)
. But, it seems that your script doesn't includescope
.
Added:
From your updated question, when your following curl command works fine,
curl -k -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=refresh_token&refresh_token=Atzr|IwE....&client_id=amzn1.application-oa2-client.d67...&client_secret=317dcd..." https://api.amazon.com/auth/O2/token
The Google Apps Script is required to be modified. Because your curl command sends the data as the form data. So could you please test the following sample script?
Sample script:
Please set the variables and test it.
var base_url = 'https://api.amazon.com/auth/O2/token';
var options = {
method: "post",
payload: {
grant_type: "refresh_token",
refresh_token: REFRESH_TOKEN,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET
},
// muteHttpExceptions: true
};
var rawData = UrlFetchApp.fetch(base_url, options).getContentText();
Logger.log(rawData)
Solution 2:[2]
Content-type
"application/x-www-form-urlencoded"
is not working. Changed it for "application/json"
and it works:
function AccessToken() {
var url = "https://api.amazon.com/auth/o2/token"
var params= {
"method":"POST",
headers: {
"Content-Type":"application/json"
},
payload: JSON.stringify({
"client_id":CLIENT_ID,
"client_secret":CLIENT_SECRET,
"grant_type":"refresh_token",
"refresh_token":REFRESH_TOKEN
//"scope":"appstore::apps:readwrite"
})
};
var response = JSON.parse(UrlFetchApp.fetch(url, params).getContentText());
Logger.log(response)
return response.access_token
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |