Has anyone ever issued an AWS S3 Presigned URL with BUBBLE?

Has anyone ever issued an AWS S3 Presigned URL with BUBBLE?

I would like to use AWS S3 Presigned URL as I would like to sell images, but I don’t know how to achieve this.

Is this for upload or for retrieval?
I do this for upload though I think almost exactly the same process applies for fetching.

Can you tell me how to do that?

I’m trying to implement a feature like the attached image.
I want to display the image for 5 minutes after the user presses the download button.

You’ll need to do this through a plugin so that you can work with NPM modules.
I’m going to assume that you’re comfortable setting up a plugin, creating a server side action and AWS - there’s lots on the forum / Bubble’s reference/AWS docs to explain those processes if you’re not.

To create the link

  1. Create a plugin and add a server-side action
  2. Add region, bucket_name, access-id and (in your case) expiration and key fields.
  3. Add aws_url return value as text.
  4. Adapt the code below so that you are using getObject rather than my putObject - you can see an example here, I think the only difference might be that you need to add a Key parameter which references the asset that you are requesting. Put this inside your function. Once you add the require() statement, Bubble will ask you (beneath the code input field) to run an initial compile of the aws-sdk module.
  5. You should add expires: 300 to the params object if you want the link to be invalid after 5 minutes.
  6. You’ll also add a key called secret as text type via the Shared tab on the plugin builder.
function(properties, context) {

    var AWS = require('aws-sdk');

    const region = properties.region;
    const bucketName = properties.bucket_name;
    const accessKeyId = properties.access_id;
    const secretAccessKey = context.keys.secret;

    const s3 = new AWS.S3({
        region: region,
        accessKeyId: accessKeyId,
        secretAccessKey: secretAccessKey,
        signatureVersion: 'v4'
    let uploadURL = context.async(async callback => {
        try {
            const params = {
                Bucket: bucketName,
                Key: properties.name

            const URL = await s3.getSignedUrlPromise('putObject', params);
    		callback(null, URL);
  		catch (err) {

return {
	"aws_url": uploadURL


To use the link

  1. Setup your plugin inside your app by bringing over your Secret and Access keys from Amazon (secret key will go in the Plugin settings and Access key will go in the field you created in the workflow)
  2. Create a Backend Workflow and add the action from your plugin to that workflow. In your case your workflow will need a parameter to receive the key for the asset you want to retrieve.
  3. Every time you call that workflow you’ll generate a pre-signed link. It’s up to you whether you save that to the database for use on the front end, or you can do what I do and return it to front-end as below. For this approach you’ll need to setup a call to the endpoint from your API Connector otherwise you won’t be able to receive the return value back from the call.

I hope that helps and sorry that I can’t go into more detail than that.


Thank you so much!
I can’t thank you enough for all you do for us!

Thanks for all the details you provided that made this happen!

Thank you so much!

スクリーンショット 2022-04-05 12.32.19

スクリーンショット 2022-04-05 12.32.45

1 Like

Hello all,

@exception-rambler thanks for your answer, it is really helpful. Could you clarify how do you upload the file? I’ve followed your instructions but I get an error when uploading because my signed url is a GET url instead of a PUT, that’s really strange because I’ve coded the ‘putObject’.