[SS Plugin action ] Best way for saving a file in bubble's filesystem

Hi everybody!

I’m currently building a plugin that generates an ics file, and saves it into bubble’s filesystem to send it via email through a workflow.
I achieved to build the action client-side, but now i’m trying to build a SS action and i’m having problems when trying to save the file to bubble’s DB.

On client side, i’m converting the file contents to Base64 and then saving it using
context.uploadContent(fileName<String>, data<B64 String>, uploadContentCallback);

but that’s not available on SS, so i have looked through bubble’s documentation and forum posts and found some possible solutions, but any of them seems as straightfoward as using context.uploadContent. (I already have the file converted into Base64 using node’s Buffer() )

Here are some posts/docs/plugins i’ve gone through:

  1. @vini_brito PDF Conjurer plugin - It saves the file in two steps, using an action to upload the file to a specified workflow,
    Bubble Plugin Editor - PDF Conjurer
    https://www.unlimitedbubbling.dev/docs_public (go to PDF C. SS Manual > steps 15, 16)
  2. Similar to Vini’s Plugin, @lottemint.md follows Bubble’s API Filesystem docs to upload the file in Bubble’s filesystem using a separate Workflow
    Save Base64 encoded file to Bubble - #4 by lottemint.md
  3. Cool post from @aaronsheldon about how Bubble handles files
    Native File Operations in Server Actions
  4. @gaimed Builds an API Call inside his plugin to upload the file to bubble’s filesystem using exposed /fileupload endpoint (i don’t particullary like this because of it being that public to any who has this endpoint)
    Save Base64 encoded file to Bubble - #10 by gaimed
  5. Similar to previous @jaredg uses Bubble’s ApiConnector Plugin to save the file into /fileupload endpoint
    Save Base64 encoded file to Bubble - #16 by jaredg

What approach do you find best to save files? I tried but failed at saving the file temporarily to send it via an email action without filling Bubble’s capacity (like a Blob for example). Is there a way to do this?

Thank you in advance!

Tom

3 Likes

Tom,

Use this plugin or look at this plugin’s source: Better Uploader ☁️ [Free Plugin]

2 Likes

Hi @bubble.trouble ! if i understand right that plugin only works/send data client side, in the plugin code it uses context.uploadContent, i’m looking for a way to upload a file Server Side!

Thanks!

I understand what you mean now. The way to do this on the server side is to hit the infamous unsecured file upload endpoint. See explanation of process here: Native File Operations in Server Actions

And some fun reading for another day: Critical Bubble Vulnerability (Terms of Service Violation) They Don't Seem To Care Enough About

2 Likes

Yes! that’s one of the ways to handle it, i would want to upload the files witout using that public endpoint

I mean, you could do some funny business and keep an open computer at all times with context.uploadContent and use it as a server side …

:wink:

1 Like

hahah, yes, but would like to use a local solution, without needing to get out of Bubble system

1 Like

Update: Here is another cool comment from @sudsy using the creating an own endpoint approach, like Vini does in his PDF Conjurer Plugni (to avoid using the public /savefile endpoint)

Update:

Right now i’m using @vini_brito’s PDF Conjurer approach ( i think is a great solution because it doesnt use the /savefile endpoint ), with a twist, that i think is more straightfoward for users (it doesnt have option for private files)


// makes a request to a custom WF that uploads a Base64 File
// function( string, stringB64, string, string)
  function uploadToBubble( upload_url, file_data, file_input, file_name ) {
        const file = {
        filename: file_name,
        contents: file_data
    };
    
    const uri = upload_url.startsWith('http') ? upload_url : 'https:' + upload_url;
    const method = 'POST';
    const body = { [file_input]: file };
    const json = true;
    
    const options = { uri, method, body, json };
    
    const response = context.request(options);
    
    const responseBody = JSON.stringify(response.body);
    
    const test = responseBody.match(/(https:)?\/\/.*?\.ics/);

    const url = test ? test[0].startsWith('http') ? test[0] : 'https:' + test[0] : "It wasn't possible to find the uploaded file URL"; 
    
    return url; 
    }
// it returns a key:value with the uploaded file url that is generated by a function inside the same action that create the file (in base64 format)

return {fileUrl: uploadToBubble( context.keys["upload_API"], base64data, context.keys["file_field"], 'invite.ics' )}

In the workflow, the plugin creates a B64 encoded file and exposes the url, that can be later used for file operations

The users set up the upload url in the plugin page instead of using a workflow and setting up the upload url each time.

At the end of the workflow i run a ‘garbage collector’ wf as stated here to get rid of unnecessary files in the DB (i need to send the file in an email and then get rid of it, so with this workflow it works like a temporary file)

Be sure to check and use @vini_brito PDF Conjurer plugin that is GREAT and is amazingly documented :star_struck:, it has been a great reference for this.

https://www.unlimitedbubbling.dev/docs_public

1 Like