如果我正确理解您的设置,您已将 S3 存储桶配置为向 SNS 主题发送通知。然后,您将 Lambda 函数订阅到该 SNS 主题。如果是这种情况,那么问题就在于 event.record[0] 中不存在“bucket”对象,因此当 Lambda 函数尝试访问它时,它会抛出错误。
如果您将 S3 存储桶设置为直接向 Lambda 函数发送通知,则它将具有存储桶对象(在 s3 对象下)。我证明了这一点,我做了以下事情:
{
'Records': [{
'eventVersion': '2.1',
'eventSource': 'aws:s3',
'awsRegion': 'us-west-2',
'eventTime': '2024-01-08T17:43:33.045Z',
'eventName': 'ObjectCreated:Put',
'userIdentity': {'principalId': 'REDACTED'},
'requestParameters': {'sourceIPAddress': 'REDACTED'},
'responseElements': {
'x-amz-request-id': 'REDACTED',
'x-amz-id-2': 'REDACTED'
},
's3': {
's3SchemaVersion': '1.0',
'configurationId': 'test-s3-post',
'bucket': {
'name': 'test-s3-notification',
'ownerIdentity': {
'principalId': 'REDACTED'
},
'arn': 'arn:aws:s3:::test-s3-notification'
},
'object': {
'key': 'testfile',
'size': 16,
'eTag': '02bcabffffd16fe0fc250f08cad95e0c',
'sequencer': '00659C3444F0B67C19'
}
}
}]
}
注意“s3”对象,其中存在“bucket”对象。
接下来,我创建了一个 SNS 主题,并让 S3 存储桶而不是 Lambda 函数向其发送通知。最后,我设置 Lambda 函数来订阅 SNS 主题。这是该调用的“事件”结构:
{
'Records': [{
'EventSource': 'aws:sns',
'EventVersion': '1.0',
'EventSubscriptionArn': 'arn:aws:sns:us-west-2:759995470648:test-s3-trigger:0ae1af08-0301-457d-88e0-c4f8f7c9b1ca',
'Sns': {
'Type': 'Notification',
'MessageId': 'b6b4faf5-aed8-5d3e-ba04-a4e3e21fd356',
'TopicArn': 'arn:aws:sns:us-west-2:759995470648:test-s3-trigger',
'Subject': 'Amazon S3 Notification',
'Message': '{
"Service":"Amazon S3",
"Event":"s3:TestEvent",
"Time":"2024-01-08T19:18:30.998Z",
"Bucket":"test-s3-notification",
"RequestId":"REDACTED",
"HostId":"REDACTED"
}',
'Timestamp': '2024-01-08T19:18:31.025Z',
'SignatureVersion': '1',
'Signature': 'REDACTED',
'SigningCertUrl': 'REDACTED',
'UnsubscribeUrl': 'REDACTED',
'MessageAttributes': {}}
}]
}
因此,正如您所看到的,当您收到来自 SNS 的消息时,存储桶信息位于不同的位置,并且有关对象的信息丢失了。