N
n8n Store
Workflow Market
Upload & Categorize Files with Supabase Storage and Secure URL Generation

Upload & Categorize Files with Supabase Storage and Secure URL Generation

by jwa910 views

Description

Categories

🔧 Engineering🤖 AI & Machine Learning

Nodes Used

n8n-nodes-base.setn8n-nodes-base.setn8n-nodes-base.setn8n-nodes-base.setn8n-nodes-base.setn8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.stickyNote
PriceGratuit
Views0
Last Updated11/28/2025
workflow.json
{
  "meta": {
    "instanceId": "1eec3d74182f3fda9f29f20c85422320a70882840e1b07acd098d5b4a836392a",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "ece7684b-64fa-4c80-9697-c6e7a4999eeb",
      "name": "When Executed by Another Workflow",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -1420,
        620
      ],
      "parameters": {
        "workflowInputs": {
          "values": [
            {
              "name": "mime_type"
            },
            {
              "name": "original_filename"
            },
            {
              "name": "binary_data_base64"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "6d600da3-a9e7-4015-bc73-a0fb5e400724",
      "name": "Prepare Upload Data",
      "type": "n8n-nodes-base.set",
      "position": [
        -940,
        440
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "bucket-mapping",
              "name": "bucket_name",
              "type": "string",
              "value": "={{ \n  (() => {\n    const mimeType = $json.mime_type || 'application/octet-stream';\n    if (mimeType.startsWith('image/')) return 'image-files';\n    if (mimeType.startsWith('audio/')) return 'audio-files';\n    if (mimeType.startsWith('video/')) return 'video-files';\n    return 'document-files';\n  })()\n}}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "5b5b91e9-b082-4d57-a191-c0fd71c84eae",
      "name": "Success Response",
      "type": "n8n-nodes-base.set",
      "position": [
        200,
        440
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "action-type",
              "name": "action",
              "type": "string",
              "value": "s3_upload"
            },
            {
              "id": "success-status",
              "name": "status",
              "type": "string",
              "value": "success"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "aa6355d3-5c2e-4b55-9f04-fcd1f5246428",
      "name": "Convert to File",
      "type": "n8n-nodes-base.convertToFile",
      "notes": "Instead of the code note i would prefer to use the n8n dedicated note for this. only thing i am not sure of now is if i map the fields correct. ",
      "position": [
        -720,
        440
      ],
      "parameters": {
        "options": {
          "fileName": "={{ $json.original_filename }}",
          "mimeType": "={{ $json.mime_type }}"
        },
        "operation": "toBinary",
        "sourceProperty": "binary_data_base64"
      },
      "typeVersion": 1.1
    },
    {
      "id": "2c1f3cf0-3726-4dd9-9121-e060e684d633",
      "name": "temp form to test workflow",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -1420,
        300
      ],
      "webhookId": "1ccfd79e-c611-46e5-90c9-4f84d54ee1af",
      "parameters": {
        "options": {
          "path": "action-workflows-testform",
          "appendAttribution": false
        },
        "formTitle": "test workflow form",
        "formFields": {
          "values": [
            {
              "fieldLabel": "original_filename",
              "requiredField": true
            },
            {
              "fieldType": "textarea",
              "fieldLabel": "binary_data_base64",
              "requiredField": true
            },
            {
              "fieldLabel": "mime_type"
            }
          ]
        },
        "formDescription": "use this form to test action workflows without having to use another workflow"
      },
      "typeVersion": 2.2
    },
    {
      "id": "64932e5f-b7fc-46ad-9946-41703fec5823",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1800,
        -100
      ],
      "parameters": {
        "color": 4,
        "width": 1100,
        "height": 260,
        "content": "## 📦 Upload files to Supabase Storage\n\n- Link to [Supabase docs](https://supabase.com/docs/guides/storage)\n\nThis workflow shows how you could upload files to a Supabase Storage Instance. It's primarily designed to be called by other workflows, as there wasn't a default node for this yet, and this could be usefull in quite a lot of other workflows. \n\nIn this particular example we use mime-type to sort files to specific buckets, but this is of course dependent on your specific storage structure. \n\nThe output is a signed url for the object, to avoid having to share secrets for entire buckets to applications that need the object as input"
      },
      "typeVersion": 1
    },
    {
      "id": "96202c5f-d481-4b20-a526-7ba0c79396a1",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1800,
        180
      ],
      "parameters": {
        "width": 340,
        "height": 340,
        "content": "## 🧪  Quick Test Form during building\n\n\nThis form allowed me to quickly check this flow without having to execute another workflow.\n\nOf course you could also pin data, but given the fact i wanted to check different filetypes i opted for this temporary form, you can populate the base64 field with base64 encoded string of testfile (using for example `base64 -i /path/to/file | pbcopy`)\n\n⚠️ Remove before putting flow live."
      },
      "typeVersion": 1
    },
    {
      "id": "c95e5ad4-0bad-4670-814b-198f51ecb1bb",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1800,
        540
      ],
      "parameters": {
        "color": 3,
        "width": 340,
        "height": 280,
        "content": "## ⚖️ Pro's and Con's of base64 encoding here\n\nI used the encoding step to be able to define input schema in this node below, it comes with a trade off though: file size of base 64 encoded files are 33% larger, also execution data is becoming quite large. \n\n⚠️Carefully consider if this is usable if you are working with large files. "
      },
      "typeVersion": 1
    },
    {
      "id": "36278709-336e-43a7-8f66-6f7b29cdca74",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1020,
        180
      ],
      "parameters": {
        "color": 5,
        "width": 460,
        "height": 240,
        "content": "## 🔧Highlevel dataprep explanation\n\n\n**Prepare Upload Data:** maps inputs to buckets based on mimetype - passes through all other inputs.\n\n**Convert to file:** converts base64 encoded files back to actual files. (see red sticky node at start)"
      },
      "typeVersion": 1
    },
    {
      "id": "0a2490ad-78ce-4252-884d-900e9848d865",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -540,
        180
      ],
      "parameters": {
        "color": 6,
        "width": 640,
        "height": 240,
        "content": "## 🔑 About Supabase Storage\n\nSupabase Storage uses HTTP API with Bearer token authentication, not traditional AWS S3 SDK protocols.\n\nIn this set up we use an anon key/service key. We dont want to use that key all the time, so we generate a signed url to the object.\n\n⚠️ Replace the url in these nodes with your own."
      },
      "typeVersion": 1
    },
    {
      "id": "309c7e12-bcfa-4756-85e8-2d54639296a6",
      "name": "Upload to Supabase Storage",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        -460,
        440
      ],
      "parameters": {
        "url": "=https://api-sb.janwillemaltink.com/storage/v1/object/{{ $('Prepare Upload Data').item.json.bucket_name }}/{{ $('Prepare Upload Data').item.json.original_filename }}",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "binaryData",
        "authentication": "predefinedCredentialType",
        "inputDataFieldName": "data",
        "nodeCredentialType": "supabaseApi"
      },
      "credentials": {
        "supabaseApi": {
          "id": "rpq8Z0VD0KxUEfDd",
          "name": "Supabase account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "ad17d932-adc3-4a93-8e02-1f52fe8a8196",
      "name": "Generate Signed Url",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        -220,
        440
      ],
      "parameters": {
        "url": "=https://api-sb.janwillemaltink.com/storage/v1/object/sign/{{ $json.Key }}",
        "method": "POST",
        "options": {},
        "jsonBody": "{\n\t\"expiresIn\": 2592000\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "supabaseApi"
      },
      "credentials": {
        "supabaseApi": {
          "id": "rpq8Z0VD0KxUEfDd",
          "name": "Supabase account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9be14ebe-84f1-4d91-8c54-392fabf89c05",
      "name": "Upload Error Response",
      "type": "n8n-nodes-base.set",
      "position": [
        -260,
        620
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "action-type-error",
              "name": "action",
              "type": "string",
              "value": "supabase_upload"
            },
            {
              "id": "error-status",
              "name": "status",
              "type": "string",
              "value": "error"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "8dbc6a1e-1a6b-4cc1-ac9f-51fe38c386b8",
      "name": "add domain",
      "type": "n8n-nodes-base.set",
      "position": [
        -20,
        440
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d346fd86-3905-4f89-8754-6966c9725a77",
              "name": "full_signedURL",
              "type": "string",
              "value": "=https://api-sb.janwillemaltink.com/storage/v1{{ $json.signedURL }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e21970f6-23d8-4e23-b42b-f5636dd52358",
      "name": "Sign Error Response",
      "type": "n8n-nodes-base.set",
      "position": [
        -20,
        620
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "action-type-error",
              "name": "action",
              "type": "string",
              "value": "supabase_sign"
            },
            {
              "id": "error-status",
              "name": "status",
              "type": "string",
              "value": "error"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    }
  ],
  "pinData": {},
  "connections": {
    "add domain": {
      "main": [
        [
          {
            "node": "Success Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to File": {
      "main": [
        [
          {
            "node": "Upload to Supabase Storage",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Success Response": {
      "main": [
        []
      ]
    },
    "Generate Signed Url": {
      "main": [
        [
          {
            "node": "add domain",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Sign Error Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Upload Data": {
      "main": [
        [
          {
            "node": "Convert to File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to Supabase Storage": {
      "main": [
        [
          {
            "node": "Generate Signed Url",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Upload Error Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "temp form to test workflow": {
      "main": [
        [
          {
            "node": "Prepare Upload Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Executed by Another Workflow": {
      "main": [
        [
          {
            "node": "Prepare Upload Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

相关工作流