Repository files navigation

Boxr

Gem Version

Boxr is a Ruby client library for the Box V2 Content API. Box employees affectionately refer to one another as Boxers, hence the name of this gem.

The purpose of this gem is to provide a clear, efficient, and intentional method of interacting with the Box Content API. As with any SDK that wraps a REST API, it is important to fully understand the Box Content API at the REST endpoint level. You are strongly encouraged to read through the Box documentation located here.

The full RubyDocs for Boxr can be found here. You are also encouraged to rely heavily on the source code found in the lib/boxr directory of this gem, as well as on the integration tests found here.

Versioning

Boxr follows Semantic Versioning since version 1.5.0

Requirements

This gem requires Ruby 2.0.0 or higher.

Installation

Add this line to your application's Gemfile:

gem'boxr'

And then execute:

$ bundle

Or install it yourself as:

$ gem install boxr

If you're going to be using chunked uploads, you will need to add parallel if you want to upload multiple chunks concurrently (i.e., n_threads > 1). Add to Gemfile:

gem'parallel','~> 1.0'

And then execute:

$ bundle

Or install it yourself as:

$ gem install parallel --version '~> 1.0'

Usage

Super-fast instructions:

  1. go to http://developers.box.com
  2. find or create your Box Content API app for testing
  3. click 'Edit Application'
  4. check the boxes for 'Read and write all files and folders' and 'Manage an enterprise'
  5. click 'Create a developer token'
  6. copy the token and use it in the code below in place of {BOX_DEVELOPER_TOKEN}
require'boxr'client=Boxr::Client.new('{BOX_DEVELOPER_TOKEN}')items=client.folder_items(Boxr::ROOT)items.each{|i| putsi.name}

Creating a client

There are a few different ways to create a Boxr client. The simplest is to use a Box Developer Token (you generate these from your Box app's General Information page). They last for 60 minutes and you don't have to go through OAuth2.

client=Boxr::Client.new('yPDWOvnumUFaKIMrNBg6PGJpWXC0oaFW')# Alternatively, you can set an environment variable called BOX_DEVELOPER_TOKEN to# the value of your current token. By default, Boxr will look for that.client=Boxr::Client.new#uses ENV['BOX_DEVELOPER_TOKEN']

The next way is to use an access token retrieved after going through the OAuth2 process. If your application is going to handle refreshing the tokens in a scheduled way (more on this later) then this is the way to go.

client=Boxr::Client.new('v2eAXqhZ28WIEpIWeAJcmyamLLt77icP')#a valid OAuth2 access token# Boxr will raise an error if this token becomes invalid. It is up to your application to generate# a new pair of access and refresh tokens in a timely manner.

If you want Boxr to automatically refresh the tokens once the access token becomes invalid you can supply a refresh token, along with your client_id and client_secret, and a block that will get invoked when the refresh occurs.

token_refresh_callback=lambda{|access,refresh,identifier| some_method_that_saves_them(access,refresh)}client=Boxr::Client.new('zX3UjFwNerOy5PSWc2WI8aJgMHtAjs8T',refresh_token: 'dvfzfCQoIcRi7r4Yeuar7mZnaghGWexXlX89sBaRy1hS9e5wFroVVOEM6bs0DwPQ',client_id: 'kplh54vfeagt6jmi4kddg4xdswwvrw8y',client_secret: 'sOsm9ZZ8L8svwrn9FsdulLQVwDizKueU',
&token_refresh_callback)# By default Boxr will look for client_id and client_secret in your environment variables as# BOX_CLIENT_ID and BOX_CLIENT_SECRET, respectively. You can omit the two optional parameters above# if those are present.# You can provide another parameter called as_user. Read about what that means here: https://developer.box.com/reference#as-user-1# You can provide yet another parameter called identifier. This can be used, for example, to# hold the id of the user associated with this Boxr client. When the callback is invoked this value# will be provided.

Here's the complete method signature to initialize an instance of Boxr::Client

initialize(access_token=ENV['BOX_DEVELOPER_TOKEN'],refresh_token: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],jwt_private_key: ENV['JWT_PRIVATE_KEY'],jwt_private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],jwt_public_key_id: ENV['JWT_PUBLIC_KEY_ID'],identifier: nil,as_user: nil,
&token_refresh_listener)

A quick example

Before diving into detailed documentation, let's take a look at how to accomplish a simple task with Boxr. This script will find a specific folder given its path, upload a file to that folder, and create an open shared link to that file.

require'boxr'client=Boxr::Client.new#using ENV['BOX_DEVELOPER_TOKEN']folder=client.folder_from_path('/some/directory/structure')file=client.upload_file('test.txt',folder)updated_file=client.create_shared_link_for_file(file,access: :open)puts"Shared Link: #{updated_file.shared_link.url}"

NOTE: Using HTTP mocking libraries for testing

When using HTTP mocking libraries for testing, you may need to set Boxr::BOX_CLIENT to a fresh instance of HTTPClient in your test setup after loading the HTTP mocking library. For example, when using WebMock with RSpec you might could add the following to your RSpec configuration:

RSpec.configuredo |config|
config.before(:suite)doBoxr::BOX_CLIENT=HTTPClient.newendend

Methods

#NOTE: these are all module methods#OAuth methodsBoxr::oauth_url(state,host: "app.box.com",response_type: "code",scope: nil,folder_id: nil,client_id: ENV['BOX_CLIENT_ID'])Boxr::get_tokens(code=nil,grant_type: "authorization_code",assertion: nil,scope: nil,username: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::refresh_tokens(refresh_token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::revoke_tokens(token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])#JWT methodsBoxr::get_enterprise_token(private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::get_user_token(user_id,private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])
folder_from_path(path)folder_from_id(folder_id,fields: [])alias:folder:folder_from_idfolder_items(folder,fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)root_folder_items(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)create_folder(name,parent)update_folder(folder,name: nil,description: nil,parent: nil,shared_link: nil,folder_upload_email_access: nil,owned_by: nil,sync_state: nil,tags: nil,can_non_owners_invite: nil,if_match: nil)move_folder(folder,new_parent,name: nil,if_match: nil)delete_folder(folder,recursive: false,if_match: nil)copy_folder(folder,dest_folder,name: nil)create_shared_link_for_folder(folder,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_folder(folder)trash(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)trashed_folder(folder,fields: [])delete_trashed_folder(folder)restore_trashed_folder(folder,name: nil,parent: nil)
file_from_path(path)file_from_id(file_id,fields: [])alias:file:file_from_iddefembed_url(file,show_download: false,show_annotations: false)alias:embed_link:embed_urlalias:preview_url:embed_urlalias:preview_link:embed_urlupdate_file(file,name: nil,description: nil,parent: nil,shared_link: nil,tags: nil,if_match: nil)lock_file(file,expires_at: nil,is_download_prevented: false,if_match: nil)unlock_file(file,if_match: nil)move_file(file,new_parent,name: nil,if_match: nil)download_file(file,version: nil,follow_redirect: true)download_url(file,version: nil)upload_file(path_to_file,parent,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)upload_file_from_io(io,parent,name:,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)delete_file(file,if_match: nil)upload_new_version_of_file(path_to_file,file,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)upload_new_version_of_file_from_io(io,file,name: nil,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)versions_of_file(file)promote_old_version_of_file(file,file_version)delete_old_version_of_file(file,file_version,if_match: nil)copy_file(file,parent,name: nil)thumbnail(file,min_height: nil,min_width: nil,max_height: nil,max_width: nil)create_shared_link_for_file(file,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_file(file)trashed_file(file,fields: [])delete_trashed_file(file)restore_trashed_file(file,name: nil,parent: nil)
chunked_upload_create_session_new_file(path_to_file,parent,name: nil)chunked_upload_create_session_new_file_from_io(io,parent,name)chunked_upload_create_session_new_version(path_to_file,file,name: nil)chunked_upload_create_session_new_version_from_io(io,file,name)chunked_upload_get_session(session_id)chunked_upload_part(path_to_file,session_id,content_range)chunked_upload_part_from_io(io,session_id,content_range)chunked_upload_list_parts(session_id,limit: nil,offset: nil)chunked_upload_commit(path_to_file,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_commit_from_io(io,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_abort_session(session_id)chunked_upload_file(path_to_file,parent,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_file_from_io(io,parent,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file(path_to_file,file,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file_from_io(io,file,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)
create_web_link(url,parent,name: nil,description: nil)get_web_link(web_link)update_web_link(web_link,url: nil,parent: nil,name: nil,description: nil)delete_web_link(web_link)trashed_web_link(web_link,fields: [])delete_trashed_web_link(web_link)restore_trashed_web_link(web_link,name: nil,parent: nil)
file_comments(file,fields: [],offset: 0,limit: DEFAULT_LIMIT)add_comment_to_file(file,message: nil,tagged_message: nil)reply_to_comment(comment,message: nil,tagged_message: nil)change_comment(comment,message)comment_from_id(comment_id,fields: [])alias:comment:comment_from_iddelete_comment(comment)
folder_collaborations(folder)add_collaboration(folder,accessible_by,role,fields: [],notify: nil)edit_collaboration(collaboration,role: nil,status: nil)remove_collaboration(collaboration)collaboration_from_id(collaboration_id,fields: [],status: nil)alias:collaboration:collaboration_from_idpending_collaborations()
user_events(stream_position,stream_type: :all,limit: 800)enterprise_events(created_after: nil,created_before: nil,stream_position: 0,event_type: nil,limit: 500)enterprise_events_stream(initial_stream_position,event_type: nil,limit: 500,refresh_period: 300)
shared_item(shared_link,shared_link_password: nil)
search(query=nil,scope: nil,file_extensions: [],created_at_range_from_date: nil,created_at_range_to_date: nil,updated_at_range_from_date: nil,updated_at_range_to_date: nil,size_range_lower_bound_bytes: nil,size_range_upper_bound_bytes: nil,owner_user_ids: [],ancestor_folder_ids: [],content_types: [],trash_content: nil,mdfilters: nil,type: nil,limit: 30,offset: 0)
current_user(fields: [])alias:me:current_useruser_from_id(user_id,fields: [])alias:user:user_from_idall_users(filter_term: nil,fields: [],offset: 0,limit: DEFAULT_LIMIT)create_user(name,login: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,is_external_collab_restricted: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_platform_access_only: nil)update_user(user,notify: nil,enterprise: true,name: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_exempt_from_reset_required: nil,is_external_collab_restricted: nil)email_aliases_for_user(user)add_email_alias_for_user(user,email)remove_email_alias_for_user(user,email_alias)delete_user(user,notify: nil,force: nil)move_users_folder(user,source_folder=0,destination_user)
groups(fields: [],offset: 0,limit: DEFAULT_LIMIT)create_group(name)update_group(group,name)alias:rename_group:update_groupdelete_group(group)group_memberships(group,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_user(user,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_me(offset: 0,limit: DEFAULT_LIMIT)group_membership_from_id(membership_id)alias:group_membership:group_membership_from_idadd_user_to_group(user,group,role: nil)update_group_membership(membership,role)delete_group_membership(membership)group_collaborations(group,offset: 0,limit: DEFAULT_LIMIT)
file_tasks(file,fields: [])create_task(file,action: :review,message: nil,due_at: nil)task_from_id(task_id)alias:task:task_from_idupdate_task(task,action: :review,message: nil,due_at: nil)delete_task(task)task_assignments(task)create_task_assignment(task,assign_to: nil,assign_to_login: nil)task_assignment(task)delete_task_assignment(task)update_task_assignment(task,message: nil,resolution_state: nil)
create_metadata(file,metadata,scope: :global,template: :properties)create_folder_metadata(folder,metadata,scope,template)metadata(file,scope: :global,template: :properties)folder_metadata(folder,scope,template)all_metadata(file)all_folder_metadata(folder)update_metadata(file,updates,scope: :global,template: :properties)update_folder_metadata(folder,updates,scope,template)delete_metadata(file,scope: :global,template: :properties)delete_folder_metadata(folder,scope,template)get_enterprise_templatesget_metadata_template_by_name(scope,template_key)get_metadata_template_by_id(template_id)create_metadata_template(display_name,template_key: nil,fields: [],hidden: nil)delete_metadata_template(scope,template_key)
get_watermark_on_file(file)apply_watermark_on_file(file)remove_watermark_on_file(file)get_watermark_on_folder(folder)apply_watermark_on_folder(folder)remove_watermark_on_folder(folder)
create_webhook(target_id,target_type,triggers,address)get_webhooks(marker: nil,limit: nil)get_webhook(webhook_id)update_webhook(webhook_id,attributes)delete_webhook(webhook_id)# When receiving a webhook, it is advised to verify that it was sent by BoxBoxr::WebhookValidator.new(headers,payload,primary_signature_key: primary_signature_key,secondary_signature_key: secondary_signature_key).valid_message?
# Requests creation of zip archive# Returns a download_url and a status_url that can be used to download the archive.## Example: create_zip_download([{ id: '1', type: 'file' }, { id: '2', type: 'folder' }])create_zip_download(items,download_file_name: nil)

Contributing

  1. Fork it ( https://github.com/cburnette/boxr/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

About

A Ruby client library for the Box Content API.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Boxr

Gem Version

Boxr is a Ruby client library for the Box V2 Content API. Box employees affectionately refer to one another as Boxers, hence the name of this gem.

The purpose of this gem is to provide a clear, efficient, and intentional method of interacting with the Box Content API. As with any SDK that wraps a REST API, it is important to fully understand the Box Content API at the REST endpoint level. You are strongly encouraged to read through the Box documentation located here.

The full RubyDocs for Boxr can be found here. You are also encouraged to rely heavily on the source code found in the lib/boxr directory of this gem, as well as on the integration tests found here.

Versioning

Boxr follows Semantic Versioning since version 1.5.0

Requirements

This gem requires Ruby 2.0.0 or higher.

Installation

Add this line to your application's Gemfile:

gem'boxr'

And then execute:

$ bundle

Or install it yourself as:

$ gem install boxr

If you're going to be using chunked uploads, you will need to add parallel if you want to upload multiple chunks concurrently (i.e., n_threads > 1). Add to Gemfile:

gem'parallel','~> 1.0'

And then execute:

$ bundle

Or install it yourself as:

$ gem install parallel --version '~> 1.0'

Usage

Super-fast instructions:

  1. go to http://developers.box.com
  2. find or create your Box Content API app for testing
  3. click 'Edit Application'
  4. check the boxes for 'Read and write all files and folders' and 'Manage an enterprise'
  5. click 'Create a developer token'
  6. copy the token and use it in the code below in place of {BOX_DEVELOPER_TOKEN}
require'boxr'client=Boxr::Client.new('{BOX_DEVELOPER_TOKEN}')items=client.folder_items(Boxr::ROOT)items.each{|i| putsi.name}

Creating a client

There are a few different ways to create a Boxr client. The simplest is to use a Box Developer Token (you generate these from your Box app's General Information page). They last for 60 minutes and you don't have to go through OAuth2.

client=Boxr::Client.new('yPDWOvnumUFaKIMrNBg6PGJpWXC0oaFW')# Alternatively, you can set an environment variable called BOX_DEVELOPER_TOKEN to# the value of your current token. By default, Boxr will look for that.client=Boxr::Client.new#uses ENV['BOX_DEVELOPER_TOKEN']

The next way is to use an access token retrieved after going through the OAuth2 process. If your application is going to handle refreshing the tokens in a scheduled way (more on this later) then this is the way to go.

client=Boxr::Client.new('v2eAXqhZ28WIEpIWeAJcmyamLLt77icP')#a valid OAuth2 access token# Boxr will raise an error if this token becomes invalid. It is up to your application to generate# a new pair of access and refresh tokens in a timely manner.

If you want Boxr to automatically refresh the tokens once the access token becomes invalid you can supply a refresh token, along with your client_id and client_secret, and a block that will get invoked when the refresh occurs.

token_refresh_callback=lambda{|access,refresh,identifier| some_method_that_saves_them(access,refresh)}client=Boxr::Client.new('zX3UjFwNerOy5PSWc2WI8aJgMHtAjs8T',refresh_token: 'dvfzfCQoIcRi7r4Yeuar7mZnaghGWexXlX89sBaRy1hS9e5wFroVVOEM6bs0DwPQ',client_id: 'kplh54vfeagt6jmi4kddg4xdswwvrw8y',client_secret: 'sOsm9ZZ8L8svwrn9FsdulLQVwDizKueU',
&token_refresh_callback)# By default Boxr will look for client_id and client_secret in your environment variables as# BOX_CLIENT_ID and BOX_CLIENT_SECRET, respectively. You can omit the two optional parameters above# if those are present.# You can provide another parameter called as_user. Read about what that means here: https://developer.box.com/reference#as-user-1# You can provide yet another parameter called identifier. This can be used, for example, to# hold the id of the user associated with this Boxr client. When the callback is invoked this value# will be provided.

Here's the complete method signature to initialize an instance of Boxr::Client

initialize(access_token=ENV['BOX_DEVELOPER_TOKEN'],refresh_token: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],jwt_private_key: ENV['JWT_PRIVATE_KEY'],jwt_private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],jwt_public_key_id: ENV['JWT_PUBLIC_KEY_ID'],identifier: nil,as_user: nil,
&token_refresh_listener)

A quick example

Before diving into detailed documentation, let's take a look at how to accomplish a simple task with Boxr. This script will find a specific folder given its path, upload a file to that folder, and create an open shared link to that file.

require'boxr'client=Boxr::Client.new#using ENV['BOX_DEVELOPER_TOKEN']folder=client.folder_from_path('/some/directory/structure')file=client.upload_file('test.txt',folder)updated_file=client.create_shared_link_for_file(file,access: :open)puts"Shared Link: #{updated_file.shared_link.url}"

NOTE: Using HTTP mocking libraries for testing

When using HTTP mocking libraries for testing, you may need to set Boxr::BOX_CLIENT to a fresh instance of HTTPClient in your test setup after loading the HTTP mocking library. For example, when using WebMock with RSpec you might could add the following to your RSpec configuration:

RSpec.configuredo |config|
config.before(:suite)doBoxr::BOX_CLIENT=HTTPClient.newendend

Methods

#NOTE: these are all module methods#OAuth methodsBoxr::oauth_url(state,host: "app.box.com",response_type: "code",scope: nil,folder_id: nil,client_id: ENV['BOX_CLIENT_ID'])Boxr::get_tokens(code=nil,grant_type: "authorization_code",assertion: nil,scope: nil,username: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::refresh_tokens(refresh_token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::revoke_tokens(token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])#JWT methodsBoxr::get_enterprise_token(private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::get_user_token(user_id,private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])
folder_from_path(path)folder_from_id(folder_id,fields: [])alias:folder:folder_from_idfolder_items(folder,fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)root_folder_items(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)create_folder(name,parent)update_folder(folder,name: nil,description: nil,parent: nil,shared_link: nil,folder_upload_email_access: nil,owned_by: nil,sync_state: nil,tags: nil,can_non_owners_invite: nil,if_match: nil)move_folder(folder,new_parent,name: nil,if_match: nil)delete_folder(folder,recursive: false,if_match: nil)copy_folder(folder,dest_folder,name: nil)create_shared_link_for_folder(folder,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_folder(folder)trash(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)trashed_folder(folder,fields: [])delete_trashed_folder(folder)restore_trashed_folder(folder,name: nil,parent: nil)
file_from_path(path)file_from_id(file_id,fields: [])alias:file:file_from_iddefembed_url(file,show_download: false,show_annotations: false)alias:embed_link:embed_urlalias:preview_url:embed_urlalias:preview_link:embed_urlupdate_file(file,name: nil,description: nil,parent: nil,shared_link: nil,tags: nil,if_match: nil)lock_file(file,expires_at: nil,is_download_prevented: false,if_match: nil)unlock_file(file,if_match: nil)move_file(file,new_parent,name: nil,if_match: nil)download_file(file,version: nil,follow_redirect: true)download_url(file,version: nil)upload_file(path_to_file,parent,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)upload_file_from_io(io,parent,name:,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)delete_file(file,if_match: nil)upload_new_version_of_file(path_to_file,file,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)upload_new_version_of_file_from_io(io,file,name: nil,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)versions_of_file(file)promote_old_version_of_file(file,file_version)delete_old_version_of_file(file,file_version,if_match: nil)copy_file(file,parent,name: nil)thumbnail(file,min_height: nil,min_width: nil,max_height: nil,max_width: nil)create_shared_link_for_file(file,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_file(file)trashed_file(file,fields: [])delete_trashed_file(file)restore_trashed_file(file,name: nil,parent: nil)
chunked_upload_create_session_new_file(path_to_file,parent,name: nil)chunked_upload_create_session_new_file_from_io(io,parent,name)chunked_upload_create_session_new_version(path_to_file,file,name: nil)chunked_upload_create_session_new_version_from_io(io,file,name)chunked_upload_get_session(session_id)chunked_upload_part(path_to_file,session_id,content_range)chunked_upload_part_from_io(io,session_id,content_range)chunked_upload_list_parts(session_id,limit: nil,offset: nil)chunked_upload_commit(path_to_file,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_commit_from_io(io,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_abort_session(session_id)chunked_upload_file(path_to_file,parent,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_file_from_io(io,parent,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file(path_to_file,file,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file_from_io(io,file,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)
create_web_link(url,parent,name: nil,description: nil)get_web_link(web_link)update_web_link(web_link,url: nil,parent: nil,name: nil,description: nil)delete_web_link(web_link)trashed_web_link(web_link,fields: [])delete_trashed_web_link(web_link)restore_trashed_web_link(web_link,name: nil,parent: nil)
file_comments(file,fields: [],offset: 0,limit: DEFAULT_LIMIT)add_comment_to_file(file,message: nil,tagged_message: nil)reply_to_comment(comment,message: nil,tagged_message: nil)change_comment(comment,message)comment_from_id(comment_id,fields: [])alias:comment:comment_from_iddelete_comment(comment)
folder_collaborations(folder)add_collaboration(folder,accessible_by,role,fields: [],notify: nil)edit_collaboration(collaboration,role: nil,status: nil)remove_collaboration(collaboration)collaboration_from_id(collaboration_id,fields: [],status: nil)alias:collaboration:collaboration_from_idpending_collaborations()
user_events(stream_position,stream_type: :all,limit: 800)enterprise_events(created_after: nil,created_before: nil,stream_position: 0,event_type: nil,limit: 500)enterprise_events_stream(initial_stream_position,event_type: nil,limit: 500,refresh_period: 300)
shared_item(shared_link,shared_link_password: nil)
search(query=nil,scope: nil,file_extensions: [],created_at_range_from_date: nil,created_at_range_to_date: nil,updated_at_range_from_date: nil,updated_at_range_to_date: nil,size_range_lower_bound_bytes: nil,size_range_upper_bound_bytes: nil,owner_user_ids: [],ancestor_folder_ids: [],content_types: [],trash_content: nil,mdfilters: nil,type: nil,limit: 30,offset: 0)
current_user(fields: [])alias:me:current_useruser_from_id(user_id,fields: [])alias:user:user_from_idall_users(filter_term: nil,fields: [],offset: 0,limit: DEFAULT_LIMIT)create_user(name,login: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,is_external_collab_restricted: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_platform_access_only: nil)update_user(user,notify: nil,enterprise: true,name: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_exempt_from_reset_required: nil,is_external_collab_restricted: nil)email_aliases_for_user(user)add_email_alias_for_user(user,email)remove_email_alias_for_user(user,email_alias)delete_user(user,notify: nil,force: nil)move_users_folder(user,source_folder=0,destination_user)
groups(fields: [],offset: 0,limit: DEFAULT_LIMIT)create_group(name)update_group(group,name)alias:rename_group:update_groupdelete_group(group)group_memberships(group,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_user(user,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_me(offset: 0,limit: DEFAULT_LIMIT)group_membership_from_id(membership_id)alias:group_membership:group_membership_from_idadd_user_to_group(user,group,role: nil)update_group_membership(membership,role)delete_group_membership(membership)group_collaborations(group,offset: 0,limit: DEFAULT_LIMIT)
file_tasks(file,fields: [])create_task(file,action: :review,message: nil,due_at: nil)task_from_id(task_id)alias:task:task_from_idupdate_task(task,action: :review,message: nil,due_at: nil)delete_task(task)task_assignments(task)create_task_assignment(task,assign_to: nil,assign_to_login: nil)task_assignment(task)delete_task_assignment(task)update_task_assignment(task,message: nil,resolution_state: nil)
create_metadata(file,metadata,scope: :global,template: :properties)create_folder_metadata(folder,metadata,scope,template)metadata(file,scope: :global,template: :properties)folder_metadata(folder,scope,template)all_metadata(file)all_folder_metadata(folder)update_metadata(file,updates,scope: :global,template: :properties)update_folder_metadata(folder,updates,scope,template)delete_metadata(file,scope: :global,template: :properties)delete_folder_metadata(folder,scope,template)get_enterprise_templatesget_metadata_template_by_name(scope,template_key)get_metadata_template_by_id(template_id)create_metadata_template(display_name,template_key: nil,fields: [],hidden: nil)delete_metadata_template(scope,template_key)
get_watermark_on_file(file)apply_watermark_on_file(file)remove_watermark_on_file(file)get_watermark_on_folder(folder)apply_watermark_on_folder(folder)remove_watermark_on_folder(folder)
create_webhook(target_id,target_type,triggers,address)get_webhooks(marker: nil,limit: nil)get_webhook(webhook_id)update_webhook(webhook_id,attributes)delete_webhook(webhook_id)# When receiving a webhook, it is advised to verify that it was sent by BoxBoxr::WebhookValidator.new(headers,payload,primary_signature_key: primary_signature_key,secondary_signature_key: secondary_signature_key).valid_message?
# Requests creation of zip archive# Returns a download_url and a status_url that can be used to download the archive.## Example: create_zip_download([{ id: '1', type: 'file' }, { id: '2', type: 'folder' }])create_zip_download(items,download_file_name: nil)

Contributing

  1. Fork it ( https://github.com/cburnette/boxr/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

About

A Ruby client library for the Box Content API.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Boxr

Gem Version

Boxr is a Ruby client library for the Box V2 Content API. Box employees affectionately refer to one another as Boxers, hence the name of this gem.

The purpose of this gem is to provide a clear, efficient, and intentional method of interacting with the Box Content API. As with any SDK that wraps a REST API, it is important to fully understand the Box Content API at the REST endpoint level. You are strongly encouraged to read through the Box documentation located here.

The full RubyDocs for Boxr can be found here. You are also encouraged to rely heavily on the source code found in the lib/boxr directory of this gem, as well as on the integration tests found here.

Versioning

Boxr follows Semantic Versioning since version 1.5.0

Requirements

This gem requires Ruby 2.0.0 or higher.

Installation

Add this line to your application's Gemfile:

gem'boxr'

And then execute:

$ bundle

Or install it yourself as:

$ gem install boxr

If you're going to be using chunked uploads, you will need to add parallel if you want to upload multiple chunks concurrently (i.e., n_threads > 1). Add to Gemfile:

gem'parallel','~> 1.0'

And then execute:

$ bundle

Or install it yourself as:

$ gem install parallel --version '~> 1.0'

Usage

Super-fast instructions:

  1. go to http://developers.box.com
  2. find or create your Box Content API app for testing
  3. click 'Edit Application'
  4. check the boxes for 'Read and write all files and folders' and 'Manage an enterprise'
  5. click 'Create a developer token'
  6. copy the token and use it in the code below in place of {BOX_DEVELOPER_TOKEN}
require'boxr'client=Boxr::Client.new('{BOX_DEVELOPER_TOKEN}')items=client.folder_items(Boxr::ROOT)items.each{|i| putsi.name}

Creating a client

There are a few different ways to create a Boxr client. The simplest is to use a Box Developer Token (you generate these from your Box app's General Information page). They last for 60 minutes and you don't have to go through OAuth2.

client=Boxr::Client.new('yPDWOvnumUFaKIMrNBg6PGJpWXC0oaFW')# Alternatively, you can set an environment variable called BOX_DEVELOPER_TOKEN to# the value of your current token. By default, Boxr will look for that.client=Boxr::Client.new#uses ENV['BOX_DEVELOPER_TOKEN']

The next way is to use an access token retrieved after going through the OAuth2 process. If your application is going to handle refreshing the tokens in a scheduled way (more on this later) then this is the way to go.

client=Boxr::Client.new('v2eAXqhZ28WIEpIWeAJcmyamLLt77icP')#a valid OAuth2 access token# Boxr will raise an error if this token becomes invalid. It is up to your application to generate# a new pair of access and refresh tokens in a timely manner.

If you want Boxr to automatically refresh the tokens once the access token becomes invalid you can supply a refresh token, along with your client_id and client_secret, and a block that will get invoked when the refresh occurs.

token_refresh_callback=lambda{|access,refresh,identifier| some_method_that_saves_them(access,refresh)}client=Boxr::Client.new('zX3UjFwNerOy5PSWc2WI8aJgMHtAjs8T',refresh_token: 'dvfzfCQoIcRi7r4Yeuar7mZnaghGWexXlX89sBaRy1hS9e5wFroVVOEM6bs0DwPQ',client_id: 'kplh54vfeagt6jmi4kddg4xdswwvrw8y',client_secret: 'sOsm9ZZ8L8svwrn9FsdulLQVwDizKueU',
&token_refresh_callback)# By default Boxr will look for client_id and client_secret in your environment variables as# BOX_CLIENT_ID and BOX_CLIENT_SECRET, respectively. You can omit the two optional parameters above# if those are present.# You can provide another parameter called as_user. Read about what that means here: https://developer.box.com/reference#as-user-1# You can provide yet another parameter called identifier. This can be used, for example, to# hold the id of the user associated with this Boxr client. When the callback is invoked this value# will be provided.

Here's the complete method signature to initialize an instance of Boxr::Client

initialize(access_token=ENV['BOX_DEVELOPER_TOKEN'],refresh_token: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],jwt_private_key: ENV['JWT_PRIVATE_KEY'],jwt_private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],jwt_public_key_id: ENV['JWT_PUBLIC_KEY_ID'],identifier: nil,as_user: nil,
&token_refresh_listener)

A quick example

Before diving into detailed documentation, let's take a look at how to accomplish a simple task with Boxr. This script will find a specific folder given its path, upload a file to that folder, and create an open shared link to that file.

require'boxr'client=Boxr::Client.new#using ENV['BOX_DEVELOPER_TOKEN']folder=client.folder_from_path('/some/directory/structure')file=client.upload_file('test.txt',folder)updated_file=client.create_shared_link_for_file(file,access: :open)puts"Shared Link: #{updated_file.shared_link.url}"

NOTE: Using HTTP mocking libraries for testing

When using HTTP mocking libraries for testing, you may need to set Boxr::BOX_CLIENT to a fresh instance of HTTPClient in your test setup after loading the HTTP mocking library. For example, when using WebMock with RSpec you might could add the following to your RSpec configuration:

RSpec.configuredo |config|
config.before(:suite)doBoxr::BOX_CLIENT=HTTPClient.newendend

Methods

#NOTE: these are all module methods#OAuth methodsBoxr::oauth_url(state,host: "app.box.com",response_type: "code",scope: nil,folder_id: nil,client_id: ENV['BOX_CLIENT_ID'])Boxr::get_tokens(code=nil,grant_type: "authorization_code",assertion: nil,scope: nil,username: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::refresh_tokens(refresh_token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::revoke_tokens(token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])#JWT methodsBoxr::get_enterprise_token(private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::get_user_token(user_id,private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])
folder_from_path(path)folder_from_id(folder_id,fields: [])alias:folder:folder_from_idfolder_items(folder,fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)root_folder_items(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)create_folder(name,parent)update_folder(folder,name: nil,description: nil,parent: nil,shared_link: nil,folder_upload_email_access: nil,owned_by: nil,sync_state: nil,tags: nil,can_non_owners_invite: nil,if_match: nil)move_folder(folder,new_parent,name: nil,if_match: nil)delete_folder(folder,recursive: false,if_match: nil)copy_folder(folder,dest_folder,name: nil)create_shared_link_for_folder(folder,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_folder(folder)trash(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)trashed_folder(folder,fields: [])delete_trashed_folder(folder)restore_trashed_folder(folder,name: nil,parent: nil)
file_from_path(path)file_from_id(file_id,fields: [])alias:file:file_from_iddefembed_url(file,show_download: false,show_annotations: false)alias:embed_link:embed_urlalias:preview_url:embed_urlalias:preview_link:embed_urlupdate_file(file,name: nil,description: nil,parent: nil,shared_link: nil,tags: nil,if_match: nil)lock_file(file,expires_at: nil,is_download_prevented: false,if_match: nil)unlock_file(file,if_match: nil)move_file(file,new_parent,name: nil,if_match: nil)download_file(file,version: nil,follow_redirect: true)download_url(file,version: nil)upload_file(path_to_file,parent,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)upload_file_from_io(io,parent,name:,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)delete_file(file,if_match: nil)upload_new_version_of_file(path_to_file,file,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)upload_new_version_of_file_from_io(io,file,name: nil,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)versions_of_file(file)promote_old_version_of_file(file,file_version)delete_old_version_of_file(file,file_version,if_match: nil)copy_file(file,parent,name: nil)thumbnail(file,min_height: nil,min_width: nil,max_height: nil,max_width: nil)create_shared_link_for_file(file,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_file(file)trashed_file(file,fields: [])delete_trashed_file(file)restore_trashed_file(file,name: nil,parent: nil)
chunked_upload_create_session_new_file(path_to_file,parent,name: nil)chunked_upload_create_session_new_file_from_io(io,parent,name)chunked_upload_create_session_new_version(path_to_file,file,name: nil)chunked_upload_create_session_new_version_from_io(io,file,name)chunked_upload_get_session(session_id)chunked_upload_part(path_to_file,session_id,content_range)chunked_upload_part_from_io(io,session_id,content_range)chunked_upload_list_parts(session_id,limit: nil,offset: nil)chunked_upload_commit(path_to_file,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_commit_from_io(io,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_abort_session(session_id)chunked_upload_file(path_to_file,parent,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_file_from_io(io,parent,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file(path_to_file,file,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file_from_io(io,file,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)
create_web_link(url,parent,name: nil,description: nil)get_web_link(web_link)update_web_link(web_link,url: nil,parent: nil,name: nil,description: nil)delete_web_link(web_link)trashed_web_link(web_link,fields: [])delete_trashed_web_link(web_link)restore_trashed_web_link(web_link,name: nil,parent: nil)
file_comments(file,fields: [],offset: 0,limit: DEFAULT_LIMIT)add_comment_to_file(file,message: nil,tagged_message: nil)reply_to_comment(comment,message: nil,tagged_message: nil)change_comment(comment,message)comment_from_id(comment_id,fields: [])alias:comment:comment_from_iddelete_comment(comment)
folder_collaborations(folder)add_collaboration(folder,accessible_by,role,fields: [],notify: nil)edit_collaboration(collaboration,role: nil,status: nil)remove_collaboration(collaboration)collaboration_from_id(collaboration_id,fields: [],status: nil)alias:collaboration:collaboration_from_idpending_collaborations()
user_events(stream_position,stream_type: :all,limit: 800)enterprise_events(created_after: nil,created_before: nil,stream_position: 0,event_type: nil,limit: 500)enterprise_events_stream(initial_stream_position,event_type: nil,limit: 500,refresh_period: 300)
shared_item(shared_link,shared_link_password: nil)
search(query=nil,scope: nil,file_extensions: [],created_at_range_from_date: nil,created_at_range_to_date: nil,updated_at_range_from_date: nil,updated_at_range_to_date: nil,size_range_lower_bound_bytes: nil,size_range_upper_bound_bytes: nil,owner_user_ids: [],ancestor_folder_ids: [],content_types: [],trash_content: nil,mdfilters: nil,type: nil,limit: 30,offset: 0)
current_user(fields: [])alias:me:current_useruser_from_id(user_id,fields: [])alias:user:user_from_idall_users(filter_term: nil,fields: [],offset: 0,limit: DEFAULT_LIMIT)create_user(name,login: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,is_external_collab_restricted: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_platform_access_only: nil)update_user(user,notify: nil,enterprise: true,name: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_exempt_from_reset_required: nil,is_external_collab_restricted: nil)email_aliases_for_user(user)add_email_alias_for_user(user,email)remove_email_alias_for_user(user,email_alias)delete_user(user,notify: nil,force: nil)move_users_folder(user,source_folder=0,destination_user)
groups(fields: [],offset: 0,limit: DEFAULT_LIMIT)create_group(name)update_group(group,name)alias:rename_group:update_groupdelete_group(group)group_memberships(group,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_user(user,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_me(offset: 0,limit: DEFAULT_LIMIT)group_membership_from_id(membership_id)alias:group_membership:group_membership_from_idadd_user_to_group(user,group,role: nil)update_group_membership(membership,role)delete_group_membership(membership)group_collaborations(group,offset: 0,limit: DEFAULT_LIMIT)
file_tasks(file,fields: [])create_task(file,action: :review,message: nil,due_at: nil)task_from_id(task_id)alias:task:task_from_idupdate_task(task,action: :review,message: nil,due_at: nil)delete_task(task)task_assignments(task)create_task_assignment(task,assign_to: nil,assign_to_login: nil)task_assignment(task)delete_task_assignment(task)update_task_assignment(task,message: nil,resolution_state: nil)
create_metadata(file,metadata,scope: :global,template: :properties)create_folder_metadata(folder,metadata,scope,template)metadata(file,scope: :global,template: :properties)folder_metadata(folder,scope,template)all_metadata(file)all_folder_metadata(folder)update_metadata(file,updates,scope: :global,template: :properties)update_folder_metadata(folder,updates,scope,template)delete_metadata(file,scope: :global,template: :properties)delete_folder_metadata(folder,scope,template)get_enterprise_templatesget_metadata_template_by_name(scope,template_key)get_metadata_template_by_id(template_id)create_metadata_template(display_name,template_key: nil,fields: [],hidden: nil)delete_metadata_template(scope,template_key)
get_watermark_on_file(file)apply_watermark_on_file(file)remove_watermark_on_file(file)get_watermark_on_folder(folder)apply_watermark_on_folder(folder)remove_watermark_on_folder(folder)
create_webhook(target_id,target_type,triggers,address)get_webhooks(marker: nil,limit: nil)get_webhook(webhook_id)update_webhook(webhook_id,attributes)delete_webhook(webhook_id)# When receiving a webhook, it is advised to verify that it was sent by BoxBoxr::WebhookValidator.new(headers,payload,primary_signature_key: primary_signature_key,secondary_signature_key: secondary_signature_key).valid_message?
# Requests creation of zip archive# Returns a download_url and a status_url that can be used to download the archive.## Example: create_zip_download([{ id: '1', type: 'file' }, { id: '2', type: 'folder' }])create_zip_download(items,download_file_name: nil)

Contributing

  1. Fork it ( https://github.com/cburnette/boxr/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

About

A Ruby client library for the Box Content API.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Boxr

Gem Version

Boxr is a Ruby client library for the Box V2 Content API. Box employees affectionately refer to one another as Boxers, hence the name of this gem.

The purpose of this gem is to provide a clear, efficient, and intentional method of interacting with the Box Content API. As with any SDK that wraps a REST API, it is important to fully understand the Box Content API at the REST endpoint level. You are strongly encouraged to read through the Box documentation located here.

The full RubyDocs for Boxr can be found here. You are also encouraged to rely heavily on the source code found in the lib/boxr directory of this gem, as well as on the integration tests found here.

Versioning

Boxr follows Semantic Versioning since version 1.5.0

Requirements

This gem requires Ruby 2.0.0 or higher.

Installation

Add this line to your application's Gemfile:

gem'boxr'

And then execute:

$ bundle

Or install it yourself as:

$ gem install boxr

If you're going to be using chunked uploads, you will need to add parallel if you want to upload multiple chunks concurrently (i.e., n_threads > 1). Add to Gemfile:

gem'parallel','~> 1.0'

And then execute:

$ bundle

Or install it yourself as:

$ gem install parallel --version '~> 1.0'

Usage

Super-fast instructions:

  1. go to http://developers.box.com
  2. find or create your Box Content API app for testing
  3. click 'Edit Application'
  4. check the boxes for 'Read and write all files and folders' and 'Manage an enterprise'
  5. click 'Create a developer token'
  6. copy the token and use it in the code below in place of {BOX_DEVELOPER_TOKEN}
require'boxr'client=Boxr::Client.new('{BOX_DEVELOPER_TOKEN}')items=client.folder_items(Boxr::ROOT)items.each{|i| putsi.name}

Creating a client

There are a few different ways to create a Boxr client. The simplest is to use a Box Developer Token (you generate these from your Box app's General Information page). They last for 60 minutes and you don't have to go through OAuth2.

client=Boxr::Client.new('yPDWOvnumUFaKIMrNBg6PGJpWXC0oaFW')# Alternatively, you can set an environment variable called BOX_DEVELOPER_TOKEN to# the value of your current token. By default, Boxr will look for that.client=Boxr::Client.new#uses ENV['BOX_DEVELOPER_TOKEN']

The next way is to use an access token retrieved after going through the OAuth2 process. If your application is going to handle refreshing the tokens in a scheduled way (more on this later) then this is the way to go.

client=Boxr::Client.new('v2eAXqhZ28WIEpIWeAJcmyamLLt77icP')#a valid OAuth2 access token# Boxr will raise an error if this token becomes invalid. It is up to your application to generate# a new pair of access and refresh tokens in a timely manner.

If you want Boxr to automatically refresh the tokens once the access token becomes invalid you can supply a refresh token, along with your client_id and client_secret, and a block that will get invoked when the refresh occurs.

token_refresh_callback=lambda{|access,refresh,identifier| some_method_that_saves_them(access,refresh)}client=Boxr::Client.new('zX3UjFwNerOy5PSWc2WI8aJgMHtAjs8T',refresh_token: 'dvfzfCQoIcRi7r4Yeuar7mZnaghGWexXlX89sBaRy1hS9e5wFroVVOEM6bs0DwPQ',client_id: 'kplh54vfeagt6jmi4kddg4xdswwvrw8y',client_secret: 'sOsm9ZZ8L8svwrn9FsdulLQVwDizKueU',
&token_refresh_callback)# By default Boxr will look for client_id and client_secret in your environment variables as# BOX_CLIENT_ID and BOX_CLIENT_SECRET, respectively. You can omit the two optional parameters above# if those are present.# You can provide another parameter called as_user. Read about what that means here: https://developer.box.com/reference#as-user-1# You can provide yet another parameter called identifier. This can be used, for example, to# hold the id of the user associated with this Boxr client. When the callback is invoked this value# will be provided.

Here's the complete method signature to initialize an instance of Boxr::Client

initialize(access_token=ENV['BOX_DEVELOPER_TOKEN'],refresh_token: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],jwt_private_key: ENV['JWT_PRIVATE_KEY'],jwt_private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],jwt_public_key_id: ENV['JWT_PUBLIC_KEY_ID'],identifier: nil,as_user: nil,
&token_refresh_listener)

A quick example

Before diving into detailed documentation, let's take a look at how to accomplish a simple task with Boxr. This script will find a specific folder given its path, upload a file to that folder, and create an open shared link to that file.

require'boxr'client=Boxr::Client.new#using ENV['BOX_DEVELOPER_TOKEN']folder=client.folder_from_path('/some/directory/structure')file=client.upload_file('test.txt',folder)updated_file=client.create_shared_link_for_file(file,access: :open)puts"Shared Link: #{updated_file.shared_link.url}"

NOTE: Using HTTP mocking libraries for testing

When using HTTP mocking libraries for testing, you may need to set Boxr::BOX_CLIENT to a fresh instance of HTTPClient in your test setup after loading the HTTP mocking library. For example, when using WebMock with RSpec you might could add the following to your RSpec configuration:

RSpec.configuredo |config|
config.before(:suite)doBoxr::BOX_CLIENT=HTTPClient.newendend

Methods

#NOTE: these are all module methods#OAuth methodsBoxr::oauth_url(state,host: "app.box.com",response_type: "code",scope: nil,folder_id: nil,client_id: ENV['BOX_CLIENT_ID'])Boxr::get_tokens(code=nil,grant_type: "authorization_code",assertion: nil,scope: nil,username: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::refresh_tokens(refresh_token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::revoke_tokens(token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])#JWT methodsBoxr::get_enterprise_token(private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::get_user_token(user_id,private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])
folder_from_path(path)folder_from_id(folder_id,fields: [])alias:folder:folder_from_idfolder_items(folder,fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)root_folder_items(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)create_folder(name,parent)update_folder(folder,name: nil,description: nil,parent: nil,shared_link: nil,folder_upload_email_access: nil,owned_by: nil,sync_state: nil,tags: nil,can_non_owners_invite: nil,if_match: nil)move_folder(folder,new_parent,name: nil,if_match: nil)delete_folder(folder,recursive: false,if_match: nil)copy_folder(folder,dest_folder,name: nil)create_shared_link_for_folder(folder,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_folder(folder)trash(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)trashed_folder(folder,fields: [])delete_trashed_folder(folder)restore_trashed_folder(folder,name: nil,parent: nil)
file_from_path(path)file_from_id(file_id,fields: [])alias:file:file_from_iddefembed_url(file,show_download: false,show_annotations: false)alias:embed_link:embed_urlalias:preview_url:embed_urlalias:preview_link:embed_urlupdate_file(file,name: nil,description: nil,parent: nil,shared_link: nil,tags: nil,if_match: nil)lock_file(file,expires_at: nil,is_download_prevented: false,if_match: nil)unlock_file(file,if_match: nil)move_file(file,new_parent,name: nil,if_match: nil)download_file(file,version: nil,follow_redirect: true)download_url(file,version: nil)upload_file(path_to_file,parent,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)upload_file_from_io(io,parent,name:,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)delete_file(file,if_match: nil)upload_new_version_of_file(path_to_file,file,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)upload_new_version_of_file_from_io(io,file,name: nil,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)versions_of_file(file)promote_old_version_of_file(file,file_version)delete_old_version_of_file(file,file_version,if_match: nil)copy_file(file,parent,name: nil)thumbnail(file,min_height: nil,min_width: nil,max_height: nil,max_width: nil)create_shared_link_for_file(file,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_file(file)trashed_file(file,fields: [])delete_trashed_file(file)restore_trashed_file(file,name: nil,parent: nil)
chunked_upload_create_session_new_file(path_to_file,parent,name: nil)chunked_upload_create_session_new_file_from_io(io,parent,name)chunked_upload_create_session_new_version(path_to_file,file,name: nil)chunked_upload_create_session_new_version_from_io(io,file,name)chunked_upload_get_session(session_id)chunked_upload_part(path_to_file,session_id,content_range)chunked_upload_part_from_io(io,session_id,content_range)chunked_upload_list_parts(session_id,limit: nil,offset: nil)chunked_upload_commit(path_to_file,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_commit_from_io(io,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_abort_session(session_id)chunked_upload_file(path_to_file,parent,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_file_from_io(io,parent,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file(path_to_file,file,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file_from_io(io,file,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)
create_web_link(url,parent,name: nil,description: nil)get_web_link(web_link)update_web_link(web_link,url: nil,parent: nil,name: nil,description: nil)delete_web_link(web_link)trashed_web_link(web_link,fields: [])delete_trashed_web_link(web_link)restore_trashed_web_link(web_link,name: nil,parent: nil)
file_comments(file,fields: [],offset: 0,limit: DEFAULT_LIMIT)add_comment_to_file(file,message: nil,tagged_message: nil)reply_to_comment(comment,message: nil,tagged_message: nil)change_comment(comment,message)comment_from_id(comment_id,fields: [])alias:comment:comment_from_iddelete_comment(comment)
folder_collaborations(folder)add_collaboration(folder,accessible_by,role,fields: [],notify: nil)edit_collaboration(collaboration,role: nil,status: nil)remove_collaboration(collaboration)collaboration_from_id(collaboration_id,fields: [],status: nil)alias:collaboration:collaboration_from_idpending_collaborations()
user_events(stream_position,stream_type: :all,limit: 800)enterprise_events(created_after: nil,created_before: nil,stream_position: 0,event_type: nil,limit: 500)enterprise_events_stream(initial_stream_position,event_type: nil,limit: 500,refresh_period: 300)
shared_item(shared_link,shared_link_password: nil)
search(query=nil,scope: nil,file_extensions: [],created_at_range_from_date: nil,created_at_range_to_date: nil,updated_at_range_from_date: nil,updated_at_range_to_date: nil,size_range_lower_bound_bytes: nil,size_range_upper_bound_bytes: nil,owner_user_ids: [],ancestor_folder_ids: [],content_types: [],trash_content: nil,mdfilters: nil,type: nil,limit: 30,offset: 0)
current_user(fields: [])alias:me:current_useruser_from_id(user_id,fields: [])alias:user:user_from_idall_users(filter_term: nil,fields: [],offset: 0,limit: DEFAULT_LIMIT)create_user(name,login: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,is_external_collab_restricted: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_platform_access_only: nil)update_user(user,notify: nil,enterprise: true,name: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_exempt_from_reset_required: nil,is_external_collab_restricted: nil)email_aliases_for_user(user)add_email_alias_for_user(user,email)remove_email_alias_for_user(user,email_alias)delete_user(user,notify: nil,force: nil)move_users_folder(user,source_folder=0,destination_user)
groups(fields: [],offset: 0,limit: DEFAULT_LIMIT)create_group(name)update_group(group,name)alias:rename_group:update_groupdelete_group(group)group_memberships(group,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_user(user,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_me(offset: 0,limit: DEFAULT_LIMIT)group_membership_from_id(membership_id)alias:group_membership:group_membership_from_idadd_user_to_group(user,group,role: nil)update_group_membership(membership,role)delete_group_membership(membership)group_collaborations(group,offset: 0,limit: DEFAULT_LIMIT)
file_tasks(file,fields: [])create_task(file,action: :review,message: nil,due_at: nil)task_from_id(task_id)alias:task:task_from_idupdate_task(task,action: :review,message: nil,due_at: nil)delete_task(task)task_assignments(task)create_task_assignment(task,assign_to: nil,assign_to_login: nil)task_assignment(task)delete_task_assignment(task)update_task_assignment(task,message: nil,resolution_state: nil)
create_metadata(file,metadata,scope: :global,template: :properties)create_folder_metadata(folder,metadata,scope,template)metadata(file,scope: :global,template: :properties)folder_metadata(folder,scope,template)all_metadata(file)all_folder_metadata(folder)update_metadata(file,updates,scope: :global,template: :properties)update_folder_metadata(folder,updates,scope,template)delete_metadata(file,scope: :global,template: :properties)delete_folder_metadata(folder,scope,template)get_enterprise_templatesget_metadata_template_by_name(scope,template_key)get_metadata_template_by_id(template_id)create_metadata_template(display_name,template_key: nil,fields: [],hidden: nil)delete_metadata_template(scope,template_key)
get_watermark_on_file(file)apply_watermark_on_file(file)remove_watermark_on_file(file)get_watermark_on_folder(folder)apply_watermark_on_folder(folder)remove_watermark_on_folder(folder)
create_webhook(target_id,target_type,triggers,address)get_webhooks(marker: nil,limit: nil)get_webhook(webhook_id)update_webhook(webhook_id,attributes)delete_webhook(webhook_id)# When receiving a webhook, it is advised to verify that it was sent by BoxBoxr::WebhookValidator.new(headers,payload,primary_signature_key: primary_signature_key,secondary_signature_key: secondary_signature_key).valid_message?
# Requests creation of zip archive# Returns a download_url and a status_url that can be used to download the archive.## Example: create_zip_download([{ id: '1', type: 'file' }, { id: '2', type: 'folder' }])create_zip_download(items,download_file_name: nil)

Contributing

  1. Fork it ( https://github.com/cburnette/boxr/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

About

A Ruby client library for the Box Content API.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Boxr

Gem Version

Boxr is a Ruby client library for the Box V2 Content API. Box employees affectionately refer to one another as Boxers, hence the name of this gem.

The purpose of this gem is to provide a clear, efficient, and intentional method of interacting with the Box Content API. As with any SDK that wraps a REST API, it is important to fully understand the Box Content API at the REST endpoint level. You are strongly encouraged to read through the Box documentation located here.

The full RubyDocs for Boxr can be found here. You are also encouraged to rely heavily on the source code found in the lib/boxr directory of this gem, as well as on the integration tests found here.

Versioning

Boxr follows Semantic Versioning since version 1.5.0

Requirements

This gem requires Ruby 2.0.0 or higher.

Installation

Add this line to your application's Gemfile:

gem'boxr'

And then execute:

$ bundle

Or install it yourself as:

$ gem install boxr

If you're going to be using chunked uploads, you will need to add parallel if you want to upload multiple chunks concurrently (i.e., n_threads > 1). Add to Gemfile:

gem'parallel','~> 1.0'

And then execute:

$ bundle

Or install it yourself as:

$ gem install parallel --version '~> 1.0'

Usage

Super-fast instructions:

  1. go to http://developers.box.com
  2. find or create your Box Content API app for testing
  3. click 'Edit Application'
  4. check the boxes for 'Read and write all files and folders' and 'Manage an enterprise'
  5. click 'Create a developer token'
  6. copy the token and use it in the code below in place of {BOX_DEVELOPER_TOKEN}
require'boxr'client=Boxr::Client.new('{BOX_DEVELOPER_TOKEN}')items=client.folder_items(Boxr::ROOT)items.each{|i| putsi.name}

Creating a client

There are a few different ways to create a Boxr client. The simplest is to use a Box Developer Token (you generate these from your Box app's General Information page). They last for 60 minutes and you don't have to go through OAuth2.

client=Boxr::Client.new('yPDWOvnumUFaKIMrNBg6PGJpWXC0oaFW')# Alternatively, you can set an environment variable called BOX_DEVELOPER_TOKEN to# the value of your current token. By default, Boxr will look for that.client=Boxr::Client.new#uses ENV['BOX_DEVELOPER_TOKEN']

The next way is to use an access token retrieved after going through the OAuth2 process. If your application is going to handle refreshing the tokens in a scheduled way (more on this later) then this is the way to go.

client=Boxr::Client.new('v2eAXqhZ28WIEpIWeAJcmyamLLt77icP')#a valid OAuth2 access token# Boxr will raise an error if this token becomes invalid. It is up to your application to generate# a new pair of access and refresh tokens in a timely manner.

If you want Boxr to automatically refresh the tokens once the access token becomes invalid you can supply a refresh token, along with your client_id and client_secret, and a block that will get invoked when the refresh occurs.

token_refresh_callback=lambda{|access,refresh,identifier| some_method_that_saves_them(access,refresh)}client=Boxr::Client.new('zX3UjFwNerOy5PSWc2WI8aJgMHtAjs8T',refresh_token: 'dvfzfCQoIcRi7r4Yeuar7mZnaghGWexXlX89sBaRy1hS9e5wFroVVOEM6bs0DwPQ',client_id: 'kplh54vfeagt6jmi4kddg4xdswwvrw8y',client_secret: 'sOsm9ZZ8L8svwrn9FsdulLQVwDizKueU',
&token_refresh_callback)# By default Boxr will look for client_id and client_secret in your environment variables as# BOX_CLIENT_ID and BOX_CLIENT_SECRET, respectively. You can omit the two optional parameters above# if those are present.# You can provide another parameter called as_user. Read about what that means here: https://developer.box.com/reference#as-user-1# You can provide yet another parameter called identifier. This can be used, for example, to# hold the id of the user associated with this Boxr client. When the callback is invoked this value# will be provided.

Here's the complete method signature to initialize an instance of Boxr::Client

initialize(access_token=ENV['BOX_DEVELOPER_TOKEN'],refresh_token: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],jwt_private_key: ENV['JWT_PRIVATE_KEY'],jwt_private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],jwt_public_key_id: ENV['JWT_PUBLIC_KEY_ID'],identifier: nil,as_user: nil,
&token_refresh_listener)

A quick example

Before diving into detailed documentation, let's take a look at how to accomplish a simple task with Boxr. This script will find a specific folder given its path, upload a file to that folder, and create an open shared link to that file.

require'boxr'client=Boxr::Client.new#using ENV['BOX_DEVELOPER_TOKEN']folder=client.folder_from_path('/some/directory/structure')file=client.upload_file('test.txt',folder)updated_file=client.create_shared_link_for_file(file,access: :open)puts"Shared Link: #{updated_file.shared_link.url}"

NOTE: Using HTTP mocking libraries for testing

When using HTTP mocking libraries for testing, you may need to set Boxr::BOX_CLIENT to a fresh instance of HTTPClient in your test setup after loading the HTTP mocking library. For example, when using WebMock with RSpec you might could add the following to your RSpec configuration:

RSpec.configuredo |config|
config.before(:suite)doBoxr::BOX_CLIENT=HTTPClient.newendend

Methods

#NOTE: these are all module methods#OAuth methodsBoxr::oauth_url(state,host: "app.box.com",response_type: "code",scope: nil,folder_id: nil,client_id: ENV['BOX_CLIENT_ID'])Boxr::get_tokens(code=nil,grant_type: "authorization_code",assertion: nil,scope: nil,username: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::refresh_tokens(refresh_token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::revoke_tokens(token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])#JWT methodsBoxr::get_enterprise_token(private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::get_user_token(user_id,private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])
folder_from_path(path)folder_from_id(folder_id,fields: [])alias:folder:folder_from_idfolder_items(folder,fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)root_folder_items(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)create_folder(name,parent)update_folder(folder,name: nil,description: nil,parent: nil,shared_link: nil,folder_upload_email_access: nil,owned_by: nil,sync_state: nil,tags: nil,can_non_owners_invite: nil,if_match: nil)move_folder(folder,new_parent,name: nil,if_match: nil)delete_folder(folder,recursive: false,if_match: nil)copy_folder(folder,dest_folder,name: nil)create_shared_link_for_folder(folder,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_folder(folder)trash(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)trashed_folder(folder,fields: [])delete_trashed_folder(folder)restore_trashed_folder(folder,name: nil,parent: nil)
file_from_path(path)file_from_id(file_id,fields: [])alias:file:file_from_iddefembed_url(file,show_download: false,show_annotations: false)alias:embed_link:embed_urlalias:preview_url:embed_urlalias:preview_link:embed_urlupdate_file(file,name: nil,description: nil,parent: nil,shared_link: nil,tags: nil,if_match: nil)lock_file(file,expires_at: nil,is_download_prevented: false,if_match: nil)unlock_file(file,if_match: nil)move_file(file,new_parent,name: nil,if_match: nil)download_file(file,version: nil,follow_redirect: true)download_url(file,version: nil)upload_file(path_to_file,parent,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)upload_file_from_io(io,parent,name:,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)delete_file(file,if_match: nil)upload_new_version_of_file(path_to_file,file,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)upload_new_version_of_file_from_io(io,file,name: nil,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)versions_of_file(file)promote_old_version_of_file(file,file_version)delete_old_version_of_file(file,file_version,if_match: nil)copy_file(file,parent,name: nil)thumbnail(file,min_height: nil,min_width: nil,max_height: nil,max_width: nil)create_shared_link_for_file(file,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_file(file)trashed_file(file,fields: [])delete_trashed_file(file)restore_trashed_file(file,name: nil,parent: nil)
chunked_upload_create_session_new_file(path_to_file,parent,name: nil)chunked_upload_create_session_new_file_from_io(io,parent,name)chunked_upload_create_session_new_version(path_to_file,file,name: nil)chunked_upload_create_session_new_version_from_io(io,file,name)chunked_upload_get_session(session_id)chunked_upload_part(path_to_file,session_id,content_range)chunked_upload_part_from_io(io,session_id,content_range)chunked_upload_list_parts(session_id,limit: nil,offset: nil)chunked_upload_commit(path_to_file,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_commit_from_io(io,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_abort_session(session_id)chunked_upload_file(path_to_file,parent,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_file_from_io(io,parent,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file(path_to_file,file,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file_from_io(io,file,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)
create_web_link(url,parent,name: nil,description: nil)get_web_link(web_link)update_web_link(web_link,url: nil,parent: nil,name: nil,description: nil)delete_web_link(web_link)trashed_web_link(web_link,fields: [])delete_trashed_web_link(web_link)restore_trashed_web_link(web_link,name: nil,parent: nil)
file_comments(file,fields: [],offset: 0,limit: DEFAULT_LIMIT)add_comment_to_file(file,message: nil,tagged_message: nil)reply_to_comment(comment,message: nil,tagged_message: nil)change_comment(comment,message)comment_from_id(comment_id,fields: [])alias:comment:comment_from_iddelete_comment(comment)
folder_collaborations(folder)add_collaboration(folder,accessible_by,role,fields: [],notify: nil)edit_collaboration(collaboration,role: nil,status: nil)remove_collaboration(collaboration)collaboration_from_id(collaboration_id,fields: [],status: nil)alias:collaboration:collaboration_from_idpending_collaborations()
user_events(stream_position,stream_type: :all,limit: 800)enterprise_events(created_after: nil,created_before: nil,stream_position: 0,event_type: nil,limit: 500)enterprise_events_stream(initial_stream_position,event_type: nil,limit: 500,refresh_period: 300)
shared_item(shared_link,shared_link_password: nil)
search(query=nil,scope: nil,file_extensions: [],created_at_range_from_date: nil,created_at_range_to_date: nil,updated_at_range_from_date: nil,updated_at_range_to_date: nil,size_range_lower_bound_bytes: nil,size_range_upper_bound_bytes: nil,owner_user_ids: [],ancestor_folder_ids: [],content_types: [],trash_content: nil,mdfilters: nil,type: nil,limit: 30,offset: 0)
current_user(fields: [])alias:me:current_useruser_from_id(user_id,fields: [])alias:user:user_from_idall_users(filter_term: nil,fields: [],offset: 0,limit: DEFAULT_LIMIT)create_user(name,login: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,is_external_collab_restricted: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_platform_access_only: nil)update_user(user,notify: nil,enterprise: true,name: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_exempt_from_reset_required: nil,is_external_collab_restricted: nil)email_aliases_for_user(user)add_email_alias_for_user(user,email)remove_email_alias_for_user(user,email_alias)delete_user(user,notify: nil,force: nil)move_users_folder(user,source_folder=0,destination_user)
groups(fields: [],offset: 0,limit: DEFAULT_LIMIT)create_group(name)update_group(group,name)alias:rename_group:update_groupdelete_group(group)group_memberships(group,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_user(user,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_me(offset: 0,limit: DEFAULT_LIMIT)group_membership_from_id(membership_id)alias:group_membership:group_membership_from_idadd_user_to_group(user,group,role: nil)update_group_membership(membership,role)delete_group_membership(membership)group_collaborations(group,offset: 0,limit: DEFAULT_LIMIT)
file_tasks(file,fields: [])create_task(file,action: :review,message: nil,due_at: nil)task_from_id(task_id)alias:task:task_from_idupdate_task(task,action: :review,message: nil,due_at: nil)delete_task(task)task_assignments(task)create_task_assignment(task,assign_to: nil,assign_to_login: nil)task_assignment(task)delete_task_assignment(task)update_task_assignment(task,message: nil,resolution_state: nil)
create_metadata(file,metadata,scope: :global,template: :properties)create_folder_metadata(folder,metadata,scope,template)metadata(file,scope: :global,template: :properties)folder_metadata(folder,scope,template)all_metadata(file)all_folder_metadata(folder)update_metadata(file,updates,scope: :global,template: :properties)update_folder_metadata(folder,updates,scope,template)delete_metadata(file,scope: :global,template: :properties)delete_folder_metadata(folder,scope,template)get_enterprise_templatesget_metadata_template_by_name(scope,template_key)get_metadata_template_by_id(template_id)create_metadata_template(display_name,template_key: nil,fields: [],hidden: nil)delete_metadata_template(scope,template_key)
get_watermark_on_file(file)apply_watermark_on_file(file)remove_watermark_on_file(file)get_watermark_on_folder(folder)apply_watermark_on_folder(folder)remove_watermark_on_folder(folder)
create_webhook(target_id,target_type,triggers,address)get_webhooks(marker: nil,limit: nil)get_webhook(webhook_id)update_webhook(webhook_id,attributes)delete_webhook(webhook_id)# When receiving a webhook, it is advised to verify that it was sent by BoxBoxr::WebhookValidator.new(headers,payload,primary_signature_key: primary_signature_key,secondary_signature_key: secondary_signature_key).valid_message?
# Requests creation of zip archive# Returns a download_url and a status_url that can be used to download the archive.## Example: create_zip_download([{ id: '1', type: 'file' }, { id: '2', type: 'folder' }])create_zip_download(items,download_file_name: nil)

Contributing

  1. Fork it ( https://github.com/cburnette/boxr/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

About

A Ruby client library for the Box Content API.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Boxr

Gem Version

Boxr is a Ruby client library for the Box V2 Content API. Box employees affectionately refer to one another as Boxers, hence the name of this gem.

The purpose of this gem is to provide a clear, efficient, and intentional method of interacting with the Box Content API. As with any SDK that wraps a REST API, it is important to fully understand the Box Content API at the REST endpoint level. You are strongly encouraged to read through the Box documentation located here.

The full RubyDocs for Boxr can be found here. You are also encouraged to rely heavily on the source code found in the lib/boxr directory of this gem, as well as on the integration tests found here.

Versioning

Boxr follows Semantic Versioning since version 1.5.0

Requirements

This gem requires Ruby 2.0.0 or higher.

Installation

Add this line to your application's Gemfile:

gem'boxr'

And then execute:

$ bundle

Or install it yourself as:

$ gem install boxr

If you're going to be using chunked uploads, you will need to add parallel if you want to upload multiple chunks concurrently (i.e., n_threads > 1). Add to Gemfile:

gem'parallel','~> 1.0'

And then execute:

$ bundle

Or install it yourself as:

$ gem install parallel --version '~> 1.0'

Usage

Super-fast instructions:

  1. go to http://developers.box.com
  2. find or create your Box Content API app for testing
  3. click 'Edit Application'
  4. check the boxes for 'Read and write all files and folders' and 'Manage an enterprise'
  5. click 'Create a developer token'
  6. copy the token and use it in the code below in place of {BOX_DEVELOPER_TOKEN}
require'boxr'client=Boxr::Client.new('{BOX_DEVELOPER_TOKEN}')items=client.folder_items(Boxr::ROOT)items.each{|i| putsi.name}

Creating a client

There are a few different ways to create a Boxr client. The simplest is to use a Box Developer Token (you generate these from your Box app's General Information page). They last for 60 minutes and you don't have to go through OAuth2.

client=Boxr::Client.new('yPDWOvnumUFaKIMrNBg6PGJpWXC0oaFW')# Alternatively, you can set an environment variable called BOX_DEVELOPER_TOKEN to# the value of your current token. By default, Boxr will look for that.client=Boxr::Client.new#uses ENV['BOX_DEVELOPER_TOKEN']

The next way is to use an access token retrieved after going through the OAuth2 process. If your application is going to handle refreshing the tokens in a scheduled way (more on this later) then this is the way to go.

client=Boxr::Client.new('v2eAXqhZ28WIEpIWeAJcmyamLLt77icP')#a valid OAuth2 access token# Boxr will raise an error if this token becomes invalid. It is up to your application to generate# a new pair of access and refresh tokens in a timely manner.

If you want Boxr to automatically refresh the tokens once the access token becomes invalid you can supply a refresh token, along with your client_id and client_secret, and a block that will get invoked when the refresh occurs.

token_refresh_callback=lambda{|access,refresh,identifier| some_method_that_saves_them(access,refresh)}client=Boxr::Client.new('zX3UjFwNerOy5PSWc2WI8aJgMHtAjs8T',refresh_token: 'dvfzfCQoIcRi7r4Yeuar7mZnaghGWexXlX89sBaRy1hS9e5wFroVVOEM6bs0DwPQ',client_id: 'kplh54vfeagt6jmi4kddg4xdswwvrw8y',client_secret: 'sOsm9ZZ8L8svwrn9FsdulLQVwDizKueU',
&token_refresh_callback)# By default Boxr will look for client_id and client_secret in your environment variables as# BOX_CLIENT_ID and BOX_CLIENT_SECRET, respectively. You can omit the two optional parameters above# if those are present.# You can provide another parameter called as_user. Read about what that means here: https://developer.box.com/reference#as-user-1# You can provide yet another parameter called identifier. This can be used, for example, to# hold the id of the user associated with this Boxr client. When the callback is invoked this value# will be provided.

Here's the complete method signature to initialize an instance of Boxr::Client

initialize(access_token=ENV['BOX_DEVELOPER_TOKEN'],refresh_token: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],jwt_private_key: ENV['JWT_PRIVATE_KEY'],jwt_private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],jwt_public_key_id: ENV['JWT_PUBLIC_KEY_ID'],identifier: nil,as_user: nil,
&token_refresh_listener)

A quick example

Before diving into detailed documentation, let's take a look at how to accomplish a simple task with Boxr. This script will find a specific folder given its path, upload a file to that folder, and create an open shared link to that file.

require'boxr'client=Boxr::Client.new#using ENV['BOX_DEVELOPER_TOKEN']folder=client.folder_from_path('/some/directory/structure')file=client.upload_file('test.txt',folder)updated_file=client.create_shared_link_for_file(file,access: :open)puts"Shared Link: #{updated_file.shared_link.url}"

NOTE: Using HTTP mocking libraries for testing

When using HTTP mocking libraries for testing, you may need to set Boxr::BOX_CLIENT to a fresh instance of HTTPClient in your test setup after loading the HTTP mocking library. For example, when using WebMock with RSpec you might could add the following to your RSpec configuration:

RSpec.configuredo |config|
config.before(:suite)doBoxr::BOX_CLIENT=HTTPClient.newendend

Methods

#NOTE: these are all module methods#OAuth methodsBoxr::oauth_url(state,host: "app.box.com",response_type: "code",scope: nil,folder_id: nil,client_id: ENV['BOX_CLIENT_ID'])Boxr::get_tokens(code=nil,grant_type: "authorization_code",assertion: nil,scope: nil,username: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::refresh_tokens(refresh_token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::revoke_tokens(token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])#JWT methodsBoxr::get_enterprise_token(private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::get_user_token(user_id,private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])
folder_from_path(path)folder_from_id(folder_id,fields: [])alias:folder:folder_from_idfolder_items(folder,fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)root_folder_items(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)create_folder(name,parent)update_folder(folder,name: nil,description: nil,parent: nil,shared_link: nil,folder_upload_email_access: nil,owned_by: nil,sync_state: nil,tags: nil,can_non_owners_invite: nil,if_match: nil)move_folder(folder,new_parent,name: nil,if_match: nil)delete_folder(folder,recursive: false,if_match: nil)copy_folder(folder,dest_folder,name: nil)create_shared_link_for_folder(folder,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_folder(folder)trash(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)trashed_folder(folder,fields: [])delete_trashed_folder(folder)restore_trashed_folder(folder,name: nil,parent: nil)
file_from_path(path)file_from_id(file_id,fields: [])alias:file:file_from_iddefembed_url(file,show_download: false,show_annotations: false)alias:embed_link:embed_urlalias:preview_url:embed_urlalias:preview_link:embed_urlupdate_file(file,name: nil,description: nil,parent: nil,shared_link: nil,tags: nil,if_match: nil)lock_file(file,expires_at: nil,is_download_prevented: false,if_match: nil)unlock_file(file,if_match: nil)move_file(file,new_parent,name: nil,if_match: nil)download_file(file,version: nil,follow_redirect: true)download_url(file,version: nil)upload_file(path_to_file,parent,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)upload_file_from_io(io,parent,name:,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)delete_file(file,if_match: nil)upload_new_version_of_file(path_to_file,file,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)upload_new_version_of_file_from_io(io,file,name: nil,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)versions_of_file(file)promote_old_version_of_file(file,file_version)delete_old_version_of_file(file,file_version,if_match: nil)copy_file(file,parent,name: nil)thumbnail(file,min_height: nil,min_width: nil,max_height: nil,max_width: nil)create_shared_link_for_file(file,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_file(file)trashed_file(file,fields: [])delete_trashed_file(file)restore_trashed_file(file,name: nil,parent: nil)
chunked_upload_create_session_new_file(path_to_file,parent,name: nil)chunked_upload_create_session_new_file_from_io(io,parent,name)chunked_upload_create_session_new_version(path_to_file,file,name: nil)chunked_upload_create_session_new_version_from_io(io,file,name)chunked_upload_get_session(session_id)chunked_upload_part(path_to_file,session_id,content_range)chunked_upload_part_from_io(io,session_id,content_range)chunked_upload_list_parts(session_id,limit: nil,offset: nil)chunked_upload_commit(path_to_file,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_commit_from_io(io,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_abort_session(session_id)chunked_upload_file(path_to_file,parent,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_file_from_io(io,parent,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file(path_to_file,file,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file_from_io(io,file,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)
create_web_link(url,parent,name: nil,description: nil)get_web_link(web_link)update_web_link(web_link,url: nil,parent: nil,name: nil,description: nil)delete_web_link(web_link)trashed_web_link(web_link,fields: [])delete_trashed_web_link(web_link)restore_trashed_web_link(web_link,name: nil,parent: nil)
file_comments(file,fields: [],offset: 0,limit: DEFAULT_LIMIT)add_comment_to_file(file,message: nil,tagged_message: nil)reply_to_comment(comment,message: nil,tagged_message: nil)change_comment(comment,message)comment_from_id(comment_id,fields: [])alias:comment:comment_from_iddelete_comment(comment)
folder_collaborations(folder)add_collaboration(folder,accessible_by,role,fields: [],notify: nil)edit_collaboration(collaboration,role: nil,status: nil)remove_collaboration(collaboration)collaboration_from_id(collaboration_id,fields: [],status: nil)alias:collaboration:collaboration_from_idpending_collaborations()
user_events(stream_position,stream_type: :all,limit: 800)enterprise_events(created_after: nil,created_before: nil,stream_position: 0,event_type: nil,limit: 500)enterprise_events_stream(initial_stream_position,event_type: nil,limit: 500,refresh_period: 300)
shared_item(shared_link,shared_link_password: nil)
search(query=nil,scope: nil,file_extensions: [],created_at_range_from_date: nil,created_at_range_to_date: nil,updated_at_range_from_date: nil,updated_at_range_to_date: nil,size_range_lower_bound_bytes: nil,size_range_upper_bound_bytes: nil,owner_user_ids: [],ancestor_folder_ids: [],content_types: [],trash_content: nil,mdfilters: nil,type: nil,limit: 30,offset: 0)
current_user(fields: [])alias:me:current_useruser_from_id(user_id,fields: [])alias:user:user_from_idall_users(filter_term: nil,fields: [],offset: 0,limit: DEFAULT_LIMIT)create_user(name,login: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,is_external_collab_restricted: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_platform_access_only: nil)update_user(user,notify: nil,enterprise: true,name: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_exempt_from_reset_required: nil,is_external_collab_restricted: nil)email_aliases_for_user(user)add_email_alias_for_user(user,email)remove_email_alias_for_user(user,email_alias)delete_user(user,notify: nil,force: nil)move_users_folder(user,source_folder=0,destination_user)
groups(fields: [],offset: 0,limit: DEFAULT_LIMIT)create_group(name)update_group(group,name)alias:rename_group:update_groupdelete_group(group)group_memberships(group,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_user(user,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_me(offset: 0,limit: DEFAULT_LIMIT)group_membership_from_id(membership_id)alias:group_membership:group_membership_from_idadd_user_to_group(user,group,role: nil)update_group_membership(membership,role)delete_group_membership(membership)group_collaborations(group,offset: 0,limit: DEFAULT_LIMIT)
file_tasks(file,fields: [])create_task(file,action: :review,message: nil,due_at: nil)task_from_id(task_id)alias:task:task_from_idupdate_task(task,action: :review,message: nil,due_at: nil)delete_task(task)task_assignments(task)create_task_assignment(task,assign_to: nil,assign_to_login: nil)task_assignment(task)delete_task_assignment(task)update_task_assignment(task,message: nil,resolution_state: nil)
create_metadata(file,metadata,scope: :global,template: :properties)create_folder_metadata(folder,metadata,scope,template)metadata(file,scope: :global,template: :properties)folder_metadata(folder,scope,template)all_metadata(file)all_folder_metadata(folder)update_metadata(file,updates,scope: :global,template: :properties)update_folder_metadata(folder,updates,scope,template)delete_metadata(file,scope: :global,template: :properties)delete_folder_metadata(folder,scope,template)get_enterprise_templatesget_metadata_template_by_name(scope,template_key)get_metadata_template_by_id(template_id)create_metadata_template(display_name,template_key: nil,fields: [],hidden: nil)delete_metadata_template(scope,template_key)
get_watermark_on_file(file)apply_watermark_on_file(file)remove_watermark_on_file(file)get_watermark_on_folder(folder)apply_watermark_on_folder(folder)remove_watermark_on_folder(folder)
create_webhook(target_id,target_type,triggers,address)get_webhooks(marker: nil,limit: nil)get_webhook(webhook_id)update_webhook(webhook_id,attributes)delete_webhook(webhook_id)# When receiving a webhook, it is advised to verify that it was sent by BoxBoxr::WebhookValidator.new(headers,payload,primary_signature_key: primary_signature_key,secondary_signature_key: secondary_signature_key).valid_message?
# Requests creation of zip archive# Returns a download_url and a status_url that can be used to download the archive.## Example: create_zip_download([{ id: '1', type: 'file' }, { id: '2', type: 'folder' }])create_zip_download(items,download_file_name: nil)

Contributing

  1. Fork it ( https://github.com/cburnette/boxr/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

About

A Ruby client library for the Box Content API.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Boxr

Gem Version

Boxr is a Ruby client library for the Box V2 Content API. Box employees affectionately refer to one another as Boxers, hence the name of this gem.

The purpose of this gem is to provide a clear, efficient, and intentional method of interacting with the Box Content API. As with any SDK that wraps a REST API, it is important to fully understand the Box Content API at the REST endpoint level. You are strongly encouraged to read through the Box documentation located here.

The full RubyDocs for Boxr can be found here. You are also encouraged to rely heavily on the source code found in the lib/boxr directory of this gem, as well as on the integration tests found here.

Versioning

Boxr follows Semantic Versioning since version 1.5.0

Requirements

This gem requires Ruby 2.0.0 or higher.

Installation

Add this line to your application's Gemfile:

gem'boxr'

And then execute:

$ bundle

Or install it yourself as:

$ gem install boxr

If you're going to be using chunked uploads, you will need to add parallel if you want to upload multiple chunks concurrently (i.e., n_threads > 1). Add to Gemfile:

gem'parallel','~> 1.0'

And then execute:

$ bundle

Or install it yourself as:

$ gem install parallel --version '~> 1.0'

Usage

Super-fast instructions:

  1. go to http://developers.box.com
  2. find or create your Box Content API app for testing
  3. click 'Edit Application'
  4. check the boxes for 'Read and write all files and folders' and 'Manage an enterprise'
  5. click 'Create a developer token'
  6. copy the token and use it in the code below in place of {BOX_DEVELOPER_TOKEN}
require'boxr'client=Boxr::Client.new('{BOX_DEVELOPER_TOKEN}')items=client.folder_items(Boxr::ROOT)items.each{|i| putsi.name}

Creating a client

There are a few different ways to create a Boxr client. The simplest is to use a Box Developer Token (you generate these from your Box app's General Information page). They last for 60 minutes and you don't have to go through OAuth2.

client=Boxr::Client.new('yPDWOvnumUFaKIMrNBg6PGJpWXC0oaFW')# Alternatively, you can set an environment variable called BOX_DEVELOPER_TOKEN to# the value of your current token. By default, Boxr will look for that.client=Boxr::Client.new#uses ENV['BOX_DEVELOPER_TOKEN']

The next way is to use an access token retrieved after going through the OAuth2 process. If your application is going to handle refreshing the tokens in a scheduled way (more on this later) then this is the way to go.

client=Boxr::Client.new('v2eAXqhZ28WIEpIWeAJcmyamLLt77icP')#a valid OAuth2 access token# Boxr will raise an error if this token becomes invalid. It is up to your application to generate# a new pair of access and refresh tokens in a timely manner.

If you want Boxr to automatically refresh the tokens once the access token becomes invalid you can supply a refresh token, along with your client_id and client_secret, and a block that will get invoked when the refresh occurs.

token_refresh_callback=lambda{|access,refresh,identifier| some_method_that_saves_them(access,refresh)}client=Boxr::Client.new('zX3UjFwNerOy5PSWc2WI8aJgMHtAjs8T',refresh_token: 'dvfzfCQoIcRi7r4Yeuar7mZnaghGWexXlX89sBaRy1hS9e5wFroVVOEM6bs0DwPQ',client_id: 'kplh54vfeagt6jmi4kddg4xdswwvrw8y',client_secret: 'sOsm9ZZ8L8svwrn9FsdulLQVwDizKueU',
&token_refresh_callback)# By default Boxr will look for client_id and client_secret in your environment variables as# BOX_CLIENT_ID and BOX_CLIENT_SECRET, respectively. You can omit the two optional parameters above# if those are present.# You can provide another parameter called as_user. Read about what that means here: https://developer.box.com/reference#as-user-1# You can provide yet another parameter called identifier. This can be used, for example, to# hold the id of the user associated with this Boxr client. When the callback is invoked this value# will be provided.

Here's the complete method signature to initialize an instance of Boxr::Client

initialize(access_token=ENV['BOX_DEVELOPER_TOKEN'],refresh_token: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],jwt_private_key: ENV['JWT_PRIVATE_KEY'],jwt_private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],jwt_public_key_id: ENV['JWT_PUBLIC_KEY_ID'],identifier: nil,as_user: nil,
&token_refresh_listener)

A quick example

Before diving into detailed documentation, let's take a look at how to accomplish a simple task with Boxr. This script will find a specific folder given its path, upload a file to that folder, and create an open shared link to that file.

require'boxr'client=Boxr::Client.new#using ENV['BOX_DEVELOPER_TOKEN']folder=client.folder_from_path('/some/directory/structure')file=client.upload_file('test.txt',folder)updated_file=client.create_shared_link_for_file(file,access: :open)puts"Shared Link: #{updated_file.shared_link.url}"

NOTE: Using HTTP mocking libraries for testing

When using HTTP mocking libraries for testing, you may need to set Boxr::BOX_CLIENT to a fresh instance of HTTPClient in your test setup after loading the HTTP mocking library. For example, when using WebMock with RSpec you might could add the following to your RSpec configuration:

RSpec.configuredo |config|
config.before(:suite)doBoxr::BOX_CLIENT=HTTPClient.newendend

Methods

#NOTE: these are all module methods#OAuth methodsBoxr::oauth_url(state,host: "app.box.com",response_type: "code",scope: nil,folder_id: nil,client_id: ENV['BOX_CLIENT_ID'])Boxr::get_tokens(code=nil,grant_type: "authorization_code",assertion: nil,scope: nil,username: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::refresh_tokens(refresh_token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::revoke_tokens(token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])#JWT methodsBoxr::get_enterprise_token(private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::get_user_token(user_id,private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])
folder_from_path(path)folder_from_id(folder_id,fields: [])alias:folder:folder_from_idfolder_items(folder,fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)root_folder_items(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)create_folder(name,parent)update_folder(folder,name: nil,description: nil,parent: nil,shared_link: nil,folder_upload_email_access: nil,owned_by: nil,sync_state: nil,tags: nil,can_non_owners_invite: nil,if_match: nil)move_folder(folder,new_parent,name: nil,if_match: nil)delete_folder(folder,recursive: false,if_match: nil)copy_folder(folder,dest_folder,name: nil)create_shared_link_for_folder(folder,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_folder(folder)trash(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)trashed_folder(folder,fields: [])delete_trashed_folder(folder)restore_trashed_folder(folder,name: nil,parent: nil)
file_from_path(path)file_from_id(file_id,fields: [])alias:file:file_from_iddefembed_url(file,show_download: false,show_annotations: false)alias:embed_link:embed_urlalias:preview_url:embed_urlalias:preview_link:embed_urlupdate_file(file,name: nil,description: nil,parent: nil,shared_link: nil,tags: nil,if_match: nil)lock_file(file,expires_at: nil,is_download_prevented: false,if_match: nil)unlock_file(file,if_match: nil)move_file(file,new_parent,name: nil,if_match: nil)download_file(file,version: nil,follow_redirect: true)download_url(file,version: nil)upload_file(path_to_file,parent,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)upload_file_from_io(io,parent,name:,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)delete_file(file,if_match: nil)upload_new_version_of_file(path_to_file,file,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)upload_new_version_of_file_from_io(io,file,name: nil,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)versions_of_file(file)promote_old_version_of_file(file,file_version)delete_old_version_of_file(file,file_version,if_match: nil)copy_file(file,parent,name: nil)thumbnail(file,min_height: nil,min_width: nil,max_height: nil,max_width: nil)create_shared_link_for_file(file,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_file(file)trashed_file(file,fields: [])delete_trashed_file(file)restore_trashed_file(file,name: nil,parent: nil)
chunked_upload_create_session_new_file(path_to_file,parent,name: nil)chunked_upload_create_session_new_file_from_io(io,parent,name)chunked_upload_create_session_new_version(path_to_file,file,name: nil)chunked_upload_create_session_new_version_from_io(io,file,name)chunked_upload_get_session(session_id)chunked_upload_part(path_to_file,session_id,content_range)chunked_upload_part_from_io(io,session_id,content_range)chunked_upload_list_parts(session_id,limit: nil,offset: nil)chunked_upload_commit(path_to_file,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_commit_from_io(io,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_abort_session(session_id)chunked_upload_file(path_to_file,parent,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_file_from_io(io,parent,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file(path_to_file,file,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file_from_io(io,file,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)
create_web_link(url,parent,name: nil,description: nil)get_web_link(web_link)update_web_link(web_link,url: nil,parent: nil,name: nil,description: nil)delete_web_link(web_link)trashed_web_link(web_link,fields: [])delete_trashed_web_link(web_link)restore_trashed_web_link(web_link,name: nil,parent: nil)
file_comments(file,fields: [],offset: 0,limit: DEFAULT_LIMIT)add_comment_to_file(file,message: nil,tagged_message: nil)reply_to_comment(comment,message: nil,tagged_message: nil)change_comment(comment,message)comment_from_id(comment_id,fields: [])alias:comment:comment_from_iddelete_comment(comment)
folder_collaborations(folder)add_collaboration(folder,accessible_by,role,fields: [],notify: nil)edit_collaboration(collaboration,role: nil,status: nil)remove_collaboration(collaboration)collaboration_from_id(collaboration_id,fields: [],status: nil)alias:collaboration:collaboration_from_idpending_collaborations()
user_events(stream_position,stream_type: :all,limit: 800)enterprise_events(created_after: nil,created_before: nil,stream_position: 0,event_type: nil,limit: 500)enterprise_events_stream(initial_stream_position,event_type: nil,limit: 500,refresh_period: 300)
shared_item(shared_link,shared_link_password: nil)
search(query=nil,scope: nil,file_extensions: [],created_at_range_from_date: nil,created_at_range_to_date: nil,updated_at_range_from_date: nil,updated_at_range_to_date: nil,size_range_lower_bound_bytes: nil,size_range_upper_bound_bytes: nil,owner_user_ids: [],ancestor_folder_ids: [],content_types: [],trash_content: nil,mdfilters: nil,type: nil,limit: 30,offset: 0)
current_user(fields: [])alias:me:current_useruser_from_id(user_id,fields: [])alias:user:user_from_idall_users(filter_term: nil,fields: [],offset: 0,limit: DEFAULT_LIMIT)create_user(name,login: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,is_external_collab_restricted: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_platform_access_only: nil)update_user(user,notify: nil,enterprise: true,name: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_exempt_from_reset_required: nil,is_external_collab_restricted: nil)email_aliases_for_user(user)add_email_alias_for_user(user,email)remove_email_alias_for_user(user,email_alias)delete_user(user,notify: nil,force: nil)move_users_folder(user,source_folder=0,destination_user)
groups(fields: [],offset: 0,limit: DEFAULT_LIMIT)create_group(name)update_group(group,name)alias:rename_group:update_groupdelete_group(group)group_memberships(group,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_user(user,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_me(offset: 0,limit: DEFAULT_LIMIT)group_membership_from_id(membership_id)alias:group_membership:group_membership_from_idadd_user_to_group(user,group,role: nil)update_group_membership(membership,role)delete_group_membership(membership)group_collaborations(group,offset: 0,limit: DEFAULT_LIMIT)
file_tasks(file,fields: [])create_task(file,action: :review,message: nil,due_at: nil)task_from_id(task_id)alias:task:task_from_idupdate_task(task,action: :review,message: nil,due_at: nil)delete_task(task)task_assignments(task)create_task_assignment(task,assign_to: nil,assign_to_login: nil)task_assignment(task)delete_task_assignment(task)update_task_assignment(task,message: nil,resolution_state: nil)
create_metadata(file,metadata,scope: :global,template: :properties)create_folder_metadata(folder,metadata,scope,template)metadata(file,scope: :global,template: :properties)folder_metadata(folder,scope,template)all_metadata(file)all_folder_metadata(folder)update_metadata(file,updates,scope: :global,template: :properties)update_folder_metadata(folder,updates,scope,template)delete_metadata(file,scope: :global,template: :properties)delete_folder_metadata(folder,scope,template)get_enterprise_templatesget_metadata_template_by_name(scope,template_key)get_metadata_template_by_id(template_id)create_metadata_template(display_name,template_key: nil,fields: [],hidden: nil)delete_metadata_template(scope,template_key)
get_watermark_on_file(file)apply_watermark_on_file(file)remove_watermark_on_file(file)get_watermark_on_folder(folder)apply_watermark_on_folder(folder)remove_watermark_on_folder(folder)
create_webhook(target_id,target_type,triggers,address)get_webhooks(marker: nil,limit: nil)get_webhook(webhook_id)update_webhook(webhook_id,attributes)delete_webhook(webhook_id)# When receiving a webhook, it is advised to verify that it was sent by BoxBoxr::WebhookValidator.new(headers,payload,primary_signature_key: primary_signature_key,secondary_signature_key: secondary_signature_key).valid_message?
# Requests creation of zip archive# Returns a download_url and a status_url that can be used to download the archive.## Example: create_zip_download([{ id: '1', type: 'file' }, { id: '2', type: 'folder' }])create_zip_download(items,download_file_name: nil)

Contributing

  1. Fork it ( https://github.com/cburnette/boxr/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

About

A Ruby client library for the Box Content API.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Boxr

Gem Version

Boxr is a Ruby client library for the Box V2 Content API. Box employees affectionately refer to one another as Boxers, hence the name of this gem.

The purpose of this gem is to provide a clear, efficient, and intentional method of interacting with the Box Content API. As with any SDK that wraps a REST API, it is important to fully understand the Box Content API at the REST endpoint level. You are strongly encouraged to read through the Box documentation located here.

The full RubyDocs for Boxr can be found here. You are also encouraged to rely heavily on the source code found in the lib/boxr directory of this gem, as well as on the integration tests found here.

Versioning

Boxr follows Semantic Versioning since version 1.5.0

Requirements

This gem requires Ruby 2.0.0 or higher.

Installation

Add this line to your application's Gemfile:

gem'boxr'

And then execute:

$ bundle

Or install it yourself as:

$ gem install boxr

If you're going to be using chunked uploads, you will need to add parallel if you want to upload multiple chunks concurrently (i.e., n_threads > 1). Add to Gemfile:

gem'parallel','~> 1.0'

And then execute:

$ bundle

Or install it yourself as:

$ gem install parallel --version '~> 1.0'

Usage

Super-fast instructions:

  1. go to http://developers.box.com
  2. find or create your Box Content API app for testing
  3. click 'Edit Application'
  4. check the boxes for 'Read and write all files and folders' and 'Manage an enterprise'
  5. click 'Create a developer token'
  6. copy the token and use it in the code below in place of {BOX_DEVELOPER_TOKEN}
require'boxr'client=Boxr::Client.new('{BOX_DEVELOPER_TOKEN}')items=client.folder_items(Boxr::ROOT)items.each{|i| putsi.name}

Creating a client

There are a few different ways to create a Boxr client. The simplest is to use a Box Developer Token (you generate these from your Box app's General Information page). They last for 60 minutes and you don't have to go through OAuth2.

client=Boxr::Client.new('yPDWOvnumUFaKIMrNBg6PGJpWXC0oaFW')# Alternatively, you can set an environment variable called BOX_DEVELOPER_TOKEN to# the value of your current token. By default, Boxr will look for that.client=Boxr::Client.new#uses ENV['BOX_DEVELOPER_TOKEN']

The next way is to use an access token retrieved after going through the OAuth2 process. If your application is going to handle refreshing the tokens in a scheduled way (more on this later) then this is the way to go.

client=Boxr::Client.new('v2eAXqhZ28WIEpIWeAJcmyamLLt77icP')#a valid OAuth2 access token# Boxr will raise an error if this token becomes invalid. It is up to your application to generate# a new pair of access and refresh tokens in a timely manner.

If you want Boxr to automatically refresh the tokens once the access token becomes invalid you can supply a refresh token, along with your client_id and client_secret, and a block that will get invoked when the refresh occurs.

token_refresh_callback=lambda{|access,refresh,identifier| some_method_that_saves_them(access,refresh)}client=Boxr::Client.new('zX3UjFwNerOy5PSWc2WI8aJgMHtAjs8T',refresh_token: 'dvfzfCQoIcRi7r4Yeuar7mZnaghGWexXlX89sBaRy1hS9e5wFroVVOEM6bs0DwPQ',client_id: 'kplh54vfeagt6jmi4kddg4xdswwvrw8y',client_secret: 'sOsm9ZZ8L8svwrn9FsdulLQVwDizKueU',
&token_refresh_callback)# By default Boxr will look for client_id and client_secret in your environment variables as# BOX_CLIENT_ID and BOX_CLIENT_SECRET, respectively. You can omit the two optional parameters above# if those are present.# You can provide another parameter called as_user. Read about what that means here: https://developer.box.com/reference#as-user-1# You can provide yet another parameter called identifier. This can be used, for example, to# hold the id of the user associated with this Boxr client. When the callback is invoked this value# will be provided.

Here's the complete method signature to initialize an instance of Boxr::Client

initialize(access_token=ENV['BOX_DEVELOPER_TOKEN'],refresh_token: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],jwt_private_key: ENV['JWT_PRIVATE_KEY'],jwt_private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],jwt_public_key_id: ENV['JWT_PUBLIC_KEY_ID'],identifier: nil,as_user: nil,
&token_refresh_listener)

A quick example

Before diving into detailed documentation, let's take a look at how to accomplish a simple task with Boxr. This script will find a specific folder given its path, upload a file to that folder, and create an open shared link to that file.

require'boxr'client=Boxr::Client.new#using ENV['BOX_DEVELOPER_TOKEN']folder=client.folder_from_path('/some/directory/structure')file=client.upload_file('test.txt',folder)updated_file=client.create_shared_link_for_file(file,access: :open)puts"Shared Link: #{updated_file.shared_link.url}"

NOTE: Using HTTP mocking libraries for testing

When using HTTP mocking libraries for testing, you may need to set Boxr::BOX_CLIENT to a fresh instance of HTTPClient in your test setup after loading the HTTP mocking library. For example, when using WebMock with RSpec you might could add the following to your RSpec configuration:

RSpec.configuredo |config|
config.before(:suite)doBoxr::BOX_CLIENT=HTTPClient.newendend

Methods

#NOTE: these are all module methods#OAuth methodsBoxr::oauth_url(state,host: "app.box.com",response_type: "code",scope: nil,folder_id: nil,client_id: ENV['BOX_CLIENT_ID'])Boxr::get_tokens(code=nil,grant_type: "authorization_code",assertion: nil,scope: nil,username: nil,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::refresh_tokens(refresh_token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::revoke_tokens(token,client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])#JWT methodsBoxr::get_enterprise_token(private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],enterprise_id: ENV['BOX_ENTERPRISE_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])Boxr::get_user_token(user_id,private_key: ENV['JWT_PRIVATE_KEY'],private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],public_key_id: ENV['JWT_PUBLIC_KEY_ID'],client_id: ENV['BOX_CLIENT_ID'],client_secret: ENV['BOX_CLIENT_SECRET'])
folder_from_path(path)folder_from_id(folder_id,fields: [])alias:folder:folder_from_idfolder_items(folder,fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)root_folder_items(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)create_folder(name,parent)update_folder(folder,name: nil,description: nil,parent: nil,shared_link: nil,folder_upload_email_access: nil,owned_by: nil,sync_state: nil,tags: nil,can_non_owners_invite: nil,if_match: nil)move_folder(folder,new_parent,name: nil,if_match: nil)delete_folder(folder,recursive: false,if_match: nil)copy_folder(folder,dest_folder,name: nil)create_shared_link_for_folder(folder,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_folder(folder)trash(fields: [],offset: 0,limit: FOLDER_ITEMS_LIMIT)trashed_folder(folder,fields: [])delete_trashed_folder(folder)restore_trashed_folder(folder,name: nil,parent: nil)
file_from_path(path)file_from_id(file_id,fields: [])alias:file:file_from_iddefembed_url(file,show_download: false,show_annotations: false)alias:embed_link:embed_urlalias:preview_url:embed_urlalias:preview_link:embed_urlupdate_file(file,name: nil,description: nil,parent: nil,shared_link: nil,tags: nil,if_match: nil)lock_file(file,expires_at: nil,is_download_prevented: false,if_match: nil)unlock_file(file,if_match: nil)move_file(file,new_parent,name: nil,if_match: nil)download_file(file,version: nil,follow_redirect: true)download_url(file,version: nil)upload_file(path_to_file,parent,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)upload_file_from_io(io,parent,name:,content_created_at: nil,content_modified_at: nil,preflight_check: true,send_content_md5: true)delete_file(file,if_match: nil)upload_new_version_of_file(path_to_file,file,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)upload_new_version_of_file_from_io(io,file,name: nil,content_modified_at: nil,send_content_md5: true,preflight_check: true,if_match: nil)versions_of_file(file)promote_old_version_of_file(file,file_version)delete_old_version_of_file(file,file_version,if_match: nil)copy_file(file,parent,name: nil)thumbnail(file,min_height: nil,min_width: nil,max_height: nil,max_width: nil)create_shared_link_for_file(file,access: nil,unshared_at: nil,can_download: nil,can_preview: nil,password: nil)disable_shared_link_for_file(file)trashed_file(file,fields: [])delete_trashed_file(file)restore_trashed_file(file,name: nil,parent: nil)
chunked_upload_create_session_new_file(path_to_file,parent,name: nil)chunked_upload_create_session_new_file_from_io(io,parent,name)chunked_upload_create_session_new_version(path_to_file,file,name: nil)chunked_upload_create_session_new_version_from_io(io,file,name)chunked_upload_get_session(session_id)chunked_upload_part(path_to_file,session_id,content_range)chunked_upload_part_from_io(io,session_id,content_range)chunked_upload_list_parts(session_id,limit: nil,offset: nil)chunked_upload_commit(path_to_file,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_commit_from_io(io,session_id,parts,content_created_at: nil,content_modified_at: nil,if_match: nil,if_non_match: nil)chunked_upload_abort_session(session_id)chunked_upload_file(path_to_file,parent,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_file_from_io(io,parent,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file(path_to_file,file,name: nil,n_threads: 1,content_created_at: nil,content_modified_at: nil)chunked_upload_new_version_of_file_from_io(io,file,name,n_threads: 1,content_created_at: nil,content_modified_at: nil)
create_web_link(url,parent,name: nil,description: nil)get_web_link(web_link)update_web_link(web_link,url: nil,parent: nil,name: nil,description: nil)delete_web_link(web_link)trashed_web_link(web_link,fields: [])delete_trashed_web_link(web_link)restore_trashed_web_link(web_link,name: nil,parent: nil)
file_comments(file,fields: [],offset: 0,limit: DEFAULT_LIMIT)add_comment_to_file(file,message: nil,tagged_message: nil)reply_to_comment(comment,message: nil,tagged_message: nil)change_comment(comment,message)comment_from_id(comment_id,fields: [])alias:comment:comment_from_iddelete_comment(comment)
folder_collaborations(folder)add_collaboration(folder,accessible_by,role,fields: [],notify: nil)edit_collaboration(collaboration,role: nil,status: nil)remove_collaboration(collaboration)collaboration_from_id(collaboration_id,fields: [],status: nil)alias:collaboration:collaboration_from_idpending_collaborations()
user_events(stream_position,stream_type: :all,limit: 800)enterprise_events(created_after: nil,created_before: nil,stream_position: 0,event_type: nil,limit: 500)enterprise_events_stream(initial_stream_position,event_type: nil,limit: 500,refresh_period: 300)
shared_item(shared_link,shared_link_password: nil)
search(query=nil,scope: nil,file_extensions: [],created_at_range_from_date: nil,created_at_range_to_date: nil,updated_at_range_from_date: nil,updated_at_range_to_date: nil,size_range_lower_bound_bytes: nil,size_range_upper_bound_bytes: nil,owner_user_ids: [],ancestor_folder_ids: [],content_types: [],trash_content: nil,mdfilters: nil,type: nil,limit: 30,offset: 0)
current_user(fields: [])alias:me:current_useruser_from_id(user_id,fields: [])alias:user:user_from_idall_users(filter_term: nil,fields: [],offset: 0,limit: DEFAULT_LIMIT)create_user(name,login: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,is_external_collab_restricted: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_platform_access_only: nil)update_user(user,notify: nil,enterprise: true,name: nil,role: nil,language: nil,is_sync_enabled: nil,job_title: nil,phone: nil,address: nil,space_amount: nil,tracking_codes: nil,can_see_managed_users: nil,status: nil,timezone: nil,is_exempt_from_device_limits: nil,is_exempt_from_login_verification: nil,is_exempt_from_reset_required: nil,is_external_collab_restricted: nil)email_aliases_for_user(user)add_email_alias_for_user(user,email)remove_email_alias_for_user(user,email_alias)delete_user(user,notify: nil,force: nil)move_users_folder(user,source_folder=0,destination_user)
groups(fields: [],offset: 0,limit: DEFAULT_LIMIT)create_group(name)update_group(group,name)alias:rename_group:update_groupdelete_group(group)group_memberships(group,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_user(user,offset: 0,limit: DEFAULT_LIMIT)group_memberships_for_me(offset: 0,limit: DEFAULT_LIMIT)group_membership_from_id(membership_id)alias:group_membership:group_membership_from_idadd_user_to_group(user,group,role: nil)update_group_membership(membership,role)delete_group_membership(membership)group_collaborations(group,offset: 0,limit: DEFAULT_LIMIT)
file_tasks(file,fields: [])create_task(file,action: :review,message: nil,due_at: nil)task_from_id(task_id)alias:task:task_from_idupdate_task(task,action: :review,message: nil,due_at: nil)delete_task(task)task_assignments(task)create_task_assignment(task,assign_to: nil,assign_to_login: nil)task_assignment(task)delete_task_assignment(task)update_task_assignment(task,message: nil,resolution_state: nil)
create_metadata(file,metadata,scope: :global,template: :properties)create_folder_metadata(folder,metadata,scope,template)metadata(file,scope: :global,template: :properties)folder_metadata(folder,scope,template)all_metadata(file)all_folder_metadata(folder)update_metadata(file,updates,scope: :global,template: :properties)update_folder_metadata(folder,updates,scope,template)delete_metadata(file,scope: :global,template: :properties)delete_folder_metadata(folder,scope,template)get_enterprise_templatesget_metadata_template_by_name(scope,template_key)get_metadata_template_by_id(template_id)create_metadata_template(display_name,template_key: nil,fields: [],hidden: nil)delete_metadata_template(scope,template_key)
get_watermark_on_file(file)apply_watermark_on_file(file)remove_watermark_on_file(file)get_watermark_on_folder(folder)apply_watermark_on_folder(folder)remove_watermark_on_folder(folder)
create_webhook(target_id,target_type,triggers,address)get_webhooks(marker: nil,limit: nil)get_webhook(webhook_id)update_webhook(webhook_id,attributes)delete_webhook(webhook_id)# When receiving a webhook, it is advised to verify that it was sent by BoxBoxr::WebhookValidator.new(headers,payload,primary_signature_key: primary_signature_key,secondary_signature_key: secondary_signature_key).valid_message?
# Requests creation of zip archive# Returns a download_url and a status_url that can be used to download the archive.## Example: create_zip_download([{ id: '1', type: 'file' }, { id: '2', type: 'folder' }])create_zip_download(items,download_file_name: nil)

Contributing

  1. Fork it ( https://github.com/cburnette/boxr/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

About

A Ruby client library for the Box Content API.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages