January 16, 2016
Getting the path from the Dropbox API
Suppose you’re using the Dropbox API to let a user choose a file from her Dropbox folder and open it in your application. Dropbox provides a convenient widget — the Chooser — you can more or less just drop into your Web page. But…suppose you want to find out the path of an item that a user opens. For example, you want to know not only that the user has opened “testfile.txt” but that it’s “Dropbox/testfolder/TestA/testfile.txt”. The chooser only tells you the link is something like:
https://www.dropbox.com/s/lry43krhdskl0bxeiv/testfile.txt?dl=1
Figuring out how to get that path information took me /for/ev/er. I know it shouldn’t have, but it did. So, here’s how I’m doing it. (As always, please try not to laugh at my efforts at coding. I am an amateur. I suck. Ok?) (I owe thanks to Andrew Twyman at Dropbox who went out of his way to help me. Thanks, Andrew! And none of this is his fault.)
The way to get the path is explained in Dropbox’s API documentation, but that documentation assumes I know more than I do. Dropbox also provides an API Explorer that lets you try out queries and shows you the code behind them. Very helpful, but not quite helpful enough for the likes of me, because I need to know what the actual PHP or JavaScript code is. (It’d be easier if I knew Python. Someday.)
So, here’s roughly how I got it working. I’m going to skip some of the preliminaries because I went through them in a prior post: how to register an app with Dropbox so you can embed the Dropbox Chooser that lets users browse their Dropbox folders and download a file.
That prior post included code that initializes the Chooser. I want to add a single line to it so we can get the pathname of the downloaded document:
1 |
var opts= { |
2 |
success: function(files) { |
|
|
3 |
var filename = files[0].link; |
4 |
filename = filename.replace(“dl=0″,”dl=1”); |
5 |
$(“#filenamediv”).text(files[0].name); |
6 |
alert(filename); |
7 |
$.ajax({ |
8 |
url: “./php/downloadDropboxContents2.php”, |
9 |
data: {src : filename}, |
10 |
success: function(cont){ |
11 |
$(“#busy”).show(); |
12 |
openOpmlFile_File(filename); |
13 |
$(“#busy”).hide(); |
14 |
setCookie(“lastfile”,”/php/currentFile/” + filename); |
15 |
getDropboxPath(filename); |
|
|
16 |
}, |
17 |
error: function(e){ |
18 |
alert(e.responseText); |
19 |
} |
20 |
}); |
|
|
21 |
}, |
22 |
multiselect: false, |
23 |
extensions: [‘.opml’], |
24 |
linkType: “download” |
25 |
}; |
26 |
var button = Dropbox.createChooseButton(opts); |
27 |
document.getElementById(“uploadDB”).appendChild(button); |
When a user chooses a file from Chooser, the “success” function that starts on line 10 is invoked. That function is passed information about the files that have been opened by the user in an array, but since I’m only allowing users to open one file at a time, the information is always going to be in the first and only element of that array. That information includes something called “link,” which is a link to the file that does not include the path information. So, in line 15 — the only new line — we’re going to pass that link to a function that will get that elusive path.
1 |
function getDropboxPath(link){ |
2 |
$.ajax({ |
3 |
type: “POST”, |
4 |
beforeSend: function (request) |
5 |
{ |
6 |
request.setRequestHeader(“Content-Type”, “application/json”); |
7 |
}, |
8 |
url: “https://api.dropboxapi.com/2/sharing/get_shared_link_metadata?authorization=Bearer [INSERT YOUR AUTHORIZATION CODE]”, |
9 |
data: JSON.stringify({url : link}), |
10 |
success: function(cont){ |
11 |
alert(cont.path_lower); |
12 |
}, |
13 |
error: function(e){ |
14 |
alert(e.responseText); |
15 |
} |
16 |
}); |
17 |
} |
This is another AJAX call; it too assumes that you’ve included jQuery. (See the prior post.)
Now, how does this work. Well, I’m not entirely sure. But it’s sending a request to the Dropbox API. It’s doing this as a standard http web call, which means (I think) that you have to include metadata that web servers expect when you’re using http. (I could be wrong about this.) So, in line 6 you tell it that you are expecting to get JSON back, not a standard Web page. (JSON is a standard way of encoding human-readable, multipart information.)
In line 8 you’re constructing the URL you’re going to send your request to. Everything up to the question mark is simply the URL of the Dropbox API for getting metadata about a link. After the question mark you’re telling it that you’re authorized to make this request, which requites getting an authorization code from Dropbox. I’m probably cheating by using the one that the API Explorer gives you, but it works for now so I’ll worry about that when it breaks, which will probably be the next time I use it. Anyway, you need to insert your authorization code where it says “insert your authorization code” in all caps.
Line 9: The data is the internal link that the Chooser gave you as the URL of the file the user downloaded. I use JSON.stringify because it didn’t work until I did.
Line 10 is what happens when your query works. You’ll get an object from Dropbox that contains several different pieces of info. You want the one called “path_lower,” presumably because it gives you the path that is lower on the great Tree of Files that is a Dropbox folder. [LATER THAT DAY: Andrew tells me it’s actually called path_lower because it’s the path in all lower case, which is useful because the Dropbox file system is case insensitive. Frankly, I prefer my explanation on poetic grounds, so we’ll have to agree to disagree :)] Line 11 gets that path (cont.path_lower) and pops it into an alert box, which is almost certainly not what you actually want to do with it. But this is a demo.
That’s it. If you have questions, try to find someone who understands this stuff because I got here through many trials and even more errors.
Good luck.