How to request access token for Reddit on Google Apps Script - javascript

I have been trying to figure out how to acquire an access token from Reddit API in Google Apps Script. I have below code written so far:
function main() {
var username = 'myredditusername';
var pwd = 'myredditpassword';
var client_id = 'myredditclientid';
var client_secret = 'myredditclientsecret';
var access_token_url = 'https://www.reddit.com/api/v1/access_token';
var api_url = 'https://oauth.reddit.com/';
var user_agent = 'MySideProjectUserAgent';
var data = {
'grant_type': 'password',
'username': username,
'password': pwd
};
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify(data),
'headers': {'User-Agent': user_agent},
// what do I enter here to pass my client_id and client_secret?
};
var resp = UrlFetchApp.fetch(access_token_url, options);
console.log(resp.getContentText());
}
Running the above code receives an error like below (not surprising because I still need to figure out how to pass in my client_id and client_secret):
Exception: Request failed for https://www.reddit.com returned code 401. Truncated server response: {"message": "Unauthorized", "error": 401} (use muteHttpExceptions option to examine full response)
When using curl, I was able to acquire the token successfully with this command:
curl -X POST -A 'KeywordTrackAgent' -d "grant_type=password&username=myredditusername&password=myredditpassword" --user 'client_id:client_secret' https://www.reddit.com/api/v1/access_token
From reaching around (example post), I figured that if I were to translate this curl request to a POST request, I'd need to add Authorization field to my headers parameter with the format like below:
function main() {
var username = 'myredditusername';
var pwd = 'myredditpassword';
var client_id = 'myredditclientid';
var client_secret = 'myredditclientsecret';
var access_token_url = 'https://www.reddit.com/api/v1/access_token';
var api_url = 'https://oauth.reddit.com/';
var user_agent = 'MySideProjectUserAgent';
var data = {
'grant_type': 'password',
'username': username,
'password': pwd
};
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify(data),
'headers': {
'User-Agent': user_agent,
// Below, I decided to encode my client_id and client_secret in base64 with the prefix 'Basic '
'Authorization': 'Basic clientIdAndClientSecretInBase64',
},
};
var resp = UrlFetchApp.fetch(access_token_url, options);
console.log(JSON.parse(resp.getContentText()));
}
I'm still receiving { error: 'unsupported_grant_type' }.
Could anyone--who has successfully fetched Reddit access token using JavaScript and preferably, using Google Apps Script--share some suggestion/insight on this? Thank you in advance for your answers!

I believe your goal as follows.
You want to convert the following curl command to Google Apps Script.
curl -X POST -A 'KeywordTrackAgent' -d "grant_type=password&username=myredditusername&password=myredditpassword" --user 'client_id:client_secret' https://www.reddit.com/api/v1/access_token
This curl command sends the data as the form data. And, the basic authorization is used. When these are reflected to the Google Apps Script, it becomes as follows.
Sample script:
In this script, your values are used.
function main() {
var username = 'myredditusername';
var pwd = 'myredditpassword';
var client_id = 'myredditclientid';
var client_secret = 'myredditclientsecret';
var access_token_url = 'https://www.reddit.com/api/v1/access_token';
var data = {
'grant_type': 'password',
'username': username,
'password': pwd
};
var options = {
'method': 'post',
'payload': data,
'headers': {
'Authorization': 'Basic ' + Utilities.base64Encode(`${client_id}:${client_secret}`),
},
};
var resp = UrlFetchApp.fetch(access_token_url, options);
console.log(JSON.parse(resp.getContentText()));
}
At this script, the request is same with the curl command.
Note:
In this script, it supposes that the values for authorizating are correct. Please be careful this.
Reference:
fetch(url, params)

Related

App Script Shopify GraphQL Request - 400 response

I am trying to call Shopify's GraphQL API via Google App Script.
I have successfully made the call via Postman using the same body and authentication values and that has been working fine.
However, when calling the API via App Script I keep receiving a 400 response code, with the following error message {"errors":{"query":"Required parameter missing or invalid"}}
Here is the code I am using:
function shopifySync() {
var url = "https://store-name.myshopify.com/admin/api/2021-07/graphql.json";
var payloaddata = `query {orders(first: 20) { edges { node { id } } } }`;
var payload = JSON.stringify(payloaddata);
var password = "api_password"; //Private Shopify App
var response = UrlFetchApp.fetch(url, {
'method': "POST",
'muteHttpExceptions': true,
'headers': { "X-Shopify-Access-Token": password , "Content-Type": "application/json"},
'payload': payload
},
);
Logger.log(response.getContentText());
Logger.log(response.getResponseCode());
}
In Shopify's documentation the 400 HTTP response is classified as "Bad Request" and the explanation is:
The request was not understood by the server, generally due to bad syntax or because the Content-Type header was not correctly set to application/json.
This status is also returned when the request provides an invalid code parameter during the OAuth token exchange process.
Source: https://shopify.dev/api/usage/response-codes
How can I resolve this issue and successfully call Shopify's GraphQL API?
I found the solution in the GraphQL documentation of another Saas company.
The issue was how the payload was formatted
How I tried it:
'payload': payload
How it should be:
'payload': JSON.stringify({'query': payloaddata})
Final code that is working for me with the 2021-07 GraphQL API for Shopify:
var url = "https://store-name.myshopify.com/admin/api/2021-07/graphql.json";
var payloaddata = 'query {orders(first: 20) { edges { node { id } } } }';
var password = "api_password";
var response = UrlFetchApp.fetch(url, {
'method': "POST",
'muteHttpExceptions': true,
'headers': { "X-Shopify-Access-Token": password , "Content-Type": "application/json"},
'payload': JSON.stringify({'query': payloaddata})
});

Request failed returned code 400. Truncated server response - Google scripts

I am very new to APIs. I have successfully built an API in postman and got the data I wanted. I generated the code sample provided by postman in JavaScript format:
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
myHeaders.append("Authorization", "Basic ZGVhbGdwwitpflgnBvcnQ6ZldZUmZvVEU5a2hNaFZtUlBlcU1VZ3J5eFRhWXBwN0U3d1hdllBZw==");
var urlencoded = new URLSearchParams();
urlencoded.append("grant_type", "password");
urlencoded.append("username", "123456789");
urlencoded.append("password", "password123!");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
};
fetch("https://accounts.kernel.com/oidc/token", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
However, I want to build this API in google scripts using the function UrlFetchApp. So far I am doing this:
function webRelay(){
var url = 'https://accounts.autoscout24.com/oidc/token';
var username = "123456789";
var password = "password123!";
var headers =
{
"Content-Type" : "application/x-www-form-urlencoded" ,
"Authorization" : "Basic ZGVhbGdwwitpflgnBvcnQ6ZldZUmZvVEU5a2hNaFZtUlBlcU1VZ3J5eFRhWXBwN0U3d1hdllBZw=="
}
var options =
{
"grant_type" : "password",
"timeout": 0,
"method" : "post",
"headers": headers
};
// Getting "bad request" here - check the username & password
var result = UrlFetchApp.fetch(url, options);
var state=result.getContentText();
}
But I get the following error:
Request failed for https://accounts.kernel.com returned code 400.
Truncated server response: {"error":"invalid_request"} (use
muteHttpExceptions option to examine full response) (line 22, file
"api")
You want to convert the Javascript in your question to Google Apps Script.
You have already confirmed that your Javascript worked.
I could understand like above. For this, how about the following modification?
Modification points:
In options of UrlFetchApp.fetch(url, options), there are no properties ofgrant_typeandtimeout`.
When your Javascript is seen, the data is sent as the form data.
Default "Content-Type" of UrlFetchApp is application/x-www-form-urlencoded.
In your script, username is not used.
When above points are reflected to the script, it becomes as follows.
Modified script:
Before you use the modified script, please set the variables of username, password and headers.
function webRelay(){
var url = 'https://accounts.autoscout24.com/oidc/token';
var username = "123456789";
var password = "password123!";
var payload = {
"grant_type": "password",
"password": password,
"username": username
}
var headers = {"Authorization" : "Basic ###"};
var options = {
"method" : "post",
"headers": headers,
"payload": payload,
};
var result = UrlFetchApp.fetch(url, options);
var state = result.getContentText();
Logger.log(state)
}
In this modified script, your token was removed using ###. When you use this, please modify it.
Reference:
Class UrlFetchApp
Although I think that the request ob above modified script is the same with your Javascript. But unfortunately, I cannot test above script. I apologize for this. So if this didn't work for your situation, I apologize.

File not uploaded on server using node js

I want to to bulk translocation and for that I uploaded the.csv file, its worked for me if I am using curl command but when I used its on node code its showing me error "file not uploaded"
Regarding to curl I am using that code which is working for me :-
curl -F 'data=#/var/www/html/achupload.csv' https://sandbox.usaepay.com/api/v2/bulk_transactions -H "Authorization: Basic X3llMVI3Mk9PdzFHOXBqcW1GaVp2NHJINjRc="
and this is my node code which are showing me error message :-
var request = require('request');
var headers = {
'Authorization': 'Basic X3llMVI3Mk9PdzFHOXBqcW1GaVp2NHJINjRc='
};
var dataString = '#/var/www/html/achupload.csv';
var options = {
url: 'url',
method: 'POST',
headers: headers,
data: dataString
};
console.log("options====",options);
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
else{
console.log("notttttttttttt================",response.body);
}
}
request(options, callback);
How about this modification?
Modification points:
File content is retrieved with fs.createReadStream().
The file is sent as formData.
Modified script:
From:
var request = require('request');
var headers = {
'Authorization': 'Basic ###'
};
var dataString = '#/var/www/html/achupload.csv';
var options = {
url: 'url',
method: 'POST',
headers: headers,
data: dataString
};
To:
var fs = require('fs'); // Added
var request = require('request');
var headers = {
'Authorization': 'Basic ###'
};
var dataString = {data: fs.createReadStream('/var/www/html/achupload.csv')}; // Modified
var options = {
url: 'url',
method: 'POST',
headers: headers,
formData: dataString // Modified
};
Note:
In this modified script, 'Authorization': 'Basic ###' was used. Please be careful this. When you use this, please replace ### to yours.
References:
fs.createReadStream()
multipart/form-data (Multipart Form Uploads)
If this didn't resolve your issue, I apologize.

Google Script return content type header missing error when making HTTP GET request

I try to make a GET request using Google Script. Sample code as below:
var username = "test#test.com";
var password = "12345";
var headers = {
"Authorization": "Basic "+ Utilities.base64Encode(username+":"+password)
};
var url = 'https://localhost/api/v2/get_sections/21';
var options = {
'method': 'get',
'contentType' : 'application/json',
'headers': headers
};
var response = UrlFetchApp.fetch(url, options);
I received an error
Request failed for https://localhost/api/v2/get_sections/21 returned code 400. Truncated server response: {"error":"Content-Type header missing (use Content-Type: application/json)"}
Is this the right way to make a get request?
The Content-Type is also a header, try :
var username = "test#test.com";
var password = "12345";
var headers = {
"Content-Type": "application/json",
"Authorization": "Basic "+ Utilities.base64Encode(username+":"+password)
};
var url = 'https://localhost/api/v2/get_sections/21';
var options = {
'method': 'get',
'headers': headers
};
var response = UrlFetchApp.fetch(url, options);

Send a set-cookie header to a redirect url in node.js

I am using node.js request module to fetch an id_token from an API. After fetching that id_token I want to send a redirect uri response with a set-cookie header to the redirected url. But I can't quite figure out how to do it.
Here is my code:
app.use("/nodejs-server/retrieveCode", function(req, res) {
var clientID = 'some random string'
var client_Secret = 'another random string'
var code_token = clientID + ":" + client_Secret
var buffer = new Buffer(code_token)
var token = buffer.toString('base64')
var rtoken = "Basic " + token;
var headers = {
'Content-Type': 'application/json',
'Authorization': rtoken
}
var postData = {grant_type: 'authorization_code', code: req.query.code, redirect_uri: 'http://localhost:3000/nodejs-server/retrieveCode'} //Query string data
var options = {
method: 'POST', //Specify the method
body: postData,
url: 'http://localhost:4000/server/token',
json: true,
headers: headers
}
request(options
, function(error, response, body){
if(error) {
console.log(error);
} else {
//send a redirect uri and set-cookie header response
}
});
I tried using
res.redirect(302, "http://localhost:9000");
and it is able to redirect but I am not able to send the cookie with it as well
Any help is appreciated.
After lots of trials and errors and googling I was finally able to achieve my goal. In order to send a cookie with an expiry to the the redirect URL, I just added
const expires = body.exp.toUTCString();
res.cookie('id_token', body.id_token, { expires });
res.redirect(302, 'http://localhost:8080');
in express 4.16.3 , you must set
res.cookie()
before
res.redirect()
and it works for me, without error

Categories

Resources