Add metadata with presign

Does anyone know if it’s possible to add metadata to a file that’s uploaded via presign? It sounds like it may be a stretch but thought worth asking anyway. Any ideas, suggestions would be appreciated.

There are possibly a few ways to solve this problem - to consider a few alternatives: (i) what exactly is the problem you are trying to solve? and (ii) where would the meta data be coming from?

We have an API and a React app. The React app will request a presign from the API and then upload the file (step 1). The file is not processed until the React app send a subsequent request to the API after the file has been uploaded (step 2).

We would like to add a metadata to the uploaded file on step 1 (at this point the file has not been processed by the API yet) and then update the metadata once the file has been processed on step 2.

Looking at the docs I have an idea on how to add the metadata when processing the file (step 2), but not when the file is uploaded to the bucket (step 1).

Does that make sense?

Apologies for the delay:

My understanding is that you would like metadata to be attached to s3 objects which are uploaded to a bucket - this metadata will be stored in the s3 bucket, along with the other metadata associated with a file. Necessarily, this metadata will have to be whitelisted with the presigned url.

plugin :presign_endpoint, presign_options: -> (request) do
  # Uppy will send the "filename" and "type" query parameters 
  filename = request.params["filename"]
  type     = request.params["type"] 
  { 
    content_length_range: 0..(10*1024*1024),                 
    content_disposition: ContentDisposition.inline(filename), 
    content_type:        type,                                
    metadata : {some_hash: "here"} ## <----- metadata is here
  }
end

The following line is hit: https://github.com/shrinerb/shrine/blob/6bfb2dae0a00bdbe5a9b46f4e480d880464df16b/lib/shrine/plugins/presign_endpoint.rb#L137 which passes the options on to the underlying aws-sdk here: https://github.com/shrinerb/shrine/blob/6bfb2dae0a00bdbe5a9b46f4e480d880464df16b/lib/shrine/storage/s3.rb#L176

But if your metadata is not added via your ruby api backend, but is created in your react app, you might have to pass that along via a query parameter to your presigned endpoint, and then will have to extract that using request.params["metadata"] in the presign_options lambda code snippet pasted above. That might not make much sense, consider the following link here as an example - paying particular attention to the uppy code:

(There may be ways of asking Uppy to pass on your metadata to a particular endpoint, if your requirements are complex - see here: Uppy — Uppy - i haven’t reviewed it too deeply though)

(caveat: i haven’t tested the code. i peeked into the shrine source + aws sdk + shrine documentation to derive the above - so there may well be mistakes in it.)

Thank you @BKSpurgeon. I was already considering the first option (having the metadata whitelisted with the presigned url). We have placed this feature on hold for a bit but I’ll test as soon as I can. In any case, now I have something to work with. Thank you again :slight_smile: