I am attempting to use request to POST to FastSpring's API for updating subscriptions for my customers. I am able to GET subscriptions without problem, but when it comes to POST, I cannot seem to get it to work.
Here is my code:
var options = {
method: 'POST',
url: 'https://api.fastspring.com/subscriptions',
headers: {
'Authorization': auth,
'User-Agent': 'request',
'Content-Type': 'application/json'
},
formData : {
'subscriptions': [
{
"subscription": subscriptionId,
"quantity": newQty,
"product": product,
"prorate": true
}
]
}
};
request.post(options, function (error, response, body) {
_logger.error('Fastspring API response: ' + JSON.stringify(response));
_logger.error('Fastspring API error: ' + JSON.stringify(error));
_logger.error('Fastspring API body: ' + JSON.stringify(body));
if (!error && response.statusCode === 200) {
res.status(200).send(JSON.parse(body));
} else {
_logger.error('Fastspring API Error: ' + error);
res.status(500).send({ 'error': error});
}
});
The result of attempting the POST results in the following error:
TypeError: source.on is not a function
I looked it up and saw that the reason why it was failing is that request cannot accept the formData I'm sending. Problem is that without it, I cannot POST to FastSpring's API (I get the error message "subscriptions not found." if I send anything else).
My question is this: Can I send my formData in any way that will be accepted by request? I've looked this issue up on the issues page of request and couldn't find a satisfactory answer.
Are you trying to pass some JSON data? Usually that kind of data are written in body not in formData.
Try something like this:
var myreq = request.post(...)
myreq.write(myJsonData);
myreq.end();
Related
I have a Spring Rest backend setup as well as a react client. Both are setup on different local ports. I am trying to send a simple request from my React client using a fetch call to my spring rest api.
When sending the POST request using Postman, the API responds as expected.
When sending the request from the React client I receive the following 400 error:
org.springframework.http.converter.HttpMessageNotReadableException:
Required request body is missing: public
org.springframework.http.ResponseEntity<?>
I have done the following:
Disabled CSRF on my spring application.
Set global CORS config to accept all requests.
Ensured on multiple occasions that the request body is correct and identical to that sent via Postman.
Here is my Fetch request from react client:
fetch(API_BASE_URL + '/api/auth/signin', {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json;charset=UTF-8',
'Access-Control-Request-Method': 'POST'
}),
body: {
username: this.state.uname,
password: this.state.password,
}
}).then(
function (response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function (data) {
let json = JSON.parse(data);
let token = json.tokenType + " " + json.accessToken;
localStorage.setItem(ACCESS_TOKEN, token);
alert('successfully saved token:' + token);
});
}
)
.catch(function (err) {
console.log('Fetch Error :-S', err);
});
For those interested:
The data passed in payload was of an incorrect format. While this may not appear logical, creating a variable as so:
let payload = {
username: this.state.username,
password: this.state.password,
};
And passing that as the body to fetch seems to work.
Hopefully this may help others facing the same problem..
My goal is to use client credentials and Graph subscriptions for messages, for several users in my tenant.
I'm successfully getting the access token via client credentials, and can use it with Graph for things like creating calendar events for multiple users.
However, when I use the access token to create a Graph subscription for messages, I get a failure of "Unsupported segment type".
Does graph support client credentials for subscriptions? If yes, am I doing something wrong?
Thanks for any help.
"error": {
"code": "BadRequest",
"message": "Unsupported segment type. ODataQuery: users//subscriptions",
"innerError": {
"request-id": "e92caf14-0343-40b0-8720-30946d7fd236",
"date": "2018-05-17T17:53:34"
}
}
Here's my subscribe function:
graph.subscribe = function(token, userid) {
var subscription = {
changeType: 'Created',
notificationUrl: 'my notification url',
resource: '/users/<userid removed>/messages',
clientState: 'blah'
};
request.post({
url: 'https://graph.microsoft.com/v1.0/users/<userid removed>/subscriptions',
headers: {
'content-type': 'application/json',
authorization: 'Bearer ' + token
},
body: JSON.stringify(subscription)
}, function(err, response, body) {
if (err) {
console.error('>>> Application error: ' + err);
} else {
console.log('>>> Subscription returned ' + body);
}
});
};
The POST should be issued to the /v1.0/subscriptions endpoint, not /v1.0/users/{upn}/subscriptions.
You may want to take a look at this Node.js example to see how they're doing it.
I'm trying to receive my users that are stored in Auth0. So, I tried using this website Auth0 management API docs with my API token and API domain. This works fine!
Then I tried to do the same in node js, but when I do that it returns an error. The error message is:
"statusCode":400,"error":"Bad Request","message":"Bad HTTP authentication header format","errorCode":"Bearer"
This is the code that i fount in the documentation
var request = require("request");
var options = { method: 'GET',
url: 'https://<api_url>/api/v2/users',
headers: { authorization: 'Bearer ACCESS_TOKEN' }
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
The only thing that is changed is that I deleted the query string and inserted my api_url and the same access token that I used on the Auth0 management API docs (which works). Am I missing something?
The code looks perfectly fine. I edited it with my hostname/access token as follows and it returned the users:
var request = require("request");
var token = 'eyJ0...'
var options = { method: 'GET',
url: 'https://tenant_name.auth0.com/api/v2/users',
headers: { authorization: 'Bearer ' + token }
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
The two things that might have gone wrong in your case are:
You didn't properly replace the ACCESS_TOKEN in the code.
The access token does not have the read:users permission. You can verify this by pasting the token in jwt.io and inspecting the payload.
I'm trying attach an image using the bot emulator tool and sending this image off to the microsofts customvision api, the issue I'm having is that I get
{ Code: 'BadRequestImageFormat', Message: '' }
back from custom the custom vision api call.
I'm using the the request module from npm to handle the calls
// Receive messages from the user and respond by echoing each message back (prefixed with 'You said:')
var bot = new builder.UniversalBot(connector, function (session) {
session.send("Hello"); //session.message.text
// If there is an attachment
if (session.message.attachments.length > 0){
console.log(session.message.attachments[0])
request.post({
url: 'xxx',
encoding: null,
json: true,
headers: {
'Content-Type': 'application/octet-stream',
'Prediction-Key': 'xxx'
},
body: session.message.attachments[0]
}, function(error, response, body){
console.log(body);
});
}
});
I believe that I may be sending the wrong format through to custom vision however I have been unable to figure it out as of yet.
I replicated your issue and it looks like the problem is your 'Content-Type'. You're attempting to pass JSON in your request, but setting the content-type as octet-stream. See my modified code below:
var bot = new builder.UniversalBot(connector, function (session) {
session.send("Hello"); //session.message.text
// If there is an attachment
if (session.message.attachments.length > 0){
console.log(session.message.attachments[0])
request.post({
url: 'https://northeurope.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures',
encoding: null,
json: true,
headers: {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': 'Your API Key...'
},
body: session.message.attachments[0]
},
function (err, response, body) {
if (err) return console.log(err)
console.log(body);
});
}
});
When I run this, I get the error InvalidImageUrl which is to be expected as it's looking for a content on localhost. You could get round this by exposing your localhost using Ngrok.
I am trying to POST an image from my Node JS app to another REST API. I have the image in Mongo DB (as binary array data) that is read by Node JS and then is supposed to be POSTed to another API.
The problem I face is how do I send request data along with the image? I have this raw data (that is in JSON format) that should be POSTed along with image:
{"data":{"client":"abc","address": "123"},"meta":{"owner": "yourself","host": "hostishere"}}
I am required to do this using the 'request' module. I can use 'multer' if that helps better. But, I am stuck on how do I send the above request data along with the image stream. Below is my current code. Could you please help me finish it?
var options = {
host: 'hostname.com',
port: 80,
path: '/api/content',
method: 'POST',
headers:{
'Content-Type' : 'multipart/form-data'
}
};
var request = http.request(options, function(response) {
var str = '';
var respTime ='';
response.on('data', function (chunk) {
str = str.concat(chunk);
});
response.on('end', () => {
console.log('No more data in response.');
});
setTimeout(function() {
res.send(JSON.stringify(
{
'imageURL': IMG_URL,
'imageId': IMG_ID,
'body': JSON.parse(str)
}
));
}, 1000);
});
request.on('error', (e) => {
console.error('**** problem with request: ', e);
});
request.write(image.IMG_STR); //image.IMG_STR is the binary array representation of the image.
request.end();
UPDATE: 06/06/2017
So, I happened to talk to the REST team that provides the end point and found out that the data should be sent in the following specific format. Below is a snapshot of the request that succeeded. Could someone help me with the Node code that I should use? I have tried form-data package but have been getting the same error:
if you have control over "the other API" too, you could include the image as base64 representation of the binary data in the post-body (and decode it on the API side)
answer to the update 06/06/2017:
according to the screenshot the API requires multipart/formdata.
such requests with the "request"-module are documented in https://github.com/request/request#multipartform-data-multipart-form-uploads
quick example (not tested):
var formData = {
Data: {data: {client: "abc" ...},
file: fs.createReadStream('testImage_2.jpg'),
};
request.post({url:'<YourUrl>', formData: formData}, function optionalCallback(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
If you add the body to your request with the JSON data, you should be able to send it:
var options = {
host: 'hostname.com',
port: 80,
path: '/api/content',
method: 'POST',
headers:{
'Content-Type' : 'multipart/form-data'
},
body: {
"data": {"client":"abc","address": "123"},
"meta":{"owner": "yourself","host": "hostishere"}
}
};
What I don't understand is why you have a setTimeout with res.send when there is no res variable defined anywhere.