sabbir
sabbir

Reputation: 2025

upload dynamically generated pdf from aws-lambda 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
                   });
                }

             });

         }
    }
};

Upvotes: 1

Views: 3248

Answers (3)

Kamran Qadri
Kamran Qadri

Reputation: 154

if we don't want to upload at s3 just return generated file from aws-lambda.

Upvotes: 0

sabbir
sabbir

Reputation: 2025

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
                    });

                  }

                });

          });
      }
  });

Upvotes: 3

Aditya Kumar
Aditya Kumar

Reputation: 26

I have done similar kind of thing before.
I want a few clarifications from you and then I will be able to help you better.
1) In your code (server side), you have mentioned in the callback function that actual aws link is getting returned. Are you sure that your file is getting uploaded to Amazon s3. I mean did you check your bucket for the file or not?
2) Have you set any custom bucket policy on Amazon s3. Bucket policy play an important role in what can be downloaded from S3.
3) Did you check the logs to see exactly which part of code is causing the error? Please provide me this information and I think the I should be able to help you.

Upvotes: 0

Related Questions