shubhamagiwal92
shubhamagiwal92

Reputation: 1432

Unable to create a resized image using AWS Lambda

I have created an AWS Lambda function to resize any image that is put in my s3 bucket. I have created an event for every Object creation in s3 bucket for the Lambda function to trigger. My Handler code for Lambda is as follows:

var async = require('async'),
    gm = require('gm').subClass({
    imageMagick: true
}) // Enable ImageMagick integration.
, request = require('request').defaults({
    encoding: null
});

var knox = require('knox');
var client = knox.createClient({
key: 'myKey',
secret: 'mySecretKey',
bucket: 'MyBucketName'
});


//hardcoded Value to get the Image url
var s3value = '.s3.amazonaws.com/';
var https = 'https://'

exports.handler = function (event, context) {
var srcBucket = event.Records[0].s3.bucket.name;
var srcKey = event.Records[0].s3.object.key;
var imageUrl = https + srcBucket + s3value + srcKey //My Http Url for image stored in s3 bucket.
request(imageUrl, function (err, res, res1) {
    if (err) {
        console.log(err);
    } else {
        gm(res1).resize(120)
            .toBuffer('jpg', function (err, buffer) {
                if (err) {
                    console.log(err);
                } else {
                    var ImageName = "/" + imageUrl.substr(0, imageUrl.indexOf(".")) + "-1x" + imageUrl.substr(imageUrl.indexOf("."), imageUrl.length); //Renaming the present image
                    client.putBuffer(buffer, ImageName, function (err, response1) {
                        if (err) {
                            console.log(err);
                        } else {
                            console.log(response1.socket._httpMessage.url);
                        }
                    });
                }
            });
    }
});
context.done();
}

My Problem is that when I store an image in S3 the resized image is not getting created in my s3 Bucket. I am unable to understand why I am unable to create a resized image in the same s3 bucket. Can somebody help me with it?

Upvotes: 0

Views: 1409

Answers (1)

James
James

Reputation: 11931

It looks like you are calling context.done() outside the callback function for request(). This will end the Lambda function before any image resizing completes. You should only call context.done() when all processing has completed or failed.

exports.handler = function (event, context) {
    var srcBucket = event.Records[0].s3.bucket.name;
    var srcKey = event.Records[0].s3.object.key;
    var imageUrl = https + srcBucket + s3value + srcKey //My Http Url for image stored in s3 bucket.
    request(imageUrl, function (err, res, res1) {
        if (err) {
            console.log(err);
            context.fail(err);
        } else {
            gm(res1).resize(120)
                .toBuffer('jpg', function (err, buffer) {
                    if (err) {
                        console.log(err);
                        context.fail(err);
                    } else {
                        var ImageName = "/" + imageUrl.substr(0, imageUrl.indexOf(".")) + "-1x" + imageUrl.substr(imageUrl.indexOf("."), imageUrl.length); //Renaming the present image
                        client.putBuffer(buffer, ImageName, function (err, response1) {
                            if (err) {
                                console.log(err);
                                context.fail(err);
                            } else {
                                console.log(response1.socket._httpMessage.url);
                                context.succeed("It worked");
                            }
                        });
                    }
                });
        }
    });
    // Don't call context.done() here, the callback hasn't run yet
    //context.done();
}

Upvotes: 2

Related Questions