Making a curl request with headers in apps script - google-apps-script

I am trying to make a curl request using apps script, the link of the official guide of which is below. Here is the query:
curl -X POST "https://bhagavadgita.io/auth/oauth/token" -H "accept: application/json" -H "content-type: application/x-www-form-urlencoded" -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=client_credentials&scope=verse"
According to the official guide:
How to get an access token?
Make a POST request to /auth/oauth/token with these parameters sent in Headers -
Client ID - Obtained from Account Dashboard after registering an app.
Client Secret - Obtained from Account Dashboard after registering an app.
Grant Type - Use client credentials.
Scope - Use verse if you just want to access the verses, chapter if you just want to access the chapters and verse chapter if you want access to both.
I have written the code as below:
function myFunction() {
var data = {
'accept': 'application/json',
'content-type': 'application/x-www-form-urlencoded',
'header':{
'client_id':'MY-CLIENT-ID',
'client_secret':'MY-CLIENT-SECRET',
'grant_type':'client_credentials',
'scope':'verse'
}
};
var response = UrlFetchApp.fetch('https://bhagavadgita.io/auth/oauth/token', data);
Logger.log(response.getContentText());
}
I am getting an error as below:
Exception: Request failed for https://bhagavadgita.io returned code 405. Truncated server response: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>405 Method Not Allowed</title> <h1>Method Not Allowed</h1> <p>The method is not allo... (use muteHttpExceptions option to examine full response) (line 13, file "Code")
What is the proper way of making such a request?
Reference: https://bhagavadgita.io/api/

405 error is stating that you cannot query that endpoint with the current HTTP verb.
You should specify that your .fetch method is making a POST Http request.
To do so you have to specify in the "method" : "post" parameter in your fetch options:
var data = {
'client_id':'MY-CLIENT-ID',
'client_secret':'MY-CLIENT-SECRET',
'grant_type':'client_credentials',
'scope':'verse'
}
var options = {
"method" : "post",
"accept": "application/json",
"content-type": "application/x-www-form-urlencoded",
"payload" : data
}
var response = UrlFetchApp.fetch('https://bhagavadgita.io/auth/oauth/token', options);
References:
UrlFetchApp
REST

Related

How to ensure the API response for a request is JSON type in Google Apps Script? [duplicate]

This question already has answers here:
Apps Script - UrlFetchApp.fetch {url, method: "GET"} to a gzip gets failed with code 406
(2 answers)
Closed 1 year ago.
I'm trying to login to the tableau rest API in apps script and then get all the available views under a workbook. I'm authenticating via PATs and on successful sign-in I receive a response from the API that looks like XML response.
Here's the fetch code for that:
function tableauTM() {
const options = {
method: 'post',
muteHttpExceptions: true,
contentType: 'application/json',
Accept: 'application/json',
payload: JSON.stringify(
{
credentials: {
personalAccessTokenName: 'Tableau',
personalAccessTokenSecret: '<token_secret>',
site: {
contentUrl: 'pixybi',
},
},
}
),
};
const response = UrlFetchApp.fetch(
'https://10ay.online.tableau.com/api/3.13/auth/signin', options
);
Logger.log(response)
This is the response text I receive:
<?xml version='1.0' encoding='UTF-8'?><tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api https://help.tableau.com/samples/en-us/rest_api/ts-api_3_13.xsd"><credentials token="1j4LgLC1TQagsevrKPwJEw|VGo4bJwHbRQPRYxuOaeHhnsVth7nNc3e" estimatedTimeToExpiration="363:04:39"><site id="c3f66f3d-1112-4bff-a5f4-b4022e303d13" contentUrl="udacitybi"/><user id="c34bf5f6-86b8-4de6-a619-f68837bce120"/></credentials></tsResponse>
How to ensure that the response is of JSON type and if that's not possible how can
one extract the attribute values for fields like token, user, and site id?
We tried the below code but it's throwing the type error: TypeError: Cannot read property 'getChild' of null
var root = XmlService.parse(response).getRootElement().getChild('credentials').getChild('user').getAttribute('id').getValue()
You can parse XML using XML Service. Based on your error message, no root element exists, therefore you should first try hasRootElement() before calling getRootElement(). Instead you can try getDescendants() and log out its result.
Fix your options by adding Headers under the headers parameter. See the UrlFetch Docs. Basically, see headers below for what I mean. Hopefully this should enable you to receive JSON.
const options = {
method: 'post',
muteHttpExceptions: true,
contentType: 'application/json',
headers: { Accept: 'application/json' }, …
}

Error 401 using Metabase API Session Token in Google Apps Script

I coded a script in Google Apps Script to catch some Metabase data and write it on a Google Sheet. When I make the login using my credentials the function work and I receive the Session Token.
But using the token in the script to access my cards the error 401 Unauthenticated is shown.
var headers = {
"method": "get",
"contentType": "application/json",
"X-Metabase-Session": "22222222-cccc-4444-9999-333333333333",
"muteHttpExceptions": true
};
Logger.log(headers);
var response = UrlFetchApp.fetch(url, headers);
I test the url and session token in my local terminal using curl command and it works normally. The Google Apps Script is almost authorized and doesn't inform any error. Does someone have any idea?
When I saw the official document of Example GET request, the sample curl command can be seen as follows.
curl -X GET \
-H "Content-Type: application/json" \
-H "X-Metabase-Session: 38f4939c-ad7f-4cbe-ae54-30946daf8593" \
http://localhost:3000/api/user/current
From this curl command, it seems that X-Metabase-Session is required to be included in the request header. So when your script is modified, it becomes as follows.
Modified script:
var options = {
"method": "get",
"contentType": "application/json",
"headers": { "X-Metabase-Session": "22222222-cccc-4444-9999-333333333333" }, // Modified
"muteHttpExceptions": true
};
var response = UrlFetchApp.fetch(url, options);
Note:
From I test the url and session token in my local terminal using curl command and it works normally., in this case, I thought that when you test the above modified script, it will work.
Reference:
Example GET request

Google Apps Script - Connect to external API by using a token received at login

I'm trying to work with an external API and can't make it work after the first step.
The API is for an affiliate marketing platform, 2Performant, and supports only JSON format.
The first step is to login.
In response several headers are received that define the session.
These are: access-token | client | expiry | token-type | uid
In the next request I need to inject mandatory access-token | client | uid headers.
I managed to do the first step but get an error for my second one.
This is the code that I'm using.
function apiconnect() {
var url = "https://api.2performant.com/users/sign_in.json";
var data = {
"user": {
"email": "mail#example.com",
"password": "mypassword"
}
};
var options = {
"method" : "post",
"contentType" : "application/json",
"payload" : JSON.stringify(data)
};
var response = UrlFetchApp.fetch(url,options);
var text = response.getResponseCode();
var token = response.getHeaders()["access-token"];
var client = response.getHeaders()["client"];
var uid = response.getHeaders()["uid"];
Logger.log(text);
Logger.log(JSON.parse(response.getContentText()));
Logger.log(response.getHeaders());
Logger.log(token);
Logger.log(client);
Logger.log(uid);
var urlPrograms = "https://api.2performant.com/affiliate/programs";
var optionsPrograms = {
"contentType" : "application/json",
"headers" : {"access-token": token,
"client" : client,
"uid" : uid,
}
};
Logger.log(UrlFetchApp.fetch(urlPrograms,optionsPrograms));
}
For the first part I can see the correct responses in the logs but I'm getting an error for the second one. The error is 500 (Internal Server Error).
I've noticed that I get a 401 code ("Provided session is not valid anymore either does not exist at all") if I put a random text instead of the correct one in one of the three needed headers (uid, password or token).
By using curl in the terminal, the second step works, but I can't manage to translate this in the Apps Script.
curl -H "Content-Type: application/json" -X POST -d '{"user":{"email":"mail#example.com","password":"mypassword"}}' -i https://api.2performant.com/users/sign_in.json
curl -H "Content-Type: application/json" -H "access-token: 12345" -H "client: 123" -H "uid: mail#example.com" -i https://api.2performant.com/affiliate/programs
It's probably obvious that i'm not experienced in this so hopefully I was clear enough with my description.
If you can point me to the right direction to replicate the curl in apps script that would be amazing.
Thanks!
It seems it was as simple as just adding .json to the second URL.

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!

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)