I am trying to make a site where I fetch my favorite podcasts from Podbean API.
I have worked with fetch before, but those API's were much easier to setup and there was no auth part. So that's what I am struggling with.
So this is basically what I have used before :
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json))
From what I understand looking through various other threads :
I need to send get request with my client_id and client_secret to the get the access_token
From there on with access_token I get access and therefore can fetch date from the podcasts object.
I would appreciate any kind of guidance how to handle the auth part and obviously let me know if some of my thought processes are completely wrong.
Thanks in advance!
Ok, so I know the question is over 2 years old but I will still share my solution as I have struggled A LOT to understand how to use this API. This solution is only applicable if you are the owner of the podcast (or at least have access to the dev account).
The thing with the API is if you do not want to use auth2 (which I am still not sure how it works exactly with podbean), you have to fecth the data with a POST method not a GET and provide parameters (body and headers) and use HTTP basic authentication scheme. Their documentation is only in php but with some research you get what they are doing, the section applicable to this solution can be found here.
Here is the code:
const fetch = require("node-fetch");
const btoa = require('btoa');
const client_id = 'Enter your client id';
const client_secret = 'Enter your client secret';
const uri = 'https://api.podbean.com/v1/oauth/token';
// Base 64 encode client_id and client_secret to use basic authentication scheme
const auth = "Basic " + btoa(client_id + ':' + client_secret);
// Set POST request params
const options = {
method: 'POST',
body: 'grant_type=client_credentials',
headers : {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": auth
}
}
// Fetch
fetch(uri, options)
.then(res => res.json())
.then(data => console.log(data))
I hope this helps anyone who would try to use this API with javascript in the future.
Related
const access_token = ""
fetch('https://api.fitbit.com/1/user/-/profile.json', {
method: "GET",
headers: {"Authorization": "Bearer " + access_token}
})
.then(response => response.json())
//.then(json => console.log(json))
.then((out) =>
{
console.log(out.data);
document.getElementById('log').innerHTML=out.data;
})
hi, I have been trying to fetch wep API using the above js code. i have successfully fetched the data inside my debug console but now I want to fetch inside my firebase. Can someone help with this. For security purpose i removed the access token.
You code seems OK. Either your access token is not correct, or the JSON object you receive has no "data" key.
If I'm on the right page, it seems that you should use "out.user" instead of "out.data":
https://dev.fitbit.com/build/reference/web-api/user/get-profile/
make sure the out.data is string not an array or object.
I have constructed an API with AWS API Gateway that is used to call an AWS Lambda function to do some serverless computing.
The payload size that I am passing through is too great (over 10 mb) so I have looked into compressing the payload clientside through the Javascript library pako making use of its gzip method. This outputs a compressed Unit8Array that I then pass through the body and make an API request call with fetch().
Now for some reason, AWS API Gateway does not acknowledge this and simply fails. There is no log output in Cloudwatch for the POST method and there is no response returned that might indicate what went wrong.
I have worked through https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-gzip-compression-decompression.html , https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-enable-compression.html , https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-make-request-with-compressed-payload.html but neither of these tutorials have helped sadly.
I have even tried passing through the exact same example shown in the 3rd link (by generating a gzip of the JSON Object they construct) and I have been attempting my own tests and this still has not succeeded in being recognised. I do believe this means that I must have missed something in the AWS API Gateway but I am very unsure of what. If anyone has any thoughts, thanks in advance.
I have attempted (and others):
Introducing Binary-Media Types in the settings of the API Gateway
Using AWS Lambda Proxy Integration so the request is sent through. The issue here is that when trying to convert I am getting Type Errors in Python stating it expected a Binary Type not Str despite using the correct methods to convert.
var myHeaders = new Headers();
myHeaders.append("Content-Encoding", "gzip");
myHeaders.append("Content-Type", "application/json");
json = JSON.stringify({"Hello": "World"});
var zlibOpts = {
level: 6,
to: 'string'
};
data = pako.gzip(json);
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: data
};
fetch("https://<endpoint>", requestOptions)
.then(response => response.text())
.then(result => {
console.log(result);
})
.catch(error => console.log('error', error));
The Firebase Documentation has some useful curl operations but doesn't provide information regarding Cors, headers, and auth using JS Fetch. We are using a fetch-only solution as I am creating a client-based Firebase npm package where users might not have the firebase modules imported for several reasons, tree shaking, minified project, etc.
I imagine I need to pass on the Auth as a header, What about Cors and credentials?
Here is a crude example, is this sufficient? or are there other unforeseen issues?
const pushOptions = {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}
var dataAPI = await fetch(databaseUrl+`/test.json`,pushOptions)
.then(response => response.json())
Reference:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
https://firebase.google.com/docs/reference/rest/database#section-put
The documentation says you need to pass your Firebase ID in query parameter 'access_token' and not in any header. For example,
curl 'https://[PROJECT_ID].firebaseio/users/jack/name.json?access_token=CREDENTIAL'
But I ended up getting Unauthorized errors.
However, the Authenticate with an ID Token section in Firebase Auth REST API documentation says, "pass the ID token generated above as the auth=<ID_TOKEN> query string parameter". A sample curl request for the same would be:
curl 'https://[PROJECT_ID].firebaseio/users/jack/name.json?auth=CREDENTIAL'
This request worked as expected.
About CORS, this answer says,
Firebase uses a fully-permissive cross-origin resource sharing (CORS) policy, meaning that you can make requests to the Firebase servers from any origin. This is possible because Firebase does not use cookies or traditional sessions to govern which requests are authorized and which are not.
Here's a working example using Javascript fetch:
firebase.auth().onAuthStateChanged(async (user) => {
const token = await firebase.auth().currentUser.getIdToken()
const pushOptions = {
method: 'GET',
}
const reqURL = "https://[PROJECT_ID].firebaseio.com" + `/path.json?auth=${token}`
const dataAPI = await fetch(reqURL, pushOptions)
.then(response => response.json())
.then(res => console.log(res))
})
I just used the client SDK to get an ID Token quickly but it will work irrespective of from where the token is generated - client SDK or Auth REST API.
The REST API accepts the same Firebase ID tokens used by the client SDKs.
I am trying to automate the creation of a customer and adding a subscription. I can create the customer through Zapier but I don't really know how to use Python or Javascript to add a subscription or invoice. I can pass in all the data I need into variables like the plan Id and invoice amount. Does anyone have experience with this?
You can create a subscription request if you have the customer_id and plan_id. If you want to do this with Zapier, you can make a POST request using the fetch library in the Code (Javascript) app.
Pass the customer_id and plan_id in the Input Data.
Encode your secret key from Stripe in Base64. You can use this site to encode your key. Replace the encodedAPiKey in the code below and paste it into Zapier.
When this code step runs, it will create a subscription for the customer.
const url = 'https://api.stripe.com/v1/subscriptions';
//Replace with Base64 encoded secret key from Stripe.
const encodedApiKey = "c2tLsfdGVzdF9aYlFNVjdBSzE3Tm1sTVdMVjkwVWdWTz";
const headers = {
'Authorization': `Basic ${encodedApiKey}`,
'Content-Type': 'application/x-www-form-urlencoded'
};
fetch(`${url}?customer=${inputData.customer_id}&items[0][plan]=${inputData.plan_id}`, {method:'POST',
headers: headers
})
.then(res => res.json())
.then(json => {
console.log(json);
callback(null, json);
})
.catch(callback);
You will find documentation for this on Stripe here.
Note: If this code gets called multiple times, it will create multiple subscriptions for the customer. You might want to add some code to handle that or setup your Zaps in a way that this step doesn't get called twice.
Hope that helps!
I'm trying to get an OAuth token for the Reddit API following the Application Only OAuth instructions. My reddit app is an installed app, so for my grant_type I'm using https://oauth.reddit.com/grants/installed_client.
Currently I'm running a very short JS script to query the API and get a token:
const APP_ID = 'MY_APP_ID'
const DEVICE_ID = 'TRACKING_ID_20_TO_30_CHARS'
let form = new FormData()
form.append('grant_type', 'https://oauth.reddit.com/grants/installed_client')
form.append('device_id', DEVICE_ID)
fetch('https://www.reddit.com/api/v1/access_token', {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${btoa(`${APP_ID}:`)}`,
}),
body: form })
.then(handleResponse)
.then(function(data) {
console.log(data)
})
.catch(error => console.error(error))
function handleResponse(response) {
return response.json()
}
(Note: running the snippet as-is will give you a NetworkError because the APP_ID isn't a real one and I don't want to give mine out.)
The response I get is:
{
"error": "unsupported_grant_type"
}
When I try the same API request using a REST client I get back the expected response, so this makes me think that the problem is JavaScript-related. Since the grant_type matches what the instructions say I'm not really sure what to do with the error. I'm hoping someone else more experienced with OAuth will know what is going on here.
The problem was the use of the FormData object. In earlier stages of troubleshooting I found this answer on Reddit and decided to use it, but that didn't work for me.
It was submitting the data as multipart/form-data rather than application/x-www-form-urlencoded, which Reddit's OAuth server did not like. I wrote a helper function based on this answer which did the trick:
function urlEncode(data) {
let out = [];
for (let key in data) {
out.push(`${key}=${encodeURIComponent(data[key])}`);
}
return out.join('&')
}