HOW TO EMBED
YOUR DOCUMENTS WITH BOXVIEW
TO START, YOU NEED
- Paperclip and AWS S3 installed and configured
- And, of course, figaro implemented
- A Document model with a name
- A Document controller with an Index, New, Create and Show method
- A resources :documents in your routes
MODIFY YOUR PAPERCLIP
You need to authorize certain types of document.
So add some MIME Types in your model.
class Document < ActiveRecord::Base
validates :name, presence: true
has_attached_file :doc
validates_attachment_content_type :doc, content_type: [
"application/pdf",
"application/msword",
"application/vnd.oasis.opendocument.text",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-powerpoint",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"text/css",
"application/javascript",
]
end
GET AN API KEY
First, you need to create an account : https://app.box.com/developers/services
Create a Box Application
Select Box View
Copy the Key
Paste it in your application.yml
LET'S BOX NOW !
BOX STEPS
- Get a document_id from Box
- Open a session in Box
- When ready, it will return an url that you'll insert into an iframe
BUT WHERE ARE WE GOING TO STORE THAT URL ?
IN THE MODEL !
UPGRADE THE MODEL
We need to add a string for :box_view_url
rails generate migration AddBoxViewUrlToDocuments box_view_url:string
and let's place the iframe in our show.html.slim
.embed-responsive.embed-responsive-4by3
iframe src=@document.box_view_url class="embed-responsive-item" frameborder="0" allowfullscreen="allowfullscreen"
I. DOCUMENT_ID
CHAT WITH BOX
We're going to use HTTParty to discuss with BoxView
In your gemfile, add :
gem 'httparty'
And of course, run
bundle install
WHAT BOX NEEDS
curl https://view-api.box.com/1/documents \
-H "Authorization: Token YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "http://www.example.com/MyFile.pdf"}' \
-X POST
def generate_box_document
HTTParty.post('https://view-api.box.com/1/documents',
headers: {
'Authorization' => "Token #{ENV['BOX_VIEW_API_KEY']}",
'Content-Type' => 'application/json',
},
body:
{
url: doc.url,
name: doc.name
}.to_json
)
end
SO, LET'S CREATE A METHOD
Why do we need the .to_json ?
Let's see Box's answer !
def create
@document = Document.new(document_params)
if @document.save
@document.generate_box_document
redirect_to document_path(@document)
else
render :new
end
end
AND CALL IT...
in the Documents Controller (for now)
II. CREATE A SESSION
WHAT BOX NEEDS
curl https://view-api.box.com/1/sessions \
-H "Authorization: Token YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"document_id": "ABC123"}' \
-X POST
def generate_box_session(document_id)
session = HTTParty.post('https://view-api.box.com/1/sessions',
headers: {
'Authorization' => "Token #{ENV['BOX_VIEW_API_KEY']}",
'Content-Type' => 'application/json',
},
body: {
document_id: document_id,
expires_at: 90.days.from_now,
is_downloadable: true,
}.to_json
)
end
THE METHOD WILL BE
Let's see Box's answer !
CODE 202 !
201
The session was successfully created.
202
The document is not ready for viewing. A Retry-After header will be included
in the response indicating the time to wait before trying again.
400
An error occurred while converting the document, or the document does not exist.
if 201
Easy, let's update our model with the url that Box gave us:
if 202
Let's run again the method:
if session.response.code == '201'
self.update_column(:box_view_url, session['urls']['view'])
if session.response.code == '202'
generate_box_session(document_id)
AND IT DOESN'T WORK
[3] pry(main)> Document.last.box_view_url
Document Load (0.4ms) SELECT "documents".* FROM "documents" ORDER BY "documents"."id" DESC LIMIT 1
=> nil
LET'S THINK DIFFERENTLY
For now, when the doc is saved in our base, we call:
@document.generate_box_document
And with the document_id generated,
we're looking to retrieve an url for our iframe.
And if we don't get that url, what happens? Nothing.
WHY DON'T WE CREATE A BOX_VIEWER METHOD THAT WILL BE CALLED IF NOTHING HAPPENED?
View
Model
- if @document.box_view_url.present?
.embed-responsive.embed-responsive-4by3
iframe src=@document.box_view_url class="embed-responsive-item" frameborder="0" allowfullscreen="allowfullscreen"
- else
- @document.box_viewer
p Your document is loading...
def box_viewer
box_document = generate_box_document
generate_box_session(box_document['id'])
end
And get rid of @document.generate_box_document
in the controller
Let's add a little twist...
III. ADD A LITTLE JAVASCRIPT
LET'S AUTOREFRESH !
Put a loader in your assets, add a class in the view and define it in your stylesheets
.box_loader {
background-image: image-url('loader.gif');
width: 64px;
height: 64px;
margin-top: 100px;
margin-left: 33.5em;
}
AND FOR THE JS...
Add a boxloader.js file and in it:
$(window).load(function(){
if($('.box_loader').length > 0){
setTimeout(function() {
location.reload();
}, 4000)
}
})
TADAAAA !
Thanks you !
And if you want to practise, here is the repo where you can start from this demo:
https://github.com/soniaprevost/lbyt-embedwithbox
Fork it !
Special thanks to
- Julien, Lead Developer @agorize
- Adrien, FrontEnd Developer @agorize
- The Wagon Team (Cécile, Sébastien, Miruna,...)
Box View Rails
By Sonia Prévost
Box View Rails
- 1,186