【问题标题】:aws upload object to S3 bucket and pass details of data to lambdaaws 将对象上传到 S3 存储桶并将数据的详细信息传递给 lambda
【发布时间】:2017-12-06 08:39:18
【问题描述】:

按照我的方式完成 AWS 教程...所以我创建了一个 S3 存储桶,当将文件放入其中时会调用我的 lambda 'testHelloWorld' 发送电子邮件...这一切都很好(见下文)

 'use strict';

console.log('Loading function');

var aws = require('aws-sdk');
var ses = new aws.SES({
   region: 'us-west-2'
});

exports.handler = function(event, context) {
    console.log("Incoming: ", event);
   // var output = querystring.parse(event);

    var eParams = {
        Destination: {
            ToAddresses: ["johnb@hotmail.com"]
        },
        Message: {
            Body: {
                Text: {
                    Data: "Hey! What is up?"
                }
            },
            Subject: {
                Data: "Email Subject!!!"
            }
        },
        Source: "johnb@hotmail.com"
    };

    console.log('===SENDING EMAIL===');
    var email = ses.sendEmail(eParams, function(err, data){
        if(err) console.log(err);
        else {
            console.log("===EMAIL SENT===");
            console.log(data);


            console.log("EMAIL CODE END");
            console.log('EMAIL: ', email);
            context.succeed(event);

        }
    });

};

但我想扩展电子邮件以包含上传到存储桶的文件的数据。我找到了How to trigger my Lambda Function once the file is uploaded to s3 bucket,它提供了一个 node.js 代码 sn-p,它应该捕获数据。我试图将它导入我现有的 lambda

 'use strict';

console.log('Loading function');

var aws = require('aws-sdk');
var ses = new aws.SES({
   region: 'us-west-2'
});
var s3 = new aws.S3({ apiVersion: '2006-03-01', accessKeyId: process.env.ACCESS_KEY, secretAccessKey: process.env.SECRET_KEY, region: process.env.LAMBDA_REGION });

exports.handler = function(event, context, exit){
    console.log("Incoming: ", event);
   // var output = querystring.parse(event);


 // Get the object from the event and show its content type
   // const bucket = event.Records[0].s3.bucket.name;
   // const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const params = {
       Bucket: 'bucketName',
       Key: 'keyName',
       Source : 'SourceName',
       Destination : 'DestinationName',
       Message : 'MessageName'
    };


     s3.getObject(function(err, data){
         if (err) {
           console.log('ERROR ' + err);
          // exit(err);
         } else {
           // the data has the content of the uploaded file
           var eParams = {
        Destination: {
            ToAddresses: ["johnboy@hotmail.com"]
        },
        Message: {
            Body: {
                Text: {
                    Data: data
                }
            },
            Subject: {
                Data: "Email Subject!!!"
            }
        },
        Source: "johnboy@hotmail.com"
    };
         }
     });     


    console.log('===SENDING EMAIL===');
    var email = ses.sendEmail(eParams, function(err, data){
        if(err) console.log(err);
        else {
            console.log("===EMAIL SENT===");
            console.log(data);


            console.log("EMAIL CODE END");
            console.log('EMAIL: ', email);
            context.succeed(event);

        }
    });

};

但这在参数上失败了

message: 'There were 3 validation errors:

* MissingRequiredParameter: params 中缺少必需的键 \'Source\' * MissingRequiredParameter:参数中缺少必需的键“Destination” * MissingRequiredParameter: 在 params' 中缺少必需的键 \'Message\', 代码:'MultipleValidationErrors', 错误:

这些源、目标和消息都列在参数中,它们的格式是否不正确并且没有提取它们?

我在网上找不到太多...任何帮助表示感谢

更新 好的 iv 让它正常工作...如果我使用 lambda 中的测试函数和以下代码...

   'use strict';

console.log('Loading function');

var aws = require('aws-sdk');
var ses = new aws.SES({
   region: 'us-west-2'
});

var s3 = new aws.S3({ apiVersion: '2006-03-01', accessKeyId: process.env.ACCESS_KEY, secretAccessKey: process.env.SECRET_KEY, region: process.env.LAMBDA_REGION });


exports.handler = function(event, context) {
    console.log("Incoming: ", event);
   // var output = querystring.parse(event);

   var testData = null;

   // Get the object from the event and show its content type
   // const bucket = event.Records[0].s3.bucket.name;
   // const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const params = {
       Bucket: 'bucket',
       Key: 'key',
    };

     s3.getObject(params, function(err, data){
         if (err) {
           console.log('ERROR ' + err);
           exit(err);
         } else {
           testData = data;
         }
     }); 

    var eParams = {
        Destination: {
            ToAddresses: ["jim@him.com"]
        },
        Message: {
            Body: {
                Text: { Data: 'testData2' + testData}
            },
            Subject: {
                Data: "Email Subject!!!"
            }
        },
        Source: "jim@him.com"
    };

    console.log('===SENDING EMAIL===');
    var email = ses.sendEmail(eParams, function(err, data){
        if(err) console.log(err);
        else {
            console.log("===EMAIL SENT===");
            console.log(data);


            console.log("EMAIL CODE END");
            console.log('EMAIL: ', email);
            context.succeed(event);

        }
    });

};

我收到了正文为 testData2null 的电子邮件

所以我尝试通过 s3 存储桶上传图片,但仍然收到正文为 testData2null 的电子邮件

是否有进一步调试这个或者有没有人知道它在说谁是空的。我从未真正测试过另一篇文章中的代码,该代码将数据传递到我认为它会工作的电子邮件中。 Does anyone else know who to obtain the data from the upload please? thanks

【问题讨论】:

    标签: javascript node.js amazon-web-services amazon-s3 aws-lambda


    【解决方案1】:

    您在s3.getObject 的回调中声明var eParams,但随后您在回调之外运行ses.sendMail。我想这就是原因!

    如果您想从电子邮件中的对象发送数据,您还需要将ses.sendEmail 移动到s3.getObject 的回调内部。

    试试这个:

    s3.getObject(function(err, objectData) {
        if (err) {
            console.log('Could not fetch object data: ', err);
        } else {
            console.log('Data was successfully fetched from object');
            var eParams = {
                Destination: {
                    ToAddresses: ["johnboy@hotmail.com"]
                },
                Message: {
                    Body: {
                        Text: {
                            Data: objectData
                        }
                    },
                    Subject: {
                        Data: "Email Subject!!!"
                    }
                },
                Source: "johnboy@hotmail.com"
            };
    
            console.log('===SENDING EMAIL===');
    
            var email = ses.sendEmail(eParams, function(err, emailResult) {
                if (err) console.log('Error while sending email', err);
                else {
                    console.log("===EMAIL SENT===");
                    console.log(objectData);
                    console.log("EMAIL CODE END");
                    console.log('EMAIL: ', emailResult);
                    context.succeed(event);
                }
            });
        }
    });
    

    【讨论】:

    • @John 不,我将 sendEmail 调用移到代码中的正确位置。如果你检查代码中的左花括号和右花括号,你会看到getObject的回调函数在运行sendEmail之前是关闭的。
    • @John 如果您尝试我的代码,您可能会解决从数据中获取 null 的另一个问题。您在回调之外使用来自getObject 调用的data 变量。
    • 感谢您的帮助。这解决了这个问题,但现在我被拒绝访问数据。再次感谢您,如果您有时间,您可能会对我当前的问题有所了解,请stackoverflow.com/questions/47686447/…
    【解决方案2】:

    您需要阅读 Nodejs 的工作原理。它是基于事件的,并且依赖于回调和承诺。你应该这样做 -

     s3.getObject(params, function(err, data){
          //This is your callback for s3 API call. DO stuff here
         if (err) {
           console.log('ERROR ' + err);
           exit(err);
         } else {
           testData = data;
            // Got your data. Send the mail here
         }
     }); 
    

    我在上面的代码中添加了我的 cmets。由于 Nodejs 是单线程的,它会调用 S3 api 并继续。发送邮件时,s3 api 调用未完成,因此数据为空。这里最好使用 Promise。

    无论如何,请阅读 nodejs 中的回调和承诺以及它是如何工作的。但希望这能回答你的逻辑错误。

    【讨论】:

    • 感谢您的帮助,非常感谢我现在了解 node,js 但是我将其他答案标记为正确只是因为他们提供了一个完整的示例......但是我现在有另一个关于访问的问题。 ..如果你有时间也许你可以看看它再次感谢你stackoverflow.com/questions/47686447/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 2018-04-25
    • 2016-08-08
    • 2017-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多