Library for communicating with Dropbox API v2.
Add this line to your application's Gemfile:
gem 'dropbox_api'
And then execute:
$ bundle
Or install it yourself as:
$ gem install dropbox_api
Please, refer to this gem's custom Dropbox API documentation. Most of the time you'll be checking the available endpoints.
Unfortunately, the documentation at RubyDoc.info is disrecommended because it lacks some nice features that have been added with YARD plugins:
- Each endpoint includes its tests right below the description, this works as an example of its usage.
- All endpoints are shown as methods of the
Client
class, just as you will use them.
Dropbox uses OAuth, in order to use this library from your application you'll have to get an authorization code.
Once you have it, just pass it on client initialization:
DropboxApi::Client.new("VofXAX8D...")
#=> #<DropboxApi::Client ...>
Or set it as an ENV variable called DROPBOX_OAUTH_BEARER
, for example:
ENV["DROPBOX_OAUTH_BEARER"] = "VofXAX8D..."
DropboxApi::Client.new
#=> #<DropboxApi::Client ...>
Note that setting an ENV variable is only a feasible choice if you're only using one account.
The easiest way to obtain an access token is to get it from the Dropbox website. You just need to log in to Dropbox and refer to the developers section, go to My apps and select your application, you may need to create one if you haven't done so yet.
Under your application settings, find section OAuth 2. You'll find a button to generate an access token.
You can obtain an authorization code with this library:
authenticator = DropboxApi::Authenticator.new(CLIENT_ID, CLIENT_SECRET)
authenticator.auth_code.authorize_url #=> "https://www.dropbox.com/..."
# Now you need to open the authorization URL in your browser,
# authorize the application and copy your code.
auth_bearer = authenticator.auth_code.get_token(CODE) #=> #<OAuth2::AccessToken ...>`
auth_bearer.token #=> "VofXAX8D..."
# Keep this token, you'll need it to initialize a `DropboxApi::Client` object
This is what many web applications will use. The process is described in Dropbox's OAuth guide.
If you have a Rails application, you might be interested in this setup guide.
Dropbox introduces, effective on September, 30 2021, a new policy for OAuth2 token based authentication. It impacts all new applications as well as being suggested for existing apps. You can read more about the change applied and how it impacts the authentication proces
In short, the persistent, long lived tokens are being replaced with short lived tokens, which are valid for up to a few hours. With the current approach the application has to revalidate permission by executing a full handshake involving an interactive user to make a new token, which will expire.
Apps that require background ('offline') access but have not yet implemented refresh tokens will be impacted.
To keep “offline” access in the background the application must change authentication strategy and obtain a new token every time the old one expires with a simplified refresh
procedure. The app performing a full token generation (the first step) must ask for special “offline” mode which will generate, except regular authentication, an additional refresh token that can be reused for future quick re-refresh procedures. Thus the refresh token is important and has to be securely stored with the application, as it will be required every time the short term token expires.
To prevent the app to lose connectivity and access to Dropbox resources using the library following changes has to be applied:
Application must replace current fixed token if it has used one with a dynamic, secure store that updates every time a token expires. For that purpose a new class DropboxApi::Token
has been introduced, which implements short lived tokens, and replaces current fixed string approach.
Furthermore overriding the class on your own and implement save_token
method allows to keep tokens within your application secure store or session data, every time needed.
class MyDropboxToken < DropboxApi::Token
def save_token(token)
# Implement your own store method, token is a `Hash` instance in here, easy to serialize:
puts 'Token to be saved somwhere in the database', token
end
end
The application must obtain a new token for “offline use”. In case of use of Authenticator approach, following change has to be applied:
authenticator = DropboxApi::Authenticator.new(CLIENT_ID, CLIENT_SECRET)
# Change 1: ask for offline token type:
authenticator.auth_code.authorize_url(token_access_type: 'offline') #=> "https://www.dropbox.com/..."
# Now you need to open the authorization URL in your browser,
# authorize the application and copy your code.
# Change 2: Use own token to save it
token = MyDropboxToken.from_code(authenticator, CODE) #=> #<DropboxApi::Token ...>`
# First save your data using overriden token implementation:
token.save!
authenticator = DropboxApi::Authenticator.new(DROPBOX_APP_KEY, DROPBOX_APP_SECRET)
# Change 3: Use own class and the deserialized token to intilize the Client:
token_hash = DESERIALIZED_TOKEN_HASH # Implement your own method to load the hash from secure store
token = MyDropboxToken.new(authenticator, token_hash)
# Intialize API with a dynamic Token:
dropbox = DropboxApi::Client.new(token)
# Enjoy the API:
puts dropbox.get_metadata('/Temp/duck.jpg').to_hash
NOTE: When token expires it will automatically call refresh procedure in the background and invoke save_token
method from overriden class, to keep new token secure for the future use.
Once you've initialized a client, for example:
client = DropboxApi::Client.new("VofXAX8D...")
#=> #<DropboxApi::Client ...>
You can perform an API call like this:
result = client.list_folder "/sample_folder"
#=> #<DropboxApi::Results::ListFolderResult>
result.entries
#=> [#<DropboxApi::Metadata::Folder>, #<DropboxApi::Metadata::File>]
result.has_more?
#=> false
The instance of Client
we've initialized is the one you'll be using to
perform API calls. You can check the class' documentation to find
all available endpoints.
If you need to upload files larger than 150MB the default #upload
endpoint
won't work. Instead, you need to start a upload session and upload
the file in small chunks.
To make this easier, the method upload_by_chunks
will handle this for you,
example:
client = DropboxApi::Client.new("VofXAX8D...")
#=> #<DropboxApi::Client ...>
File.open("large_file.avi") do |f|
client.upload_by_chunks "/remote_path.txt", f
end
Check out the method documentation to find out all available options.
This gem depends on oauth2 and faraday.
It has official support for Ruby versions 2.x
.
After checking out the repo, run bin/setup
to install dependencies. Then, run
bin/console
for an interactive prompt that will allow you to experiment.
I recommend you to use a test account other than your main one.
We use VCR to record the HTTP calls to Dropbox, however we sometimes need to
regenerate the cassettes. Let's take list_folder
as an example to show what
would be the procedure to do so:
-
Manually delete the existing cassettes in
spec/fixtures/vcr_cassettes/list_folder/*.yml
. -
Run the task to build the scaffolding in your Dropbox account so the tests will pass. If it doesn't exist you may need to write it yourself, check the
DropboxScaffoldBuilder
class to find all existing scaffold builders.DROPBOX_OAUTH_BEARER=YOUR_AUTH_BEARER rake test:build_scaffold[list_folder]
Note that you'll have to type
rake test:build_scaffold\[list_folder\]
if you usezsh
.You can build all available scaffolds with just
rake test:build_scaffold
. -
Run the tests and the cassettes will be written:
DROPBOX_OAUTH_BEARER=YOUR_AUTH_BEARER rspec spec/endpoints/files/list_folder_spec.rb
The OAuth bearer shouldn't have been recorded in the cassette and it should've been filtered. However, you may want to double check before pushing your updates to Github.
Tip: you can simply run export DROPBOX_OAUTH_BEARER=YOUR_AUTH_BEARER
at
the beginning of your work session so you don't need to prefix it in every
command line.
Any help will be much appreciated. The easiest way to help is to implement one
or more of the endpoints that are still pending. To see how the
endpoints are implemented, check out the lib/dropbox_api/endpoints
folder.