I am trying to make an HTTP request to the Discord API, and I keep getting ECONNREFUSED as an error back. I am trying to access this route provided in the Discord API Documentation:
Get Global Application Commands GET/applications/{application.id}/commands
Fetch all of the global commands for your application. Returns an array of ApplicationCommand objects.
Using NodeJS, here is the relevant section of code:
const https = require('https')
const options = {
hostname: 'https://discord.com',
path: '/api/v8/applications/<myapplicationID>/commands', //with my actual appID
port: 443,
method: 'GET',
headers: {
Authorization: `Bot ${process.env.TOKEN}`
}
}
const req = https.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', error => {
console.error(error)
})
req.end()
I know this is a relatively simple question, but looking at the related questions didn't provide much insight, and as far as I can tell, I am adhering to the API's documentation. Any advice would be very helpful.
Thanks,
Dylan
So it was pretty stupid... The hostname field can't have 'https://'
Related
I have a Node.js application which currently allows the user to provision a Digital Ocean Droplet. However, I'm now trying to migrate over to IBM Cloud and instead want to provision a Virtual Server.
The issue I'm having is I have no experience working with APIs. Digital Ocean has its own NPM package acting as a wrapper over the Digital Ocean API bit I can't find an equivalent for IBM Cloud. I've been looking through the VPC API documentation and I have gone through the entire process of creating a Virtual Server using the terminal and I've successfully provisioned a Virtual Server.
Now, I'm trying to get these cURL requests to work in Node.js. I'm starting with just the simple GET images API to try and print the available images. The command looks like this:
curl -X GET "https://eu-gb.iaas.cloud.ibm.com/v1/images?version=2019-10-08&generation=1" \
-H "Authorization: *IAM TOKEN HERE*"
I've read over the Node HTTP documentation and so far I've converted this command to look like this:
const http = require('http')
const options = {
hostname: 'https://eu-gb.iaas.cloud.ibm.com',
port: 80,
path: '/v1/images?version=2019-10-08&generation=1',
method: 'GET',
headers: {
'Authorization': '*IAM TOKEN HERE*'
}
};
const req = http.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
req.end();
However, when I run the JS file, I get the following error:
problem with request: getaddrinfo ENOTFOUND https://eu-gb.iaas.cloud.ibm.com https://eu-gb.iaas.cloud.ibm.com:80
Can someone please explain to me the error, where I'm going wrong, and how I can fix this issue?
Many thanks in advance,
G
try as below:
const https = require('https');
const options = {
hostname: 'eu-gb.iaas.cloud.ibm.com',
port: 443,
path: '/v1/images?version=2019-10-08&generation=1',
method: 'GET',
headers: {
'Authorization': 'Bearer <IAM TOKEN HERE>'
}
};
const req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (e) => {
console.error(e);
});
req.end();
The protocol http:// shouldn't be included in the host field, also, it is recommended the use of https.
I would like to use the https library in node.js to send a request to this api:
https://rapidapi.com/dimas/api/NasaAPI?endpoint=apiendpoint_b4e69440-f966-11e7-809f-87f99bda0814getPictureOfTheDay
The given example on the RapidAPI website uses Unirest, and I would like to only use the https library. I've tried to write it like this:
const https = require('https');
var link = "https://NasaAPIdimasV1.p.rapidapi.com/getPictureOfTheDay";
var options = {host: "https://NasaAPIdimasV1.p.rapidapi.com/getPictureOfTheDay",
path: "/", headers: {"X-RapidAPI-Key": "---MY KEY(Yes, I've replaced it)---", "Content-Type": "application/x-www-form-urlencoded"}}
https.get(link, options, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
console.log(data);
});
}).on("error", (err) => {
console.log("https error 4: " + err.message);
});
But that returns the following response:
{"message":"Endpoint\/ does not exist"}
Thanks for any help
There are several mistakes.
First, you essentially pass URL in https twice - first as link param, second as combination of host and path properties for options param.
Second, your host is actually the full path - but it shouldn't be. In the end, looks like the library got confused and sent request to https://NasaAPIdimasV1.p.rapidapi.com/ instead.
Finally, this particular API requires using 'POST', not 'GET' method. That's actually mentioned in the documentation. That's why you have 'endpoint does not exist' error even on correctly formed request.
One possible approach is dropping link altogether, sending URL as part of options:
var options = {
host: 'NasaAPIdimasV1.p.rapidapi.com',
method: 'POST',
path: '/getPictureOfTheDay',
headers: {/* the same */}
};
https.request(options, (resp) => { /* the same */ }).end();
I've checked the NodeJS documentation but could not find any information on how to make the following code use HTTP2 to carry out the request:
const https = require('https');
const options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET'
};
const req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (e) => {
console.error(e);
});
req.end()
Is this simply not supported yet by even the most recent versions of NodeJS?
This is available in v9.9.0. You can take a look at HTTP2 in Nodejs. You can create a secureServer in HTTP2 if you want the whole thing. Else firing off requests using http2 is available too. You can take a look at this article for some ideas
You will not find a Node.js native way to:
how to make the following code use HTTP2 to carry out the request
Because, HTTP2 works completely different from HTTP1.1.
Therefore, the interface exported by the Node.js http2 core module is completely different, with additional features such as multiplexing.
To make HTTP2 request with the HTTP1.1 interface you can use npm modules, I personally coded and use:
http2-client
const {request} = require('http2-client');
const h1Target = 'http://www.example.com/';
const h2Target = 'https://www.example.com/';
const req1 = request(h1Target, (res)=>{
console.log(`
Url : ${h1Target}
Status : ${res.statusCode}
HttpVersion : ${res.httpVersion}
`);
});
req1.end();
const req2 = request(h2Target, (res)=>{
console.log(`
Url : ${h2Target}
Status : ${res.statusCode}
HttpVersion : ${res.httpVersion}
`);
});
req2.end();
I am trying to get an authentication token from an API.
the request is supposed to look like
POST /oauth2/token HTTP/1.1
Host: mysageone.ca.sageone.com
client_id=4b64axxxxxxxxxx00710&
client_secret=iNumzTxxxxxxxxxxhVHstrqWesH8tm9&
code=12a0f9c12cxxxxxxxxxxxxxxx92a48cc1f237ead&
grant_type=authorization_code&
redirect_uri=https://myapp.com/auth/callback
My current code keeps giving me status 400. I have tried to modify the headers but it doesn't work. i have also tried to make the required parameters part of the path using ?.
const http = require('http');
var options = {
hostname: 'app.sageone.com',
path: '/oauth2/token',
method: 'POST',
headers: {
"client_id":"xxxxx",
"client_secret":"xxxxx",
"code":"xxxxxx",
"grant_type":"authorization_code",
"redirect_uri":"https://some link"
}
};
console.log('in users file point 2');
var req1 = http.request(options, (res1) => {
console.log('statusCode:', res1.statusCode);
console.log('headers:', res1.headers);
console.log('message',res1.statusMessage);
res1.on('data', (d) => {
res.json(d);
});
});
req1.on('error', (e) => {
console.error('error starts here',e);
});
req1.end();
});
Looks to me like your problem is not with Node.js, but with your use of Sage One's api. This is the relevant documentation that might solve your problem.
From a quick glance it looks like you want to send a GET not a POST, and you should send those parameters in the URL. Here is the example URL they give:
https://www.sageone.com/oauth2/auth?response_type=code&client_id=4b64axxxxxxxxxx00710&redirect_uri=https://myapp.com/auth/callback
&scope=full_access
I've never used Sage One before, but that would match my experience with other OAuth APIs.
I am writing a React app using Node, Express, and Webpack. My problem is that my API calls' URLs always have a port number between the host and the path. It seems like most of the questions on this topic have more to do with routing than with external API calls.
I am much more comfortable with Request, but I got very frustrated trying to get it to play nicely with Webpack, so I turned to Node's http which I know less about.
Here is the method responsible for the API call:
getData() {
const self = this;
const url = "api.civicapps.org";
const options = {
"method": "GET",
"mode": "no-cors",
"host": url,
"path": "/restaurant-inspections/?restaurant_name=" + this.state.nameQuery,
"port": 8080,
"headers": {
"Access-Control-Allow-Origin": "http://localhost:3000"
}
}
const p1 = new Promise(function(resolve, reject) {
resolve(
http.request(options, function(res) {
res.setEncoding('utf8');
const body = {};
//This is clearly not ideal, but all I need right now is to get a response from the API
res.on('data', function(chunk) {
body.push(chunk);
});
return body;
}).end()
)
});
p1.then(function(data) {
console.log(data);
self.setState({
name: data.body
});
});
p1.catch(function(err) {
...
});
}
All I want to do is a simple test GET request to this API. Once that's working, I will be fine.
Thanks in advance.
It turns out setting the port to 80 and running with sudo solved the problem.
I know this topic is old, but I think it's good to share my experience with a similar issue in a Docker environment.
Since I was calling a service as hostname in my Node container, I didn't want the port to be set after the service name (e.g.: http://my-api-service/v1/users was called as http://my-api-service/v1/users:80).
I didn't reach to figure it out so I used Axios. It has its own definition types and can be used like that:
import Axios, { AxiosRequestConfig } from 'axios';
...
const options: AxiosRequestConfig = {
headers: { 'Authorization': 'Bearer ' + token, 'Accept': 'application/ld+json' }
};
Axios.get('http://my-api-service/v1/users', options)
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.error("Error: " + error.message);
})
.then(() => {
// always executed
// ...
});
This is the only way I found to solve that kind of errors with a Dockerized environment.