Node Javascript Tiny CC - javascript

I am trying to use the tiny.cc REST API from Node, but seem to be hitting an issue since the Server always responds with a message 'Missing input parameters'.
var message = JSON.stringify({
"urls": [
{
"long_url": "http://example.com",
}
]
});
var https_options = {
host: 'tinycc.com',
path: '/tiny/api/3/urls/',
port: 443,
method: 'POST',
headers: {
'Authorization': 'Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'Content-Length': message.length
}
}
var req = https.request(https_options,res => {
var msg = '';
res.on('data',d => msg += d);
res.on('end',() => {
console.log('end',JSON.parse(msg));
});
});
req.on('error',e => console.log('tinyURL error',e));
req.write(message);
req.end();
The response is always
{
error: {
code: 1305,
message: 'Missing input parameters',
details: ''
},
version: '3.1'
}

I don't know which library are you using for making the API call, but I think you will be better using request and including your payload as the body on your post request rather than using the more manual method of writing to the request.
var message = {
"urls": [
{
"long_url": "http://example.com",
}
]
};
var options = {
host: 'tinycc.com',
path: '/tiny/api/3/urls/',
port: 443,
method: 'POST',
body: message,
json: true,
headers: {
'Authorization': 'Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'Content-Length': message.length,
"Content-Type": "application/json"
}
}
request(options, console.log)

Related

Why am I getting the error "'request' is not defined"?

I'm trying to create an app with the Spotify API, but can't seem to get it to work. The error I'm getting is that 'request' is undefined and I've replaced it with JQuery too and that doesn't work either. Can anyone tell me why I might be getting that error and how to fix it? Should I be running it inside node.js in cmd?
var client_id = '?';
var client_secret = '?';
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
headers: {
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64'))
},
form: {
grant_type: 'client_credentials'
},
json: true
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var token = body.access_token;
}
else {
console.log(JSON.stringify(error))
}
});
The spotify documentation is out of date, as request is deprecated, and should no longer be used.
Instead, you can make a request with built-in Node.js libraries, as mentioned in the documentation.
It should be run with node.js, i.e. node <filename>
const https = require('https')
const client_id = 'CLIENT_ID'
const client_secret = 'CLIENT_SECRET'
const reqBody = JSON.stringify({
grant_type: 'client_credentials'
})
const authOptions = {
hostname: 'accounts.spotify.com',
port: 443,
path: '/api/token',
method: 'POST',
headers: {
'Authorization': 'Basic ' + (new Buffer.from(client_id + ':' + client_secret).toString('base64')),
'Content-Type': 'application/json',
'Content-Length': reqBody.length
}
}
const req = https.request(authOptions, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
process.stdout.write(d)
})
})
req.write(reqBody);
req.end();

POST with custom headers using Request Library

I am trying to make a POST request to Expo's servers using the request library for JS.
Expo requires that certain headers be added, and so I went ahead and added them in a dictionary called headers.
expoPushURL = "https://exp.host/--/api/v2/push/send";
headers = {
"accept": "application/json",
"accept-encoding": "gzip, deflate",
"content-type": "application/json"
};
data = JSON.stringify({
"to": "ExponentPushToken[myDeviceToken]",
"sound": "default",
"title": "hello",
"body": "Hello world!"
});
options = {
url: expoPushURL,
headers: headers,
method: "POST",
body: data,
json: true
};
request(options, function (error, response, body) {
console.log("Response from request: ",response);
console.log("Error from request: ", error);
});
The callback is returning an undefined object. The request module has been imported without any problems. What am I doing wrong?
I am getting this error message:
Error from request: { Error: getaddrinfo ENOTFOUND exp.host exp.host:443
at errnoException (dns.js:28:10)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:76:26)
code: 'ENOTFOUND',
errno: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'exp.host',
host: 'exp.host',
port: 443 }
These "settings" or parameters work perfectly fine when I use curl or Python's requests library, but I need this solution to be in JS. With that said, I am sure that means there is something wrong with my code.
EDIT: The related curl would look like this:
curl -H "Content-Type: application/json" -X POST https://exp.host/--/api/v2/push/send -d '{
"to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
"title":"hello",
"body": "world"
}'
You do not have problem with headers, they are working correctly, something else is missing. What is your curl?
I have run your code against my dummy server, which returns in body all interesting values that he accepted. With this code
const expoPushURL = "http://localhost:3099";
const headers = {
"accept": "application/json",
"accept-encoding": "gzip, deflate",
"content-type": "application/json"
};
const data = JSON.stringify({
"to": "ExponentPushToken[myDeviceToken]",
"sound": "default",
"title": "hello",
"body": "Hello world!"
});
const options = {
url: expoPushURL,
headers: headers,
method: "POST",
body: data,
json: true
};
import * as request from 'request';
request(options, function (error, response, body) {
console.log(body.received);
});
I got this response
{ body: '"{\\"to\\":\\"ExponentPushToken[myDeviceToken]\\",\\"sound\\":\\"default\\",\\"title\\":\\"hello\\",\\"body\\":\\"Hello world!\\"}"',
method: 'POST',
headers:
{ accept: 'application/json',
'accept-encoding': 'gzip, deflate',
'content-type': 'application/json',
host: 'localhost:3099',
'content-length': '115',
connection: 'close' },
url: '/' }
If someone would be just interested, the server I am using is having this code
const http = require('http');
const _ = require('lodash');
http.createServer((request, response) => {
const { headers, method, url } = request;
let body = [];
request.on('error', (err) => {
console.error(err);
}).on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
let bodyToSend = JSON.stringify({
alwaysHere: 'Always here',
received: {
body,
method,
headers,
url,
}
});
if (body) {
body = JSON.parse(body);
if (body && _.isObject(body.control)) {
const control = body.control;
if (_.isNumber(control.statusCode)) {
response.statusCode = control.statusCode;
}
if (_.isArray(control.headers)) {
control.headers.forEach(header => {
response.setHeader(header.name, header.value);
});
}
if (_.isString(control.body)) {
bodyToSend = control.body;
}
}
}
if (!response.hasHeader('content-type')) {
response.setHeader('Content-Type', 'application/json');
}
response.write(bodyToSend); // write a response to the client
response.end(); // end the response
});
}).listen(3099);

node JS HTTP request does nothing using http request

I'm trying to send http post request using native node js http request.
I'm using the following code but nothing happens:
var http = require('http');
var options = {
hostname: '192.168.1.134',
port: '8082',
path: '/api',
method: 'POST',
headers: {'content-type': 'application/json',
'cache-control': 'no-cache'}
};
callback = function(response)
{
var result = [];
response.on('data', function (chunk)
{
result.push(chunk);
});
response.on('end', function ()
{
console.log("LOCAL END" + result);
});
}
var req = http.request(options, callback);
req.write(JSON.stringify(
{
customer: 'customer',
deviceIndicator: 'id',
userId: 'id2',
lastVersion: 999
}), 'utf8' ,
function(data)
{
console.log('flushed: ' + data);
});
req.end();
console.log(" - trying to post to example - done" );
But if i'm adding the following dummy calls i'm getting an answer from my local server as expected:
var options1 = {
hostname: 'www.google.com',
port: '80',
path: '/',
headers: {'cache-control': 'no-cache'}
};
callback1 = function(response1) {
var str = ''
response1.on('data', function (chunk) {
str += chunk;
});
response1.on('end', function () {
console.log("GOOGLE END" + str);
});
}
var req1 = http.request(options1, callback1);
req1.end();
console.log("sent to google - done");
What am i doing wrong?
Make sure 192.168.1.134:8082 is reachable and responding (using a browser, curl or wget) then try adding a content-length header:
var http = require('http');
var payload = JSON.stringify({
customer: 'customer',
deviceIndicator: 'id',
userId: 'id2',
lastVersion: 999
});
var options = {
hostname: '192.168.1.134',
port: 8082,
path: '/api',
method: 'POST',
headers: {
'content-length': Buffer.byteLength(payload), // <== here
'content-type': 'application/json',
'cache-control': 'no-cache'
}
};
var req = http.request(options, function(response) {
var result = [];
response.on('data', function(chunk) {
result.push(chunk);
});
response.on('end', function () {
console.log('LOCAL END' + result);
});
});
req.write(payload);
req.end();
Eventually, I discovered that the problem was with the device itself which had some kind of problem..
When sent http request to a direct ip address nothing happened but when sent to an address that need dns server it is working...
Unfortunately, I don't have any additional info about this bug...

Why is my callback not working with the axios library?

I have a small Spotify app that I am trying to convert to use the axios http library. I am having an issue with the callback when logging in. Up to this point I have been using request like is in all of the Spotify documentation. Everything works fine with request, but even though everything looks the same with axios, I get a 500 Internal Server Error. Here is my code to make the http request:
var authOptions = {
method: 'POST',
url: 'https://accounts.spotify.com/api/token',
form: {
code: code,
redirect_uri: REDIRECT_URI,
grant_type: 'authorization_code'
},
headers: {
'Authorization': 'Basic ' + (new Buffer(CLIENT_ID + ':' + CLIENT_SECRET).toString('base64'))
},
json: true
};
axios(authOptions).then(res => {
console.log(res)
})
I can pass the same authOptions object to the request library everything works fine. Here is my request from axios logged out to the console.
{
method: 'POST',
url: 'https://accounts.spotify.com/api/token',
form:
{ code: 'changedthecode',
redirect_uri: 'http://localhost:8888/callback',
grant_type: 'authorization_code' },
headers: { Authorization: 'Basic changedthecode=' },
json: true,
timeout: 0,
transformRequest: [ [Function] ],
transformResponse: [ [Function] ],
withCredentials: undefined
}
And here is my response with the axios library:
{ data: { error: 'server_error' },
status: 500,
statusText: 'Internal Server Error',
headers:
{ server: 'nginx',
date: 'Fri, 04 Dec 2015 14:48:06 GMT',
'content-type': 'application/json',
'content-length': '24',
connection: 'close' },
config:
{ method: 'POST',
headers: { Authorization: 'Basic changedthecode' },
timeout: 0,
transformRequest: [ [Function] ],
transformResponse: [ [Function] ],
url: 'https://accounts.spotify.com/api/token',
form:
{ code: 'changedthecode',
redirect_uri: 'http://localhost:8888/callback',
grant_type: 'authorization_code' },
json: true,
withCredentials: undefined }
}
The only option that I didn't know about from axios was withCredentials, and it didn't work when it was set to false or true. What else am I missing?
The problem is that I was posting a form and was not encoding it when going across the wire and I was not setting the Content-Type. I changed my authOptions to:
var authOptions = {
method: 'POST',
url: 'https://accounts.spotify.com/api/token',
data: querystring.stringify({
grant_type: 'refresh_token',
refresh_token: refreshToken
}),
headers: {
'Authorization': 'Basic ' + (new Buffer(CLIENT_ID + ':' + CLIENT_SECRET).toString('base64')),
'Content-Type': 'application/x-www-form-urlencoded'
},
json: true
};
and everything worked fine.

How to resolve NODE.Js HTTP POST "ECONNRESET" Error

I have this function and the below data which is passed into this function returns a ECONNRESET, socket hang up error. However, when the discountCode array is reduced to like only 10 objects, it can POST without any problem.
What could the cause for this problem? I tried to do multiple req.write() by segmenting the data in Buffer, however that doesn't work out well. Any NodeJs ninja could give some insights to this problem?
createObj: function(data, address, port, callback) {
//console.log('Create Reward: '+JSON.stringify(data));
var post_data = JSON.stringify(data);
var pathName = '/me/api/v1/yyy/'+data.idBusinessClient+'/newObj';
//
var options = {
hostname: address,
port: port,
path: pathName,
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Accept': 'application/json',
'Accept-Encoding': 'gzip,deflate,sdch',
'Accept-Language': 'en-US,en;q=0.8'
}
};
// http call to REST API server
var req = restHttp.request(options, function(res) {
console.log('HTTP API server PUT Reward response received.');
var resData = '';
res.on('data', function(replyData) {
// Check reply data for error.
console.log(replyData.toString('utf8'));
if(replyData !== 'undefined')
resData += replyData;
});
res.on('end', function() {
//<TODO>Process the data</TODO>
callback(JSON.parse(resData));
});
});
req.write(post_data);
req.end();
console.log('write end');
req.on('close', function() {
console.log('connection closed!');
});
req.on('error', function(err) {
console.log('http request error : '+err);
callback({'error':err});
throw err;
});
req.on('socket', function(socket) {
console.log('socket size:'+socket.bufferSize);
socket.on('data', function(data) {
console.log('socket data:'+data);
});
});
}
]}`
I had the same problem and was able to resolve it by adding a Content-Length header:
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': Buffer.byteLength(post_data),
'Accept': 'application/json',
'Accept-Encoding': 'gzip,deflate,sdch',
'Accept-Language': 'en-US,en;q=0.8'
}
However, I still have no clear idea why a missing Content-Length header causes such a trouble. I assume it's some kind of weirdness in the internal Node.js code. Maybe you can even call it a bug, but I'm not sure about that ;)
PS: I'm absolutely interested more information about the cause of this problem. So please leave a comment if you have any idea...
When you change the content of response for sure you need also to update on header the content length:
headers: {
...
'Content-Length': Buffer.byteLength(post_data),
...
}
But i run on this problem also when i try to make multiple request and seems that this is not well managed on different library so a workaround that i have found if this problem persist is to add on headers:
headers: {
...
connection: 'Close'
...
}
So if you are making request on different servers.. this close the connection after finish the process. This worked for me in net, node-http-proxy.
If Express and http-proxy-middleware is used to make the POST call, and some body parser middleware is used like express.json(), the request interceptor fixRequestBody must be used (more info). Otherwise the POST call will hang with the ECONNRESET error.
const express = require('express');
const { createProxyMiddleware, fixRequestBody } = require('http-proxy-middleware');
const app = express();
app.use(express.json());
app.post(
'/path',
createProxyMiddleware('/path', {
target: API_URL,
changeOrigin: true,
pathRewrite: (path, req) => `/something/${req?.body?.someParameter}`,
onProxyReq: fixRequestBody // <- Add this line
});
Had the same problem. The solution for me was to append it to the proxy for it to work. If you're not using a proxy, you can probably just append it to the post request itself.
With proxy:
import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
import logger from './logger';
// setup routes
server.get('/isAlive', (req, res) => res.send('Alive'));
server.get('/isReady', (req, res) => res.send('Ready'));
server.use(express.static(path.join(__dirname, '../build')));
const restream = (proxyReq, req, res, options) => {
if (req.body) {
let bodyData = JSON.stringify(req.body);
proxyReq.setHeader('Content-Type', 'application/json');
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
proxyReq.write(bodyData);
}
};
server.use(
'/api',
createProxyMiddleware({
target: 'http://your-backendUrl-api',
onProxyReq: restream,
changeOrigin: true,
proxyTimeout: 30000,
secure: true,
logLevel: 'info',
onError: (err, req, res) => {
logger.error('error in proxy', err, req, res);
},
})
);
E.g without proxy:
import axios, { AxiosResponse } from 'axios';
const api = axios.create({
baseURL: '/api/....',
timeout: 35000,
withCredentials: true,
headers: { Pragma: 'no-cache', 'Cache-Control': 'no-cache' },
validateStatus: (status) => status < 400,
});
const response = await api.post(
`/somepath/${exampleInjectedId}/somepathToRestAPI`,
{
...payload
},
{
baseURL: '/api/...',
timeout: 35000,
withCredentials: true,
headers: {
Pragma: 'no-cache',
'Cache-Control': 'no-cache',
'Content-Length': Buffer.byteLength(
JSON.stringify({
...payload
})
),
},
validateStatus: (status) => status < 400,
}
);

Categories

Resources