how to send a pdf base64 variable through a nodejs request? - node.js

Trying to send a base64 pdf string with request, but I can't seem to figure out the proper structure of the request. Thanks in advance for the help!
var dpdf = pdfvar.toString('base64');
var options = {
method: 'POST',
body: dpdf,
url: FILEPICKER_URL,
headers: [
{
name: 'content-type',
value: 'application/pdf'
}
]
};
request(options, function(err, httpResponse, body){
console.log('body: ', body);
console.log('code ', httpResponse.statusCode)
});

The other side is expecting a PDF
application/pdf
and not a BASE64 representation of it.
Anyway, looking at what you are trying to do, without necessarily understanding how you are trying to do it... I would try and append a data url compatible header to your string like so :
var dpdf = 'data:application/pdf;base64,' + pdfvar.toString('base64')

Related

How to select specific field of a JSON response in Node JS?

I have the following API response named "body" and trying to log a specific field/submap, for example the "response" map. I don't really know the correct syntax in NodeJS or JavaScript.
{"get":"fixtures","parameters":{"league":"135","season":"2022","status":"NS","timezone":"Europe\/rome"},"errors":[],"results":40,"paging":{"current":1,"total":1},"response":[{"fixture":{"id":881790,"referee":"M. Piccinini","timezone":"Europe\/rome","date":"2022-08-20T18:30:00+02:00","timestamp":1661013000,"periods":{"first":null,"second":null},"venue":{"id":943,"name":"Stadio Olimpico Grande Torino","city":"Torino"},"status":{"long":"Not Started","short":"NS","elapsed":null}},"league":{"id":135,"name":"Serie A","country":"Italy","logo":"https:\/\/media.api-sports.io\/football\/leagues\/135.png","flag":"https:\/\/media.api-sports.io\/flags\/it.svg","season":2022,"round":"Regular Season - 2"},"teams":{"home":{"id":503,"name":"Torino","logo":"https:\/\/media.api-sports.io\/football\/teams\/503.png","winner":null},"away":{"id":487,"name":"Lazio","logo":"https:\/\/media.api-sports.io\/football\/teams\/487.png","winner":null}},"goals":{"home":null,"away":null},"score":{"halftime":{"home":null,"away":null},"fulltime":{"home":null,"away":null},"extratime":{"home":null,"away":null},"penalty":{"home":null,"away":null}}},]}
The code is below:
var request = require("request");
var options = {
method: 'GET',
url: 'https://v3.football.api-sports.io/fixtures?league=135&season=2022&status=NS&timezone=Europe/rome',
qs: {},
headers: {
'x-rapidapi-host': 'v3.football.api-sports.io',
'x-rapidapi-key': 'xxxxxxxxxxxxxxxxx'
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
I tried console.log(body.response); without success. I also tried body["response"] ending with "undefined" result.
It seems body was a String result so I could select the field with JSON syntax. I solved with console.log(JSON.parse(body).response[0]);
Two approaches:
Approach 1: Set the Content-Type as application/json in the server.
Approach 2: Convert the body from string to JSON object by JSON.parse

Using request module and passing the body to the next request

I am using request to get an image:
request(req.body.imageUrl, {encoding: null}, function(error, response, body) {
I then want to use the body to pass to an api that uses a multipart form and send that image (which is now in the body). I don't want to write the file to disk and then readstream from the disk again. I basically want to enter the formData of the next request by using the Buffer of the body, but it is not working.
So, for the options in the next request I have:
const options = {
method: "POST",
url: coreURL,
headers: {
"Content-Type": "multipart/form-data"
},
formData : {
file : new Buffer.from(body,'binary')
}
};
And this does not work, if I write the body to a file fs.writeFileSync(fileName, body, 'binary');
And then read in the options formData : { file : fs.createReadStream(fileName)}
it works but I cannot use the disk, so need an alternative way to pass the body into the next post as multipart form data.
Any ideas?
POC:
let request = require('request');
request.post({
url: "http://httpbin.org/anything",
formData: {
myfile: request.get("https://www.gravatar.com/avatar/f056d36f9e273fd4740ec8a5cea1348a"),
}
},
function (err, req, body) {
console.log(body);
}
);

Unable to exchange code for access token in node.js. Mailchimp API

I am trying to use OAuth2 with the Mailchimp API, and I am following their documentation to the letter, but I am unable to complete step 4. At this step, I exchange the code I received from the authorization screen for the token. Per the documentation, this can be done in curl like so:
curl --request POST \
--url 'https://login.mailchimp.com/oauth2/token' \
--data "grant_type=authorization_code&client_id={client_id}&client_secret={client_secret}&redirect_uri={encoded_url}&code={code}" \
--include
I attempted to convert this to work on node.js by writing this:
var dataString = 'grant_type=authorization_code&client_id=' + clientid + '&client_secret=' + clientsecret + '&redirect_uri=' + encodedurl + '&code=' + url.parse(req.url, true).query.code;
var options = {
url: 'https://login.mailchimp.com/oauth2/token',
method: 'POST',
data: dataString
};
function callback(error, response, body) {
if (!error) {
console.dir(JSON.stringify(body));
}
else{
console.dir(error);
}
}
request(options, callback);
When I make the request.debug = true, I see that I am getting a 400 error. The message sent to the console is a bunch of garbled characters though. When I use these same variables and endpoints to authenticate through Postman though, it works fine, so the issue is not with the variables or the API itself.
I am not entirely sure what I am doing wrong here. The request I am making seems almost identical what is written in curl in the documentation. So where am I going wrong?
Hmm, did you forget to define request?
var request = require("request");
Finally figured it out. The issue was in the header of the request. There are two ways to fix this. The first is to use "form" instead of "data". Request includes a "content-type: x-www-form-urlencoded" header automatically if the option "form" is used.
var options = {
url: 'https://login.mailchimp.com/oauth2/token',
method: 'POST',
form: dataString
};
I am not sure what header is used when the "data" option is used, or if no content-type is declared at all. Either way, if you choose to continue to use the "data" option, you can manually declare a content-type header. This is the second possible solution.
var options = {
url: 'https://login.mailchimp.com/oauth2/token',
method: 'POST',
headers:
{ 'Content-Type': 'application/x-www-form-urlencoded' },
body: dataString
};
After alot of tries, I figured out. You can use code only once. So make sure you use code you get from redirect URI only once.
With new code use this code
const dataString = "grant_type=authorization_code&client_id="+client_id+"&client_secret="+client_secret+"&redirect_uri="+redirect_uri+"&code="+req.body.code
var options = {
url: 'https://login.mailchimp.com/oauth2/token',
method: 'POST',
headers:
{
'Content-Type': 'application/x-www-form-urlencoded',
},
form: dataString
};
function callback(error, response, body) {
if (!error) {
let str = JSON.stringify(body)
res.setHeader("Content-Type", "application/json; charset=utf-8")
res.send(body)
}
else{
console.dir(error);
res.send(error)
}
}
request(options, callback);

BadRequestImageFormat error while trying to post an image attachment to Custom Vision API using NodeJS bot

var request = require('request'); //node module for http post requests
exports.retreiveMessage = function (session){
request.post({
url: 'https://southcentralus.api.cognitive.microsoft.com/customvision/v1.0/Prediction/279ae65a-c1f8-4eb0-a4d8-03a3234bc023/image?iterationId=bcfb842f-df51-47e3-8ba4-c90209a16003',
json: true,
headers: {
'Content-Type': 'application/octet-stream',
'Prediction-Key': 'XXXXX'
},
body: session.message.attachments[0]
}, function(error, response, body){
if (error){
console.log(error);
}
console.log(validResponse(body));
session.send(validResponse(body));
});
}
function validResponse(body){
if (body && body.Predictions && body.Predictions[0].Tag){
return "This is " + body.Predictions[0].Tag
} else{
console.log('Oops, please try again! Something is wrong with custom vision.');
}
}
This is the block of code that I'm trying to use to post an image attachment to Custom Vision API, but I keep getting BadRequestImageFormat and I don't know what to do. Any help is appreciated.
I think it's due to the reference part of request body is not clear at the documentation, but we can from the c# code sample at https://learn.microsoft.com/en-us/azure/cognitive-services/custom-vision-service/use-prediction-api, that we need to post the image binary in body property.
And in Bot Framework, the session.message.attachments[0] is an object with the attachments info not content in buffer type:
which rised your issue.
Please try following code snippet:
const rp = require('request-promise');
rp.get(session.message.attachments[0].contentUrl).then(buffer=>{
return rp.post(
{
url:<url>,
headers: {
'Content-Type': 'application/octet-stream',
'Prediction-Key': '<key>'
},
body: buffer
}
)
}).then(res=>{
console.log(res);
session.send(res)
})
You need to remove json: true.

How to set POST encoding with request module on node.js?

I'm using request module on node.js but there is something problem with encoding option. beneath codes are simple post request, but I don't know how to set up encoding of form field data. I already set headers to 'Content-Type': 'application/x-www-form-urlencoded; charset=euc-kr' But it doesn't works. field data is korean, like "안녕하세요", and I should post it with euc-kr encoding. (The site takes euc-kr, not utf8)
The same program on Java application, I coded like this :
PrintWriter wr = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "euc-kr"));
But I don't know how to in nodejs. Can anyone give some solution...?
Code Sample
//Load the request module
var request = require('request');
//Lets configure and request
request({
url: 'http://google.com', //URL to hit
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=euc-kr' },
method: 'POST',
form: {
field1: 'data',
field2: 'data'
}
}, function(error, response, body){
if(error) {
console.log(error);
} else {
console.log(response.statusCode, body);
}
});
Finally I got a soultion, and I solved this problem.
If you send a data as a form using request module, the module change your form encoding to utf-8 by force. So even you setted your form encoding to another charset, the module changes your charset to utf8 again. You can see that at request.js on line 1120-1130.
So, You'd better send a data by 'body' option, not 'form' option.
Node doesn't support EUC-KR so you can use iconv-lite to extend the native encodings available and set the encoding option in request.
List of Natively Supported Encodings
iconv.extendNodeEncodings(); only works for node pre v4+. See here to get this working for a newer version of node.
var iconv = require('iconv-lite');
var request = require('request');
// This will add to the native encodings available.
iconv.extendNodeEncodings();
request({
url: 'http://google.com', //URL to hit
method: 'POST',
form: {
field1: 'data',
field2: 'data'
},
encoding: 'EUC-KR'
}, function(error, response, body){
if(error) {
console.log(error);
} else {
console.log(response.statusCode, body);
}
});
iconv.undoExtendNodeEncodings();

Resources