【问题标题】:Printing s3 bucket upload object key with lambda with Ruby?使用 Ruby 使用 lambda 打印 s3 存储桶上传对象键?
【发布时间】:2019-08-07 17:03:02
【问题描述】:

以下是 aws lambda 为 s3 事件提供的测试示例:

{
  "Records": [
    {
      "eventVersion": "2.0",
      "eventSource": "aws:s3",
      "awsRegion": "us-east-2",
      "eventTime": "1970-01-01T00:00:00.000Z",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "EXAMPLE"
      },
      "requestParameters": {
        "sourceIPAddress": "127.0.0.1"
      },
      "responseElements": {
        "x-amz-request-id": "EXAMPLE123456789",
        "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
      },
      "s3": {
        "s3SchemaVersion": "1.0",
        "configurationId": "testConfigRule",
        "bucket": {
          "name": "example-bucket",
          "ownerIdentity": {
            "principalId": "EXAMPLE"
          },
          "arn": "arn:aws:s3:::example-bucket"
        },
        "object": {
          "key": "test/key",
          "size": 1024,
          "eTag": "0123456789abcdef0123456789abcdef",
          "sequencer": "0A1B2C3D4E5F678901"
        }
      }
    }
  ]
}

我特别想知道,我将如何打印object: key:

具体是"test/key"?

我试过这个和其他一些方法都没有成功:

require 'json'
require 'aws-sdk-elastictranscoder'
require "aws-sdk-s3"

def lambda_handler(event:, context:)
    src_bkt = "example-bucket"
    src_key = event.Records[0].s3.object.key

    s3.getObject({
        Bucket: src_bkt,
        Key: src_key
    })
    # TODO implement
    { statusCode: 200, body: JSON.generate(src_key) }
end

我得到的回复是一个失败的回复,内容如下:

Response:
{
  "errorMessage": "undefined method `Records' for #<Hash:0x0000561d9afa6618>",
  "errorType": "Function<NoMethodError>",
  "stackTrace": [
    "/var/task/lambda_function.rb:7:in `lambda_handler'"
  ]
}

更新:

我可以打印整个记录:

def lambda_handler(event:, context:)
    body = JSON.generate(event)
    parse = JSON.parse(body)

    puts(parse["Records"])
end

但是我在puts/print中添加了一个类似的东西:

puts(parse["Records"]["object"]["key"])

我收到如下错误:

"errorMessage": "no implicit conversion of String into Integer",

【问题讨论】:

  • 为什么要访问散列值,就好像它们是对象上的方法一样?是你正在使用的额外的东西吗?
  • 我正在尝试定义"object": { "key": "test/key",,以便我可以使用该名称在文件上传时创建水印。我已成功使用 lambda 来执行此操作,但我无法弄清楚如何识别正在从 s3 上传创建触发器的文件。我需要在 s3 存储桶中定义一个文件,以便在文件上创建水印。因此,我正在测试如何识别密钥,以便可以将其用作文件名
  • 由于您的数据的表示方式,不是parse[:Records][0][:s3][:object][:key](或parse['Records'][0]['s3']['object']['key'])
  • 我实际上在不久前就使用了确切的代码,只是用了双引号。但现在 lambda 循环。所以现在我需要弄清楚

标签: ruby amazon-web-services amazon-s3 aws-lambda aws-sdk


【解决方案1】:

如果您执行以下操作会怎样:

record = event["Records"][0]
key = record.dig *%w(s3 object key)

我认为,您感到困惑的原因是 event 对象是一个带有键 Records 的哈希,其中包含所有事件记录的数组。因此,您可以将记录取出(第一行)而不是转换为 JSON,然后使用哈希的 dig 方法访问密钥(我发现在遍历 AWS 事件记录哈希时非常方便)。

【讨论】:

  • 所以这行得通,而且我所拥有的代码更少。现在我的问题是由于相同的文件上传和一遍又一遍地触发 lambda,lambda 不断循环。你认为什么是打破循环的好方法......现在,唯一不好的是我正在使用 Active Storage,所以存储桶需要保持不变。
  • @uno 您是否尝试仅在最初上传时触发 lambda,而不是每次更新时触发?
  • 它适用于 PUT,当我更改为 POST 时,没有任何反应。因此,用户上传视频,应用视频水印,它循环......一旦应用水印,它希望它停止。我认为做 POST 可以解决问题,但它甚至不会触发,除非在 PUT 上?
  • @uno 根据文档docs.aws.amazon.com/AmazonS3/latest/dev/…,不同的 PUT 和 POST 事件类型来自可用于访问 S3 对象的不同 API。如果您因为重写同一个文件而遇到问题,如果您尝试对项目进行版本控制并仅在文件具有特定版本时处理请求怎么办?
  • 你能举例说明你的意思吗?你是说,只允许例如:.mov 文件,然后以 .mp4 格式输出文件?那么它就不会循环了?
猜你喜欢
  • 2022-11-23
  • 1970-01-01
  • 2021-08-26
  • 1970-01-01
  • 2020-12-01
  • 1970-01-01
  • 2020-05-19
  • 1970-01-01
  • 2023-03-21
相关资源
最近更新 更多