Exception: Bad request: https://internal-api.company.com... -Google appscript - google-apps-script

I have an internal API that I can check by postman status connected to VPN and with a token that changes daily:
but I have not been able to make the same query from Google Apps Script, I get this error:
Exception: Bad request: https://... .
function nomina() {
var url = 'https://internal-api.company.com/app-api/master/api/ssff/users';
var headers= {
'Authorization' : 'Bearer token',
'Accept': 'application/json',
'contentType': 'application/json'
}
var options =
{
'method' : 'GET',
'headers' : headers
}
var response = UrlFetchApp.fetch(url,options);
jsonParse=(JSON.parse(response))
}
Maybe you could suggest me something to be able to do the API query?
I need to know why it doesn't give me an answer, this is another API that I use and this does bring me information.
I see this similar post but have same error still:
Request to external api to get authentication token in google appscript

Google Apps Script run from the Google servers. It can't use your VPN. You should talk with the responsible of the API and request them to make a connection with Google servers. They might have to involve other people (system and / or networks administrators).

Related

How to allow Cors Headers in Google AppScript for making an XMLHttpRequest?

I have created a doGet and doPost endpoints in my appscript. When I hit the endpoint to make a post request from Python, it does work perfectly and as expected.
But when I try to hit the same url with my Flutter based mobile App, it throws me an XML error. (Which I suspect is related to CORSING).
When I hit the url with get request, I get the right response, but post request is failing. To ensure that my Post request is properly configured, I have made a post request to public API and it worked like charm.
Is it possible to add headers, where I could enable cors like this:
allowHeaders = {
"Access-Control-Allow-Origin": "*", // Required for CORS support to work
"Access-Control-Allow-Credentials": true, // Required for cookies, authorization headers with HTTPS
"Access-Control-Allow-Headers": "Origin,Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,locale",
"Access-Control-Allow-Methods": "POST, OPTIONS"
}
Here is what my doPost request returns:
ContentService.createTextOutput(JSON.stringify(
{
data: isAuthenticated.data,
error: true,
//request: request,
msg: query.apiKey,
//paramters:request.parameters
})).setMimeType(ContentService.MimeType.JSON)
Here is my python script to get the post response:
requests.post("https://script.google.com/macros/s/AKfycbz7kTROol8u509M_p9pMZ9XRnL-myVjcRQKeb9Etp_OIMPnH640vHf_0Jp2dvvrbto7kOg/exec",
json = requestObject)
And here is my Flutter function:
Future<http.Response> createAlbum() async{
print("Trying to make a post request");
var result = await http.post(Uri.parse('https://script.google.com/macros/s/AKfycbz7kTROol8u509M_p9pMZ9XRnL-myVjcRQKeb9Etp_OIMPnH640vHf_0Jp2dvRIco7kOg/exec'),
headers: {"Content-Type": "application/json"},
body: jsonEncode(<String, dynamic>{
"apiKey":apiKey,
"operationType":"register_user",
"operationData": {
"email": "shivam#yoptima.com",
"otp": 318728
}
}),
);
print("Here is the result: " + result.body);
}
Just to clarify things:
Get Request works for both the platforms.
Post Request works with python for AppScript.
Post Request works for any other public API from flutter.
Post Request doesn't work for Flutter when Hitting AppScript API.
I suspect it to be something to do with CORS. (But not very sure).
Flutter http library makes request via XMLHttpRequest.

Github GraphQL API Authentication

I want to retrieve data from github's graphql api but I keep getting error message:
{ message: 'This endpoint requires you to be authenticated.', documentation_url: 'https://docs.github.com/v3/#authentication' }
Despite using a token, I even generated a new token to see if the other one was broken. The script to fetch the data can be found at https://repl.it/#DukeSanmi/AcrobaticModernLanguage#index.js
What could be the issue?
Okay you need to put a space between bearer and your variables.githubToken like so:
const headers = {
'Content-Type': 'application/json',
'Authorization': 'bearer ' + variables.githubToken
};
Furthermore, NEVER publish secrets/credentials like API tokens in public code!

"Insufficient Permission" when trying to authenticate to cloud-storage via apps-script

I am about to give up on this as I can't find out what I am doing wrong.
I have a cloud-storage bucket with our companies billing data (json file objects written by google) that I am supposed to process into spreadsheets.
As there is no apps script API for oauth2, I am using the custom OAuth2 library provided by google with the key "1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF", and have setup the auth request as shown in this example for service accounts:https://github.com/googlesamples/apps-script-oauth2/blob/master/samples/GoogleServiceAccount.gs
The token is being created and put into the scripts property store, where I can view it. So far so good.
I have this code for requesting the token and then I am trying to list the contents of the bucket in the function "getFilesList()":
function getService() {
return OAuth2.createService('CloudStoreGrab-Service')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setPrivateKey(creds_private_key)
.setIssuer(creds_client_email)
.setSubject(creds_user_email)
.setPropertyStore(PropertiesService.getScriptProperties())
.setScope(['https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/script.external_request','https://www.googleapis.com/auth/script.storage','https://www.googleapis.com/auth/spreadsheets']);
}
function getFilesList() {
var service = getService();
service.reset();
if (service.hasAccess()) {
var url = 'https://www.googleapis.com/storage/v1/b/'+bucket+'/o';
var response = UrlFetchApp.fetch(url, {
method: "GET",
muteHttpExceptions: true,
headers: {
Authorization: 'Bearer ' + service.getAccessToken()
}
});
}
Logger.log("Response:", response.getContentText())
}
No matter what I seem to try, the request always returns "403 Insufficient Permission". The service account has all necessary roles and permissions activated though (DwD, Storage-Administrator, Project-Owner). When I authenticate with the same credentials from gcloud and then browse the bucket with gsutils I can see the listing. This leads me to believe, that I am still requesting the auth token incorrectly. I tried using the generated token with curl and am getting the same Insufficient Permission response.
What am I doing wrong, while requesting the token?
Are the requested scopes too narrow?
Are the requested scopes too narrow?
That they are. You can find the OAuth scopes for Google's Cloud Storage API listed below (you won't need to use all of them, pick the ones best suited to your use-case, the 1st and 5th scopes in the list should be sufficient):
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/cloud-platform.read-only
https://www.googleapis.com/auth/devstorage.full_control
https://www.googleapis.com/auth/devstorage.read_only
https://www.googleapis.com/auth/devstorage.read_write
In future, you can find the required OAuth scopes for any Google API you need at the following link:
https://developers.google.com/identity/protocols/googlescopes

UrlFetchApp Post Req response inconsistent

When I make a request via apps script, the response is inconsistent than when I make a request with a tool like postman or any other way of sending a post request, it seems specific to apps script.
Here is my request:
var headers = {'Authorization': 'Bearer #'},
var payload = JSON.stringify({'_id':_id, "email": email}),
var options = {
'method': 'post',
'contentType': 'application/x-www-form-urlencoded',
'payload': payload,
'headers': headers,
'muteHttpExceptions':false
}
var response = UrlFetchApp.fetch('https://...", options);
The response code is 201, it appears that the contentText returned in the response is correct except for one key piece of information, the email that was sent in the post payload should be in the response as well. After the post is sent, it triggers an email using the email sent in the payload. This doesn't work with the apps script post request.
When I run this same exact request via postman or another tool, it works perfectly, the email is triggered right after the request is sent and works as intended.
Does anyone have any ideas why the "email" in the payload isn't working via apps script, but does via postman? Do I have an error in payload or way I'm using UrlFetchApp?
Change content type to:
'contentType': 'application/json',
The documentation shows an example with the object stringified, and they change the contentType
Apps Script Documentation UrlFetchApp.fetch(url, parameters)

StackExchange API authentication in Google Apps Script

I'm trying to use the V2.2 of StackExchange API in Google Apps Script.
The problem comes in the last step of the explicit OAuth 2.0 flow, when I try to send the POST request to obtain the access token. I receive a 404 error, but making the same request manually (using postman extension) everything is ok.
To simplify the problem, if I send this POST request with no payload I receive the same 404
var response = UrlFetchApp.fetch("https://stackexchange.com/oauth/access_token", {
method: 'post',
muteHttpExceptions: true
});
Logger.log(response);
while in postman I receive this 400:
{
"error": {
"type": "invalid_request",
"message": "client_id not provided"
}
}
I guess this will be a problem with UrlFetchApp, but does anyone know how to solve it? Thanks!
The problem is related with the Origin header.
You cannot remove from the header directly but you can perform the call via a proxy :)
You need to provide the data for the post by adding an 'option' object to the call.
For example:
var options = { "method" : "post", "payload" : payload };
UrlFetchApp.fetch("https://stackexchange.com/oauth/access_token", options);
Btw, have you tried you use the OAuth that UrlFetch got: https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#addOAuthService(String) - It might be better way.