sabbir sabbir - 5 months ago 192
Node.js Question

upload dynamically generated pdf from aws-lamda into aws-s3

In my

serverless
app, I want to create pdf which is generated dynamically and then upload that created pdf into
aws s3
. My problem is, when a url is returned to client-side code from server, uploaded url doesn't working. My code is given below:

Client-side javascript code (angular.js)

$scope.downloadAsPDF = function() {

// first I have to sent all html data into server
var html = angular.element('html').html(); // get all page data

var service = API.getService();
service.downloadPdf({}, { html : html }, // api call with html data
function(res) {
console.log("res : ", res);
window.open(res.url); // open uploaded pdf file
// err: The server replies that you don't have permissions to download this file
// HTTP/1.1 403 Forbidden
}, function(err) {
console.log("err : ", err);
});
};


Serverless Code

var fs = require('fs');
var pdf = require('html-pdf');

var AWS = require("aws-sdk");
var s3 = new AWS.S3();

module.exports.handler = function(event, context) {

if (event.html) { // client html data

AWS.config.update({
accessKeyId: 'xxxxxxxxxxxxxxxxx',
secretAccessKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
region: 'xxxxxxxxxxxxxxxxxxxx'
});

var awsInfo = {
bucket: 'xxxxx-xxxxxx'
};

var baseUrl = 'https://s3-my-region.amazonaws.com/s3-upload-directory';
var folderRoot = 'development/pdf';

// unique file name
var output_filename = Math.random().toString(36).slice(2) + '.pdf';

// file created directory
var output = '/tmp/' + output_filename;

pdf.create(event.html, options).toStream(function(err, stream) {

if( err ) {
console.log('pdf err : ', err);
} else {

writeStream =fs.createWriteStream(output);

s3.putObject({
Bucket : awsInfo.bucket,
Key : folderRoot + '/' + output_filename,
Body : fs.createReadStream(output),
ContentType : "application/pdf"
},
function(error, data) {

if (error != null) {
console.log("error: " + error);
} else {
// upload data: { ETag: '"d41d8cd98f00b204e9800998ecf8427e"' }
console.log('upload data : ', data);

return cb(null, {
// return actual aws link, but no file
// ex: 'https://s3-my-region.amazonaws.com/s3-upload-directory/output_filename.pdf
url: baseUrl + '/' + output_filename
});
}

});

}
}
};


How can I solve this problem? Thanks in Advance.

Answer

I've solve my problem. I was trying to upload pdf before I generate pdf. I have solve this problem using the following code:

  pdf.create(event.html, options).toStream(function(err, stream) {
      if (err) {
          console.log('pdf err : ', err);
      } else {
           var stream = stream.pipe(fs.createWriteStream(output));

          stream.on('finish', function () {

            s3.putObject({
                  Bucket : awsInfo.bucket,
                  Key : folderRoot + '/' + output_filename,
                  Body :  fs.createReadStream(output),
                  ContentType : "application/pdf"
                },
                function(error, data) {

                  if (error != null) {
                    console.log("error: " + error);
                    return cb(null, {
                      err:  error
                    });
                  } else {

                    var url =  baseUrl +  '/' + output_filename

                    return cb(null, {
                      url: url
                    });

                  }

                });

          });
      }
  });
Comments