Kannel HTTP POST fails - node.js

This is my NodeJS (request-promise) for sending SMS via HTTP GET with SMS gateway Kannel:
var options = {
method: 'GET',
uri: 'http://127.0.0.1:13002/cgi-bin/sendsms',
qs: {
username: 'foo',
password: 'bar',
to: '127883327304',
from: '12488331359',
text: 'Hi
}
};
This works, but changing to HTTP POST fails.
var options = {
method: 'POST',
uri: 'http://127.0.0.1:13002/cgi-bin/sendsms',
form: {
username: 'foo',
password: 'bar',
to: '127883327304',
from: '12488331359',
text: 'Hi
}
};
Getting body: 'Authorization failed for sendsms' } }
Also able to get: body: 'Invalid content-type' } }
But the content-type is correct http form: application/x-www-form-urlencoded.
...and tried old school XML:
var xml = ' \
<?xml version="1.0"?>\
<message>\
<submit>\
<da><number>11021034235</number></da>\
<oa><number>11076034723</number></oa>\
<ud>Hello</ud>\
<from>\
<user>foo</user>\
<username>foo</username>\
<pass>bar</pass>\
<password>bar</password>\
</from>\
</submit>\
</message>\
';
var options = {
method: 'POST',
uri: 'http://127.0.0.1:13002/cgi-bin/sendsms',
body: xml,
headers: {'content-type': 'text/xml'}
};
but getting: body: 'Authorization failed for sendsms' } }
I'm lost on what to do, and HTTP GET doesn't work for long SMSes.

Tried
request({
url: 'http://127.0.0.1:13002/cgi-bin/sendota',
method: 'POST',
headers : {
'content-type': 'text/xml',
'X-Kannel-Username': 'foo',
'X-Kannel-Password': 'bar',
'X-Kannel-To': '1324422133',
'X-Kannel-From': '12023455750'
},
body: xml
}, 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.
});
Now I'm getting body: Unsupported content-type, rejected
but text/xml should be supported...

Related

Search Contacts with SendGrid API

https://sendgrid.api-docs.io/v3.0/contacts/search-contacts
I'm attempting to search for a contact as shown in SendGrids docs above. In the body section below I'd like to change the hard coded "andrew#gmail.com" to be a variable. Such as email = req.user.email; What is the correct way to do that? Just setting the variable and dropping in 'email' does not work.
var request = require("request");
var options = { method: 'POST',
url: 'https://api.sendgrid.com/v3/marketing/contacts/search',
headers:
{ 'content-type': 'application/json',
authorization: 'Bearer SG.key' },
body: { query: 'email LIKE \'andrew#gmail.com\' AND CONTAINS(list_ids, \'6bcc2d0c-ea17-41ba-a4a1-962badsasdas1\')' },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Twilio SendGrid developer evangelist here.
Try using string interpolation using back ticks (which, as an added bonus, means you don't have to escape your single quotes), like below:
const email = req.user.email;
const body = `email LIKE '${email}' AND CONTAINS(list_ids, '6bcc2d0c-ea17-41ba-a4a1-962badsasdas1')`;
const options = {
method: 'POST',
url: 'https://api.sendgrid.com/v3/marketing/contacts/search',
headers: {
'content-type': 'application/json',
authorization: 'Bearer SG.key'
},
body: { query: query },
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});

Error message "Empty entity body" returned after making LinkedIn API call

I'm trying to use the LinkedIn API to create a post using Node & Express with the node-fetch package to make the requests, however I always seem to get the error message "Empty entity body is not allowed for create method request" and I don't know how to resolve the error. I've included the body in the request but I guess not in the correct way. I also get the error code 400 so I know I'm doing something wrong, I'm just not sure what.
My questions are:
What is the entity body?
And how do I add it to my request?
function newPost(req, done) {
const id = "XXX";
const url = "https://api.linkedin.com/v2/ugcPosts";
const title = "Title title";
const text = "Text text";
const body = {
owner: `urn:li:person:${id}`,
subject: title,
text: {
text: text,
},
content: {
title: title,
},
};
const headers = {
'Authorization': `Bearer ${YYY}`,
'cache-control': 'no-cache',
'X-Restli-Protocol-Version': '2.0.0',
'x-li-format': 'json',
}
fetch(url, {
method: "POST",
headers: headers,
json: body,
}).then(res => res.json()).then(result => {
console.log(result);
const message = {
text: "Posted",
success: true,
}
done(message, "linkedin");
}).catch(err => {
console.log(err);
const message = {
text: "Failed",
success: false,
}
done(message, "linkedin");
});
}
As described in the to the doc, Post with JSON section, you should JSON.stringify the json body object, so try this:
fetch(url, {
method: "POST",
headers: headers,
json: JSON.stringify(body),
instead of:
fetch(url, {
method: "POST",
headers: headers,
json: body,
While calling fetch, you aren't passing body anywhere, you're passing json instead, which seems like a typo.
Existing code:
fetch(url, {
method: "POST",
headers: headers,
json: body,
}
What it should be instead:
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body),
}

axios content type not showing in request

var request = require('request');
var options = {
'method': 'POST',
'url': 'http://',
'headers': {
},
form: {
'username': '',
'password': ''
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
transforming this to axios request:
let data = qs.stringify({ 'username': '',
'password': '' })
const options = {
method: 'POST',data,
headers: { 'Content-Type': 'application/x-www-form-urlencoded'},
url: '',
};
response[0] = await Axios(options).then((res) => {
console.log("res",res)
return res.data
}
).catch((err) => {
console.log("err status", err.response.status)
return err.response.data
});
gives an error and the headers shown doesnt have the url encoded:
url: '',
method: 'post',
data: 'username=&password=',
headers: {
Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.19.2'
},
Why the content-type : url-encoded is not in the headers and only the Accept: 'application/json, text/plain, /' is showing.
You are not showing which error you are receiving but the way you are setting the Axios call seems right following the Axios documentation. So I suspect it is a problem on how you have set up your Node.js server.
If you are using Express.js v.4+, probably you forgot to set up in your server the directive to parse application/x-www-form-urlencoded content type as explained here in the official documentation.
app.use(express.urlencoded({ extended: true }))
If you are using the body-parser package you need to set up your server with:
app.use(bodyParser.urlencoded({extended: true}));

Axios login request: Unauthorized, request status code 401

I'm trying to get an authorization token by making a request to an api using axios:
axios({
method: 'post',
url: 'http://62.110.134.187/api/signin',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
auth: {
username: usr,
password: pwd
}
}).then(function (response) {
console.log(response)
}).catch(function (error) {
console.log('Error: ' + error)
})
I'm getting always status code 401(Unauthorized):
Error: Request failed with status code 401
Where I'm doing wrong?
The fact is that making the same request using python works fine:
payload = "username=%s&password=%s" % (usr,pwd)
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.request("POST", url_login, data=payload, headers=headers)
print(response.text)
data = response.json()
token = data["token"]
By sending username and password in auth: {} in axios, you are doing the basic-authentication, basically sending Authorization: basic <base64(user:pass)> header.
As per working python program, you need to send the username and password as part of the request body. You need to serialize the body params for url-encoded content type as well.
e.g.
const querystring = require('querystring');
axios({
method: 'post',
url: 'http://62.110.134.187/api/signin',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
data: querystring.stringify({
username: usr,
password: pwd
})
}).then(function (response) {
console.log(response)
}).catch(function (error) {
console.log('Error: ' + error)
})

make a post request with in node.js application

I've a node.js service with /api/authenticate endpoint. I can call this service successfully from POSTMAN with 'username' and 'password' as input (body parameters). How do I call the same services from another node.js server?
With postman I get,
body: {name: 'xxxxxx', password: 'xxxxxx' }
headers: { 'content-type': 'application/x-www-form-urlencoded',
host: 'xx.xx.xx.xx:xxxx',
connection: 'close',
'content-length': '0' }
POST /api/authenticate 200 1.336 ms - 72
Following is another nodejs application ... which makes a successful request call but doesn't have any body parameters (username and password) when it reaches to the authentication server api.
var my_http = require('http');
app.get('/makeacall', function(req, res) {
var output = '';
var options = {
body: { name: 'xxxxxx', password: 'xxxxxx' },
method: 'POST',
host: 'xx.xx.xx.xx',
port: 'xxxx',
path: '/api/authenticate',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
console.log('before request');
var req = my_http.request(options, function(response) {
console.log('response is: ' + response);
console.log('Response status code: ' + response.statusCode);
response.on('data', function(chunk) {
console.log('Data ..');
output += chunk;
});
response.on('end', function(chunk) {
console.log('Whole Data ..' + output);
});
});
req.on('error', function(err) {
console.log('Error: ' + err);
});
req.end();
console.log('444');
res.send({ message: 'View record message'});
});
From this nodejs application I get empty body on the server.
body: {}
headers: { 'content-type': 'application/x-www-form-urlencoded',
host: 'xx.xx.xx.xx:xxxx',
connection: 'close',
'content-length': '0' }
POST /api/authenticate 200 1.336 ms - 72
What am I missing? Any help is appreciated.
Using stock http library of NodeJS doesn't allow you to use that syntax.
Take a look at RequestJS as a much simpler solution. It will make your life a lot easier and allow you to use the syntax you want.
This is the solution to do it with stock Node.
https://nodejs.org/api/http.html#http_http_request_options_callback
Relevant Parts:
var postData = querystring.stringify({
'msg' : 'Hello World!'
});
And then, at the end:
// write data to request body
req.write(postData);
req.end();
But use a library unless you absolutely can't.
Are you trying to get the posted data from a form/etc?
Try using express.
npm install express -save
You can get posted data from a url with the ff:
app.post('*', function(request, response){
var post = {};
if(Object.keys(request.body).length){
for(var key in request.body){
post[key] = request.body[key];
console.log(key+'=>'+post[key];
}
}
});

Resources