NodeJS String to Buffer pdf file - node.js

Hi guys i'm trying to download a pdf file and save it on my disk. The API send me a string. But the following code not working.
axios.get('https://myapi.com/download', config).then((res) => {
var buff = Buffer.from(res.data, 'binary');
fs.writeFile('file.pdf', buff, function (err) {
if (err) throw err;
console.log('Saved!');
});
}).catch((e) => {
console.log(e);
})
I've tried it, and working ...
fs.readFile('./download.pdf','binary', function (err, data) {
var str = data.toString();
var buff = Buffer.from(str, 'binary');
fs.writeFile('novopdf.pdf',buff, () => {
console.log('ok');
})
});

You need to config axios get request as follows
const response = await Axios({
method: 'GET',
url: url,
responseType: 'stream'
})
response.data.pipe(Fs.createWriteStream(path)) // path is location where you want to write the file.
Then check for end event on the response object.

Related

node.js save http response as pdf file

I have AWS Lambda function that return pdf file like arr.
I want to call function and save pdf file, but after saving I can't open it, it brocken. I cant undestand why, i tried differente ways to create pdf, by the way i can get arr and using online converter convert arr to file, and its work, but when i create pdf file using node code its always broken. I tried internal node moduls like fs, and external like pdfkit.
`const https = require('https');
const fs = require('fs');
const PDFDocument = require('pdfkit');
const options = {
host: 'uek9w0hztc.execute-api.eu-north-1.amazonaws.com',
path: '/pdfmaker',
method: 'POST',
headers: {
url: 'https://www.linkedin.com'
}
}
const req = https.request(options, res => {
let data = [];
const headerDate = res.headers && res.headers.date ? res.headers.date : 'no response date';
console.log('Status Code:', res.statusCode);
console.log('Date in Response header:', headerDate);
res.on('data', chunk => {
data.push(chunk);
});
res.on('end', () => {
console.log('Response ended: ');
// fs.writeFileSync('index.pdf', Buffer.from(data));
// fs.writeFileSync("index_v2.pdf", Buffer.from(data), 'binary', (err) => {
// if(err) {
// return console.log(err);
// }
// console.log("The file was saved!");
// });
// const doc = new PDFDocument();
// doc.pipe(fs.createWriteStream('output.pdf'));
let writeStream = fs.createWriteStream('pdf123.pdf')
writeStream.once('open', (fd) =>{
writeStream.write(new Buffer.from(data, 'binary'))
writeStream.on('finish', () => {
console.log('wrote all data to file');
});
writeStream.end()
})
});
}).on('error', err => {
console.log('Error: ', err.message);
});
req.end();`
I tried internal node moduls like fs, and external like pdfkit.
I expect someone give me a hint where the problem is.

Saving docx file from URL using NodeJS

I would like to download a docx file content from a url to S3 using Node JS. Is there a suggested library for doing the same. I tried to download locally using something like this but it turns out the document contents are Gibberish. Is there anything I am missing here.
const axios = require("axios");
const fs = require("fs");
(async function () {
let article;
try {
const httpResponse = await axios.get("https://<url>/Go_Lang.docx?raw=true",
{responseType: 'blob', headers : { 'Accept': "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}});
fs.writeFileSync(“./temp.docx", Buffer.from(httpResponse.data), function (err) {
if (err) console.log(err);
else console.log("done");
});
} catch (err) {
console.log(err)
}
})();
Change responseType to arraybuffer, and you don't need to convert it to Buffer.
Also, .writeFileSync does not take callback, so it's writeFile
try this:
(async function() {
let article;
try {
const httpResponse = await axios.get("https://<url>/Go_Lang.docx?raw=true", {
responseType: 'arraybuffer',
headers: {
'Accept': "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}
});
fs.writeFile("./temp.docx", httpResponse.data, function (err) {
if (err) console.log(err);
else console.log("done");
});
} catch (err) {
console.log(err)
}
})();

How to make express download link with GridFsBucket?

As the title says, how do you make a direct download link with a file from mongoDB(GridFsBucket) using express?
The file should be downloadable from memory, as i dont want to save it temporarily on the server.
I have this method:
async function downloadFileFromDB(fileId) {
var gridfsbucket = new mongoose.mongo.GridFSBucket(mongoose.connection.db, {
chunkSizeBytes: 1024,
bucketName: 'filesBucket'
});
try {
const stream = gridfsbucket.openDownloadStream(fileId)
const fileBuffer = Buffer.from(stream)
return fileBuffer
} catch (err) {
stream.on('error', () => {
console.log("Some error occurred in download:" + error);
})
console.log(err);
}
}
And this route:
router.get('/download-file', async (req,res) => {
const fileId = req.query.fileId
const ObjectFileId = new ObjectId(fileId)
const fileBuffer = await fileFacade.downloadFileFromDB(ObjectFileId)
res.download(fileBuffer)
})
But res.download wants a path and not a buffer. Aswell im not sure i can make a buffer directly from the openDownloadStream method.
Can anyone help?
I believe you need to write the data to your res object. I accomplished this like:
const readStream = gridfs.openDownloadStreamByName(filename);
readStream.on("data", (chunk) => {
res.write(chunk);
});
readStream.on("end", () => {
res.status(200).end();
mongoClient.close();
});
readStream.on("error", (err) => {
console.log(err);
res.status(500).send(err);
});
So, you may just have to do:
res.write(fileBuffer).end();
//// Instead of doing:
// res.download(fileBuffer);

Node js file upload issue

I'm trying to upload a file to nanosets API. I uploaded the following node js function to firebase and trying to excess it with following URL for example with a file in body (trying to test this with postman)
Node js function looks like:
exports.uploadFile = functions.https.onRequest((req, res) => {
cors(req, res, () => {
if (req.method !== "POST") {
return res.status(500).json({
message: "Not allowed"
});
}
const busboy = new Busboy({headers: req.headers});
let uploadData = null;
busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
const filepath = path.join(os.tmpdir(), filename);
uploadData = {modelId: '4bc54977-60cf-4415-a417-c39f1c18b83f', file: fs.createReadStream(filename), type: mimetype};
const options = {
url: 'https://app.nanonets.com/api/v2/OCR/Model/XXXXXXX-60cf-4415-a417-c39f1c18b83f/LabelFile/',
formData: uploadData,
headers: {
'Authorization': 'Basic ' + Buffer.from('tiOJNxuDbdl40lXXXXXXXXXXFTYbY' + ':').toString('base64')
}
};
request.post(options, function (err, httpResponse, body) {
if (err) {
console.log(err);
}
console.log(body)
});
});
busboy.on("finish", () => {
res.status(200).json({
message: "It worked!"
});
});
busboy.end(req.rawBody);
});
});
Why I check the logs with firebase functions:log I get the following results:
2020-06-06T09:35:06.168774140Z D uploadFile: Function execution started
2020-06-06T09:35:06.344Z I uploadFile: invoice_4.pdf
2020-06-06T09:35:06.432Z I uploadFile: FileStream {
2020-06-06T09:35:06.439Z E uploadFile: TypeError: source.pause is not a function
Anyone an idea? How to pass the file to nanosets?
In order to make outgoing requests from Cloud Functions, your project must be on the Blaze payment plan.

Fetch and post text in NodeJS

I'm trying to grab text from an API that only returns a string of text ((here)) and having troubles throwing that out in a response. When posting, it comes out as [object Response], and the console.log doesn't show the text I want out of it.
The code I'm using:
fetch('http://taskinoz.com/gdq/api').then(
function(response) {
console.log(response);
throttledSendMessage(channel, response);
return response;
})
.catch(function(error) {
throttledSendMessage(channel, "An error has occured");
})
Log can be found here
Thanks for looking with me, couldn't find a solution :/
I think that because fetch returns a Response you need to call one of the functions on Response in order to get at the body's text. Here's an example:
fetch('https://github.com/')
.then(res => res.text())
.then(body => console.log(body));
Probably the problem is in async behavior of node.js. You can read more here
Also, I'm assume you use this package to make fetch request in node.js.
And assume that throttledSendMessage function is synchronous.
About your problem, just try to rewrite co de to use async/await for cleaner solution.
// We'll use IIFE function
(async () => {
const fetchResult = await fetch('http://taskinoz.com/gdq/api')
// Here fetch return the promise, so we need to await it again and parse according to our needs. So, the result code would be this
const data = await fetchResult.text();
throttledSendMessage(channel, data);
return data;
})()
Fetch is not available in nodejs , you could use the node-fetch https://www.npmjs.com/package/node-fetch , or you could use this fetch function:
const https = require('https');
const http = require('http');
function fetch(url, options = {}) {
return new Promise((resolve, reject) => {
if (!url) return reject(new Error('Url is required'));
const { body, method = 'GET', ...restOptions } = options;
const client = url.startsWith('https') ? https : http;
const request = client.request(url, { method, ...restOptions }, (res) => {
let chunks = '';
res.setEncoding('utf8');
res.on('data', (chunk) => {
chunks += chunk;
});
res.on('end', () => {
resolve({ statusCode: res.statusCode, body: chunks });
});
});
request.on('error', (err) => {
reject(err);
});
if (body) {
request.setHeader('Content-Length', body.length);
request.write(body);
}
request.end();
});
}
module.exports = fetch;
you could use it like this inside your code :
const result = await fetch(
`https://YOUR_URL`,
{
method: 'PUT',
body: JSON.stringify({ test: 'This is just a test', prio: 1 }),
},
);

Resources