I have my head in water with the new CoinMarketCap API.
Below is an example of a request in Node. How can I make a request in Angular?
Any suggestions?
Thanks.
/* Example in Node.js ES6 using request-promise, concepts should translate
to your language of choice */
const rp = require('request-promise');
const requestOptions = {
method: 'GET',
uri: 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest',
qs: {
start: 1,
limit: 5000,
convert: 'USD'
},
headers: {
'X-CMC_PRO_API_KEY': 'API_KEY_HERE'
},
json: true,
gzip: true
};
rp(requestOptions).then(response => {
console.log('API call response:', response);
}).catch((err) => {
console.log('API call error:', err.message);
});
As per the documentation found here you cannot perform this HTTP call from a web client:
Making HTTP requests on the client side with Javascript is currently prohibited through CORS configuration. This is to protect your API Key which should not be visible to users of your application so your API Key is not stolen. Secure your API Key by routing calls through your own backend service.
A solution would be to create your own back-end API. This API can then perform the HTTP call to Coinmarketcap. Your website then communicates with your custom made back-end API.
getAllCoinsListing() {
const httpOptions = {
headers: new HttpHeaders({
'X-CMC_PRO_API_KEY': 'API_KEY_HERE'
})
};
return this.http.get(this.apiUrl, httpOptions);
}
Related
Spotify Oauth2 Docs - Client Credential Flow
I asked a similar question, and I was able to get the code running in google apps script (javascript). I am using Client Credential Flow. However, I tried to recreate this code in Nodejs. When running this code, I receive a server error.
error: "server_error"
This is the problem code in Nodejs
const defaultConfig = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
// this encodes the app_id and api_key into a base64 string like the documentation states
'Authorization': `Basic ${btoa(spotify.API_ID + ':' + spotify.API_KEY)}`
},
body: JSON.stringify({
'grant_type': 'client_credentials',
})
};
// this function is wrapped in a list titled, "apiSettings" with other functions. I just included the authorization function here:
const apiSettings = {
getSpotifyAuthorizeToken: async () => {
const endpoint = "https://accounts.spotify.com/api/token";
return await (await fetch(endpoint, defaultConfig)).json();
},
};
I got this similar code to work in google apps script with no problems.
Could the server error be a result of me running Nodejs on a "localhost:xxxx"? The documentation states that, "The Client Credentials flow is used in server-to-server authentication."
if this is not the case, could you provide a working
Spotify API OAUTH2 Server Error Response when requesting token
From your previous question, I would like to propose the following sample scripts.
Sample script 1:
If you want to convert the script of this answer to Node.js and node-fetch, how about the following script?
const spotify = { API_ID: "API_ID", API_KEY: "API_KEY" }; // Please set your client ID and client secret.
const buf = Buffer.from(spotify.API_ID + ":" + spotify.API_KEY);
const para = new URLSearchParams();
para.append("grant_type", "client_credentials");
const defaultConfig = {
method: "POST",
headers: { Authorization: `Basic ${buf.toString("base64")}` },
body: para,
};
const apiSettings = {
getSpotifyAuthorizeToken: async () => {
const endpoint = "https://accounts.spotify.com/api/token";
return await (await fetch(endpoint, defaultConfig)).json();
},
};
Sample script 2:
If you want to convert the script of this answer to Node.js and node-fetch, how about the following script?
const spotify = { API_ID: "API_ID", API_KEY: "API_KEY" }; // Please set your client ID and client secret.
const para = new URLSearchParams();
para.append("grant_type", "client_credentials");
para.append("client_id", spotify.API_ID);
para.append("client_secret", spotify.API_KEY);
const defaultConfig = {
method: "POST",
body: para,
};
const apiSettings = {
getSpotifyAuthorizeToken: async () => {
const endpoint = "https://accounts.spotify.com/api/token";
return await (await fetch(endpoint, defaultConfig)).json();
},
};
Reference:
node-fetch
I would like to connect with the Stripe API using a https call using the https library.
var https = require('https');
I have gotten the secret key and publishable key and put it inside a object:
var stripe = {
secret_key: 'secret_key_given_in_the_dashboard',
publishable_key: 'publishable_key_given_in_the_dashboard'
}
I am now in the part of creating the requestDetail object:
var requestDetails = {
'protocol' : 'https:',
'hostname' : 'api.stripe.com',
'method' : 'POST', //WHICH OF POST GET PUT DELETE SHOULD I USE?
'path' : '???????????????????????',// WHICH ENDPOINT SHOULD I USE?
'auth' : '???????????????????????',// SHOULD I USE THE SECRET AND PUBLISHABLE KEY HERE?
'headers' : {
'Content-Type' : 'application/x-www-form-urlencoded',
'Content-Length' : Buffer.byteLength(stringPayload)
}
};
I plan to make use of the requestDetails object in the call using https:
var req = https.request(requestDetails, function(res){
// Grab the status of the sent request
var status = res.statusCode;
//Callback successfully if the request went through
if(status == 200 || status == 201) {
callback(false);
} else {
callback('Status code returned was ' + status);
}
});
Where and how should I use the secret key and publishable key in order to make a call to the stripe API?
Which endpoint?
Which method (POST, GET, PUT,or DELETE)?
I would like to eventually create a order and pay through the STRIPE api.
But for now just any authenticated call through the stripe api will do as I need a sample format that works....
I'm not too sure where to add the secret key and publishable key....
You should install official stripe package (source: https://github.com/stripe/stripe-node), require the package and authenticate it using your secret key ( example from the github docs):
const stripe = require('stripe')('your_stripe_secret_key');
stripe.customers.create({
email: 'customer#example.com',
})
.then(customer => console.log(customer.id))
.catch(error => console.error(error));
The package is an abstraction to make the API requests for you.
More docs: https://stripe.com/docs/api?lang=node
However, if you want to use the https directly for Stripe API requests, which is not recommended, you can check the docs and examples for using the cURL, since it shows the endpoints for each example.
https://stripe.com/docs/api/authentication?lang=curl
try using fetch, 'Authorization': 'Bearer ' + sk.
My working example of retrieving a customer based on the customer_id:
const url = `https://api.stripe.com/v1/customers/${stripe_customer_id}`;
return await fetch(url, {
method: "get",
headers: {
"Content-Type": "application/json",
'Authorization': 'Bearer ' + sk,
}
})
.then(function(response) {
return response.json();
})
.then(function(response) {
// console.log(response);
return response;
});
};
The API I am trying to consume is from a third party and it blocks Cross-Origin, so I can not consume it with jquery, nor javascript ... So I had to create a script in nodejs to consume this API ...
I would like to know how do I consume this data that nodejs got from the API to my frontend, using javascript?
Remembering that this nodejs is in a separate file from my frontend and running from another server.
var request = require("../../node_modules/request");
var options = { method: 'GET',
url: 'https://....apimanagement.us2.hana.ondemand.com/bot/v1/...',
qs: { Shop: '..'', PeriodoAte: '...' },
headers:
{ 'postman-token': '822e513f-da5e-4a0b-b403-1dd8fa46e86f',
'cache-control': 'no-cache',
authorization: 'Basic .........',
apikey: '....',
'content-type': 'application/json' },
json: true };
request(options, function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
console.log('body:', body); // Print the HTML for the Google homepage.
});
One path would be:
pick a node framework (Express, Hapi, ...) lets pick Hapi for this example
read the getting started guide https://hapijs.com/tutorials/getting-started
learn about promises or go through callback hell
end up with something like this for testing
'use strict';
const Hapi = require('hapi');
const rp = require('request-promise');
const server = Hapi.server({
port: 3000,
host: 'localhost'
});
server.route({
method: 'GET',
path: '/',
handler: (request, h) => {
const options = {
method: 'GET',
uri: 'https://./..',
qs: {Shop: '..', PeriodoAte: '...'},
headers: {
'postman-token': '822e513f-da5e-4a0b-b403-1dd8fa46e86f',
'cache-control': 'no-cache',
authorization: 'Basic .........',
apikey: '...',
'content-type': 'application/json'
},
json: true
};
return rp(options).catch(e => {
console.log(`api call failed ${e}`);
return 'fail';
})
}
});
const init = async () => {
await server.start();
console.log(`Server running at: ${server.info.uri}`);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
now you can start it with node and visit 'localhost:3000/'
read more, try more
read about node production mode and hosting
Something like that, hope it helps a bit
EDIT: //
to consume on client just use for example jquery to fetch the route served with the code above
Here is some client example as requested in the comments:
If you are serving your html from another location, not the hapi api, you will need to enable cors in the HapiJS route.
server.route({
method: 'GET',
path: '/',
config: {
cors: {
origin: ['*'],
additionalHeaders: ['cache-control', 'x-requested-with']
}
},
Then one way to consume this endpoint would be jquery
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<input type="button" id="Button" value="Fetch"/>
<div id='main'></div>
<script type="text/javascript">
$(document).ready(function () {
$('#Button').click(() => {
$.ajax({
url: "http://localhost:3000/info", success: (result) => {
$("#main").text(result);
}
});
});
});
</script>
</body>
</html>
You need a web server listening for requests in order to communicate your frontend with your backend (Node.js). You could use Express if you want something simple. You could also use a JavaScript framework, there are many (Sails.js would be a good option to get started fast).
If you can't install Node.js in your server, another option would be using AWS Lambda to quickly create an API that you can consume from your frontend through an HTTP request.
I want to make GET request to scrape some data thru a proxy server that is randomly generated using the gimmeproxy.com free API.
I am able to get the proxy ip/port and am using
'https-proxy-agent' to setup the agent with the proxy data.
Whenever I try to call any website I always get
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>405 Method Not Allowed</title>
</head><body>
<h1>Method Not Allowed</h1>
<p>The requested method CONNECT is not allowed for the URL
/index.html.en.backup.</p>
</body></html>
Here is my node script:
const request = require('request'), HttpsProxyAgent = require('https-proxy-agent');
generateRandomProxy(function(proxy){
var agent = new HttpsProxyAgent({
proxyHost: proxy.proxyHost,
proxyPort: proxy.proxyPort
});
request({
uri: "http://example.com",
method: "GET",
agent: agent,
timeout: 5000,
}, function(error, response, body) {
console.log(body);
});
})
function generateRandomProxy(cb){
request.get(' https://gimmeproxy.com/api/getProxy?get=true&cookies=true&country=US',{json:true},function(err,res){
if(!err){cb({
proxyHost: res.body.ip,
proxyPort: res.body.port
})}
else{console.log('problem obtaining proxy')}
})
}
So my question: How can I route my request thru the proxy and then get a returned body that is valid?
As you see now I keep getting the 405 Method Not Allowed
Thank you for any assistance.
Edit: Just found some GimmeProxy wrapper for Node.js: gimmeproxy-request.
It claims to automatically re-route requests through another proxy when one fails.
With this module code would look like this:
const setup = require('gimmeproxy-request').setup;
const request = require('gimmeproxy-request').request;
setup({
api_key: 'your api key',
query: 'get=true&cookies=true&country=US&supportsHttps=true&maxCheckPeriod=1800&minSpeed=10', // additional gimmeproxy query parameters
retries: 5, // max retries before fail
test: (body, response) => body.indexOf('captcha') === -1 && response.statusCode === 200 // test function
});
request('https://example.com', {
timeout: 10000 // additional request parameters, see https://github.com/request/request
},
function(err, res, body) {
console.log('err', err)
console.log('res', res)
console.log('body', body)
process.exit()
});
I guess the issue is that you sometimes get not an https proxy from Gimmeproxy, while 'https-proxy-agent' expects https proxy only.
To fix it, use the proxy-agent package of the same author and pass curl field of GimmeProxy response. It will select correct proxy agent implementation.
The following code works for me:
const request = require('request'), ProxyAgent = require('proxy-agent');
generateRandomProxy(function(proxy){
console.log(proxy);
var agent = new ProxyAgent(proxy.curl);
request({
uri: "https://example.com",
method: "GET",
agent: agent,
timeout: 5000,
}, function(error, response, body) {
console.log(error);
console.log(body);
});
})
function generateRandomProxy(cb){
request.get('https://gimmeproxy.com/api/getProxy?get=true&cookies=true&country=US&supportsHttps=true&maxCheckPeriod=1800&minSpeed=10',{json:true},function(err,res){
if(!err){cb(res.body)}
else{console.log('problem obtaining proxy')}
})
}
Note: If you want to call https websites, you should query for proxies with https support using supportsHttps=true parameter. Also it makes sense to query for fresh proxies with maxCheckPeriod=1800 parameter. Setting minSpeed=10 also helps:
https://gimmeproxy.com/api/getProxy?get=true&cookies=true&country=US&supportsHttps=true&maxCheckPeriod=1800&minSpeed=10
My RESTful service allows batching requests.
I'm trying to combine requests into one batch with help of Fetch API:
let req1 = {
url: "/cups/count",
options: {
method: 'GET',
headers: {
'Content-Type': 'application/http'
}
}
},
req2 = {
url: "/spoons/count",
options: {
method: 'GET',
headers: {
'Content-Type': 'application/http'
}
}
},
authToken = "Bearer my_token123",
batchUrl = "http://something.com/batch",
options = {
method: 'POST',
headers: {
'Authorization': authToken,
'Content-Type': 'multipart/mixed'
},
body: {req1, req2}
};
return fetch(batchUrl, options)
.then(response => response.json())
.then(items => dispatch(batchSuccess(items)))
.catch((err) => {
console.log(err)
});
However it returns an error - bad request. I suppose I may combine HTTP requests in wrong way.
Is there simpler way of doing this?
Where in Network Chrome Dev Tools can I see nested HTTP requests?
Your code does not work because it does not follow multipart/mixed request format:
In Content-Type header, there is no boundary information.
The child requests are not divided by boundary, instead they will be sent as plain text of req1 & req2 object.
In order to send valid multipart/mixed request, there is a node.js module batchelor. According to the introduction page, its usage is pretty simple.
If you want to send multipart/mixed request from browser, you can use build tool (gulp, webpack etc.) to compile batchelor into something like "batchelor-compiled.js" and import it in HTML.
For developer tool, I didn't find anything in Chrome, but the child requests are visible in Firefox debug window's "Params" tab.
Here is an example of a batch request using the Fetch API with the Gmail Batch REST API.
This will get the content of several messages at once.
const response = await fetch("https://www.googleapis.com/batch/gmail/v1", {
headers: {
"Content-Type": "multipart/mixed; boundary=batch_boundary",
Authorization: "Bearer <access_token>",
},
method: "POST",
body: `--batch_boundary
Content-Type: application/http
Content-ID: 1
GET /gmail/v1/users/me/messages/{message-id-1}
--batch_boundary
Content-Type: application/http
Content-ID: 2
GET /gmail/v1/users/me/messages/{message-id-2}
--batch_boundary--`,
});
console.log(await response.text());