Discord API tells me: "401: Unauthorized" when i make a GET with Google-Scripts: "UrlFetchApp.fetch()" - google-apps-script

I'm setting up a api connection. I want to get informations from discord api for my app.
So I implemented OAuth2 without any problems, I have my access token. Then I tried query some endpoints (/users/#me, /users/#me/guilds,...) but every time I get the same error.
I'm sending my authorization token in headers but it's still returning error 401.
I call the script with the generated url:
https://discordapp.com/api/oauth2/authorize?client_id=XYZ&redirect_uri=https%3A%2F%2Fscript.google.com%2Fmacros%2Fs%2FAKfycbyyt9-FiVv0zXOr8p8pMfojwEs2AXvBftVN1xdWeU3UQ1xgURD%2Fexec&response_type=code&scope=identify
Here is my "authentication code":
function doGet(e){
if(typeof e.parameter.code !== 'undefined') {
var code = e.parameter.code;
getAccessToken(code);
}
return ContentService.createTextOutput('someThink..');
}
function getAccessToken(code){
var API_TOKEN_URL = 'https://discordapp.com/api/oauth2/token'
var CLIENT_ID = 'XYZ'
var CLIENT_SECRET = 'XYZ'
var REDIRECT_URI = 'https://script.google.com/macros/s/AKfycbyyt9-FiVv0zXOr8p8pMfojwEs2AXvBftVN1xdWeU3UQ1xgURD/exec'
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': REDIRECT_URI,
'scope': 'identify'
}
header = {
'method' : 'post',
'Content-Type': 'application/x-www-form-urlencoded',
'payload' : data
}
var result = UrlFetchApp.fetch(API_TOKEN_URL, header);
if (result.getResponseCode() == 200) {
var params = JSON.parse(result.getContentText());
Logger.log(params.access_token); // all is fine
getUser(params.access_token, params.token_type)
}
}
And this code is my API request:
function getUser(accessToken, token_type){
var API_USERS_URL = 'https://discordapp.com/api/users/#me';
header2 = {
'method' : 'GET',
'Authorization': token_type + ' ' + accessToken,
// I tested all of them
// 'followRedirects' : true,
// 'muteHttpExceptions': true,
// 'Content-Type': 'application/json',
// 'Content-Type': 'application/x-www-form-urlencoded',
}
var resultUsers = UrlFetchApp.fetch(API_USERS_URL, header2); // ERROR HERE !
if (resultUsers.getResponseCode() == 200) {
var paramsUser = JSON.parse(result.getContentText());
Logger.log(paramsUser);
}
}
I accept the connection with discord with the same SCOPES: identify.
I tried so hard but I don't succeed. Every time the same error:
{"code": 0, "message": "401: Unauthorized"}

You're sending the header as the params/options parameter to UrlFetchApp.fetch(). Send the header as the header parameter in options:
var resultUsers = UrlFetchApp.fetch(API_USERS_URL,{headers: header2});

Related

Google Apps Script and Google Search Console API

I need to access datas from Search Console using Apps Script.
I tried a loads of things but nothing worked.
I'm using this doc : https://developers.google.com/webmaster-tools/v1/searchanalytics/query
Here are some things I tried :
function authenticate() {
return gapi.auth2.getAuthInstance()
.signIn({scope: "https://www.googleapis.com/auth/webmasters https://www.googleapis.com/auth/webmasters.readonly"})
.then(function() { console.log("Sign-in successful"); },
function(err) { console.error("Error signing in", err); })}
function loadClient() {
gapi.client.setApiKey("YOUR_API_KEY");
return gapi.client.load("https://content.googleapis.com/discovery/v1/apis/searchconsole/v1/rest")
.then(function() { console.log("GAPI client loaded for API"); },
function(err) { console.error("Error loading GAPI client for API", err); })}
function execute() {
return gapi.client.webmasters.searchanalytics.query({
"resource": {}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error", err); })}
Other try:
function searchConsoleQuery() {
var service = getService();
var apiURL =
'https://www.googleapis.com/webmasters/v3/sites/[SITE_URL]/searchAnalytics/query';
var headers = {
'Authorization': 'Bearer ' + service.getAccessToken(),
'contentType':'application/json',
'startDate':'20019-10-01',
'endDate':'2019-10-10'};
var options = {
'payload': JSON.stringify(headers),
'method' : 'POST',
'muteHttpExceptions': true};
var response = UrlFetchApp.fetch(apiURL, options);
var json = JSON.parse(response.getContentText());
Logger.log(json)}
Modification points:
In your script, headers is used to payload.
'startDate' is 20019-10-01.
When these points are reflected in your script, it becomes as follows.
Modified script:
function searchConsoleQuery() {
var siteUrl = "###"; // Please set your site URL.
var service = getService();
var apiURL = `https://www.googleapis.com/webmasters/v3/sites/${encodeURIComponent(siteUrl)}/searchAnalytics/query`;
var options = {
'method': 'POST',
'muteHttpExceptions': true,
'headers': { 'Authorization': 'Bearer ' + service.getAccessToken() },
'contentType': 'application/json',
'payload': JSON.stringify({
'startDate': '2019-10-01',
'endDate': '2019-10-10'
})
};
var response = UrlFetchApp.fetch(apiURL, options);
var json = JSON.parse(response.getContentText());
Logger.log(json)
}
Note:
In this modification, it supposes that Google Search Console API has already been enabled at API console and also siteUrl and your access token of service.getAccessToken() are the valid values for using the API. Please be careful about this. When I tested this modified script with my site URL, I confirmed that the values are returned without error. So, if an error occurs, please confirm the condition of API in your API console and your values again.
If no values are returned, please modify 'startDate': '2019-10-01' and 'endDate': '2019-10-10' and test it again.
References:
Search Analytics: query
fetch(url, params)

Why is Forge returning code 403 for Data Connector API This clientId is not authorized to perform the operation

Why is Forge returning code 403 for Data Connector API This clientId is not authorized to perform the operation. The token call comes back correctly but I get 403 on the gethubs {"warnings":[{"Id":null,"HttpStatusCode":"403","ErrorCode":"BIM360DM_ERROR","Title":"Unable to get hubs from BIM360DM EMEA.","Detail":"You don't have permission to access this API","AboutLink":null,"Source":null,"meta":null}]}}
And getcon as well "{"detail":"This clientId is not authorized to perform the operation.","status":403,"type":"error","title":"Forbidden","id":69852363,"errors":[{"detail":"This clientId is not authorized to perform the operation.","title":"Forbidden","type":"error"}]}"
These are the calls from App script using, what I think is, 3-legged code grant.
function getToken() {
var formData = {
'client_id': 'ClientID',
'client_secret': 'ClientSecret',
'grant_type': 'client_credentials',
'scope': 'user-profile:read user:read user:write viewables:read
data:create data:read data:write data:search bucket:read bucket:create
bucket:update code:all account:read account:write',
'prompt':'login'
}; var response =
UrlFetchApp.fetch('https://developer.api.autodesk.com/authentication/v1/a uthenticate', {
method: 'POST',
payload: formData
});
var token = JSON.parse(response.getContentText());
console.log(token);
return token.access_token;
}
function getHubs() {
var token = getToken();
console.log(token);
var header = {"Authorization" : "Bearer " + token};
console.log(header);
var options = {
"method" : "get",
"headers" : header
};
var response = UrlFetchApp.fetch('https://developer.api.autodesk.com/project/v1/hubs', options);
var hubs = JSON.parse(response.getContentText());
console.log(JSON.stringify(hubs));
}
function getDConn() {
var token = getToken();
console.log(token);
var header = {"Authorization" : "Bearer " + token,"Content-Type": "application/json" };
console.log(header);
var options = {
"method" : "post",
"headers" : header,
"description": "AccountExtract",
"isActive": true,
"scheduleInterval": "ONE_TIME",
"reoccuringInterval": null,
"effectiveFrom": "2022-10-06T10:00:00.106Z",
"effectiveTo": "2022-10-06T10:00:00.106Z",
"serviceGroups": "locations",
"callbackUrl": null,
"sendEmail": true,
"projectId": null
};
//Google Account ID
var response = UrlFetchApp.fetch('https://developer.api.autodesk.com/data- connector/v1/accounts/ACCOUNTID/requests', options);
var hubs = JSON.parse(response.getContentText());
console.log(JSON.stringify(hubs));

Google Apps Script : API Error message "client_id is required"

I've created a variable to hold the client ID (CLIENT_ID) but I keep getting an error message saying that the client ID is required when running this function. Anyone have any idea of what I've done wrong here?
function getAuth() {
var authBasedUrl = 'https://test-api.service.hmrc.gov.uk/oauth/authorize';
var response = UrlFetchApp.fetch(authBasedUrl, {
headers: {
'Accept' : 'application/vnd.hmrc.1.0+json',
'response_type': 'code',
'client_id' : CLIENT_ID,
'scope' : 'hello',
'redirect_uri' : 'https://www.xxxxxxx.com/'
}});
var result = JSON.parse(response.getContentText());
Logger.log(JSON.stringify(result, null, 2));
}
Based on the docs you need to make a POST request. There is a blockqoute on the page that says:
Include the request parameters in the request body, not as request
headers.
EDIT:
function getAuth() {
var authBasedUrl = 'https://test-api.service.hmrc.gov.uk/oauth/token';
var options = {
headers: {
'Accept': 'application/vnd.hmrc.1.0+json',
"Content-Type": "application/json"
},
payload: JSON.stringify({
client_id: 'RgwU6hvdxxxxxxic6LwIt',
client_secret: '9e8c9yyyyyyyyyyc2fc2ed9126',
grant_type: 'client_credentials',
scope: 'hello'
})
}
var response = UrlFetchApp.fetch(authBasedUrl, options);
var result = JSON.parse(response.getContentText());
console.log(result);
}

LinkedIn API OAUTH returning "grant_type" error

I am pretty new to coding, but trying to write a simple script using LinkedIn's API that will pull an organizations follower count into google app script. Before I can even query the API, I have to authenticate using oath explained in the LinkedIn API here.
This function returns with an error response
function callLinkedAPI () {
var headers = {
"grant_type": "client_credentials",
"client_id": "78ciob33iuqepo",
"client_secret": "deCgAOhZaCrvweLs"
}
var url = `https://www.linkedin.com/oauth/v2/accessToken/`
var requestOptions = {
'method': "POST",
"headers": headers,
'contentType': 'application/x-www-form-urlencoded',
'muteHttpExceptions': true
};
var response = UrlFetchApp.fetch(url, requestOptions);
var json = response.getContentText();
var data = JSON.parse(json);
console.log(json)
}
When I try sending the headers through I get this error as a response
{"error":"invalid_request","error_description":"A required parameter \"grant_type\" is missing"}
grant_type, client_id, client_secret do not go in the header of the request. Instead, try to put them in the body of the POST request with the content type x-www-form-urlencoded as you already had in the headers of the code you posted.
For example:
fetch('https://www.linkedin.com/oauth/v2/accessToken/', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: '78ciob33iuqepo',
client_secret: 'deCgAOhZaCrvweLs'
})
})
.then(response => response.json())
.then(responseData => {
console.log(JSON.stringify(responseData))
})
Using Apps Script you should send the payload like so:
Example:
function callLinkedAPI() {
var payload = {
"grant_type": "client_credentials",
"client_id": "78ciob33iuqepo",
"client_secret": "deCgAOhZaCrvweLs"
}
var url = `https://www.linkedin.com/oauth/v2/accessToken/`
var requestOptions = {
'method': "POST",
'contentType': 'application/x-www-form-urlencoded',
'muteHttpExceptions': true,
"payload":payload
};
var response = UrlFetchApp.fetch(url, requestOptions);
var json = response.getContentText();
var data = JSON.parse(json);
console.log(json)
}

How to use Google Apps Script to create issues in Redmine?

I'm trying to create an issue in Redmine using Google Apps Script, the code is following:
function create_issue() {
var payload = {
'project_id': 'helpdesk',
'subject': 'This is a test ticket',
'description': 'This is just a genius test ticket',
'category_id': 1
};
var headers = {
'X-Redmine-API-Key': '<myapikey>',
'Content-Type': 'application/json'
};
var url = 'http://myredmine.com/issues.json';
var options = {
'method': 'POST',
'headers': headers,
'payload': payload,
//uteHttpExceptions': true
};
var response = UrlFetchApp.fetch(url, options);
Logger.log(response);
}
Every time I ran that script, it threw the following exception:
Execution failed: Request failed for http://myredmine.com/issues.json
returned code 422. Truncated server response: {"errors":["Subject
can't be blank"]} (use muteHttpExceptions option to examine full
response) (line 25, file "Code") [0.645 seconds total runtime]
But as you see, the "subject" parameter was passed in the payload already. What am I missing?
Thanks,
Trinh
I found the problem, I need to indicate the issue in the payload:
function create_issue() {
var issue = {
"description": "Test ticket",
"subject": "Genius ticket"
}
var payload = {
"issue": issue,
"key": "<myapikey>",
"project_id": "helpdesk",
};
payload = JSON.stringify(payload);
var headers = {
'X-Redmine-API-Key': '<myapikey>',
'Content-Type': 'application/json'
};
var url = 'http://myredmine.com/issues.json';
var options = {
'method': 'POST',
'headers': headers,
'payload': payload,
'contentType': 'application/json',
//'muteHttpExceptions': true
};
var response = UrlFetchApp.fetch(url, options);
Logger.log(response);
}
And it works!