Dropbox file chooser integration

I'm curious if anyone (else) has successfully implemented a Dropbox Chooser from within a Retool app for seamless file-link-fetching into a text input component.

I've managed to accomplish this (with some sweat, trial & error, and scotch tape), and have a draft "How-To" nearly ready to go – buuut it's kind of a beast, and I'm somewhat hesitant to share it :grimacing:. I was surprised to not find any (closely) related forum threads; I was expecting it to be a somewhat common functionality that Retool users would want. That's why I'm curious if anyone else has done the same/similar before subjecting the forum to my version of it, and/or is there interest for this?

Hi @Schteevynn , can you share how you get Dropbox Chooser implement please? I am building an internal tool for my team, and we need to search our DB for images.
Thanks!

Sure @Jagerbom, I'm happy to share. I wrote this up a couple months ago:

Here's an example of the Dropbox chooser popup after clicking one of the buttons shown above:

After you find and select the desired file and click Choose, the popup closes and the URL populates itself into the text input. Nice! But how?

This solution combines the Retool Custom Component and the Dropbox Chooser. I suggest reading through both!

I certainly don't claim the following to be comprehensive – this entailed a few hours of experimentation, and there are lot of variables involved (not to mention personal preferences) – but I hope it's enough to convey the gist of it.

The Dropbox Chooser docs refer to an "app key" – ultimately, you'll need an app key generated from the organization that will be browsing its own Dropbox files. That may be the same as your dropbox account if you are part of that org's dropbox account, or not (e.g. if you're a freelancer). Something to keep in mind.

A few notes for when you're in the "Create a Dropbox app" page on Dropbox:

You also don't want "multiselect" enabled for your Chooser, since you're only grabbing one URL. You probably also want Preview links rather than Direct links, as the latter expire after a few hours.

In your Retool app:

  1. Add a text input field and a custom component to your app. Give 'em good names.

  2. Set the custom component's Model to { "dropboxURL": null }.

  3. For the first dropbox button example shown above (the wide, default "Choose from Dropbox" button), replace the custom component's iFrame code with the following (update yourAppKeyGoesHere with your app key):

<style>
  body { margin: 0; }
</style>

<script type="text/javascript" 
  src="https://www.dropbox.com/static/api/2/dropins.js" 
  id="dropboxjs" 
  data-app-key="yourAppKeyGoesHere">
</script>

<script>

var options = { 
  success: function(files) {
        window.Retool.modelUpdate({ dropboxURL: files[0].link })
    },
  multiselect: false
};
var button = Dropbox.createChooseButton(options);
document.getElementById("dropbox").appendChild(button);

</script>

<div id="dropbox"></div>

I wanted a more compact solution (second button example shown above), so I used this as the iFrame code (again, note the yourAppKeyGoesHere):

<style>
  body { margin: 0; display: flex; align-items: center; }
  img:hover { background: #ffffff; }
</style>

<script type="text/javascript"
  src="https://www.dropbox.com/static/api/2/dropins.js"
  id="dropboxjs"
  data-app-key="yourAppKeyGoesHere">
</script>

<script>
var options = { 
  success: function(files) {
        window.Retool.modelUpdate({ dropboxURL: files[0].link })
    },
  multiselect: false
};
</script>

<img src="https://cfl.dropboxstatic.com/static/images/logo_catalog/dropbox_logo_glyph_m1.svg" style="height: 1.1em;" onClick="Dropbox.choose(options)" />

For either approach, toggle on the custom component's "Allow popups to escape sandbox" and "Allow same origin."

  1. Set the text input's default value to be the custom component's model value (this will pop the URL into the text field as soon as the custom component's model is updated by the Chooser):

Screen Shot 2022-04-25 at 12.51.25 PM

This should result in a functioning Dropbox Chooser -> text input field implementation.

The Catch

After some successful use, we noticed that the dropboxURL value in the custom component's Model can hang around and cause some unexpected behavior if the text input field is part of a form that is linked to a table that has a "select row to edit" functionality. Basically, the form is trying to default a value into the text input from the table's selected row while the text input is simultaneously trying to default in a lingering value from the custom component's Model.

The solution for this was two-pronged. First, routinely null the Model's value any time the table's selection is changed or cleared (this seems to cover the scenarios when you want to dump that value, YMMV); second, when there is a value in the custom component's model (i.e. you have just chosen a new URL from the Chooser), break the link between any existing value in the table's selected row and the text input, thus allowing the just-picked new URL to overwrite the existing value from the table:

Table component:

Text input component:

Screen Shot 2022-04-25 at 3.09.40 PM


The above is working well for our specific use cases – I hope it is helpful for you!

2 Likes

I really appreciate your effort for writing such a detailed instruction, as well as your willingness to share your knowledge.
I am new to Retool and this is an important tool for my team, this could save us so much time and effort.
If I found anything that I could improve, I would let you know as well.

1 Like

Hello Schteevynn,

Thank you very much for this, it is working!

Do you know how to send a file to dropbox from Retool? Say from an image input

Thanks!
H

Hey @Hugh_O_Keeffe!

Is this something you're still investigating? I imagine you might try using the Dropbox API along with a REST query, curious to know if that would fit your use case.

This is the code I am trying to work with but not working, I don't understand where I am going wrong

<script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="MY_APP_KEY"></script>

<script>
  function uploadFile(files) {
    var file = files[0]; // Get the first file from the selected files

    var accessToken = 'MY_ACCESS_TOKEN'; // Replace with your access token

    var dbx = new Dropbox.Dropbox({ accessToken: accessToken });
    dbx.filesUpload({ path: '/' + file.name, contents: file })
      .then(function (response) {
        console.log('File uploaded successfully!', response);
      })
      .catch(function (error) {
        console.error('Error uploading file.', error);
      });
  }
</script>

<input type="file" id="fileInput" onchange="uploadFile(this.files)" />

Hey @Hugh_O_Keeffe!

Based on that code it looks like you're using the Dropbox Chooser and I'm not sure you can actually upload files with that :thinking: I was thinking you might try using this endpoint specifically:

With that, you'd upload your files to a Retool File Input or similar component and then trigger the query that actually uploads the file.

The API is typically authenticated using OAuth, and Dropbox has a guide on setting that up here. You can also read more about how to set up OAuth on the Retool side in these docs. The screenshot above uses a generated access token that's good for testing but the token has a limited lifespan so if the setup does end up working out for you, you'll probably want to set up a full OAuth flow.

Does that look like it may work for you?

Thanks for this. It works perfectly.

Is there any way to get the folder location instead of file? I would like to include the Dropbox folder url into my app.

Thanks

Hi @Dhani , hmm, I don't see any method to retrieve folder links, it looks like it only works for file links. The documentation for the Chooser doesn't mention folders or directories either. Perhaps submit a feature request to Dropbox?

Hi Schteevynn,

Thanks for the reply. Well I think I have to live with it.
I can manually copy and paste the DB folder link to my Retool form.

Thanks