So, I came across a project for work where I had to work with the Freshbooks API. Instead of having users put in their “API URL” and “Authentication Token” everytime (by going to their Freshbooks > My Account > Freshbooks API), which was just inconvenient. I registered my app for Freshbooks OAuth use. Problem was, there wasn’t an great documentation on how to implement Freshbooks and OAuth calls. I tried authenticating with OAuth classes that were already built, but the problem was that Freshbooks expects an Authorization header and not Authorization posted to the body, as far as I could see. So, I read a blog entry on Formstack’s blog and started writing a Freshbooks API with OAuth class. I was able to get Authentication working and grab an access token, etc. but a problem lied where I couldn’t figure out how to send requests to Freshbooks API with an OAuth header. I contacted Michael Mattax ( @mmattax ) via email and he helped me out a little with a cURL function to send requests to Freshbooks API.
So, first off, after expanding the file available for download you’ll see and “index.php” and a folder “src” which contains: “freshbooks.php” and “config.php”.
** Updated October 1st, 2010
Demo — I’m not going to put a demo up, just incase Freshbooks decides to turn on API Rate Limits; Although an example is provided in the source code.
Config.php simply defines your Consumer Key, Consumer Secret, and Callback for after they have authorized their account.
After defining everything in the “config.php” file, you can move on to the “index.php”
I start by starting a session and including the “config.php” and “freshbooks.php” from the “src” folder.
Then I do a series of if statements.
The first is to check if a $_SESSION[‘oauth_token’] and $_SESSION[‘oauth_token_secret’] exist. (If they do then we can create a connection to the Freshbooks class like so:)
$c = new Freshbooks(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET, NULL, $_SESSION[‘subdomain’], $_SESSION[‘oauth_token’], $_SESSION[‘oauth_token_secret’]);
If there isn’t a $_SESSION[‘oauth_token’] and $_SESSION[‘oauth_token_secret’] then we can check to see if there is a $_GET[‘oauth_token’] and $_GET[‘oauth_verifier’] in the url (this meaning it’s the callback):
$c = new Freshbooks(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET, NULL, $_SESSION[‘subdomain’]);
$_SESSION[‘oauth_token’] = $access_token[‘oauth_token’];
$_SESSION[‘oauth_token_secret’] = $access_token[‘oauth_token_secret’];
We set the $_SESSION[‘oauth_token’] and $_SESSION[‘oauth_token_secret’] then redirect to the “index.php” so that now there are session vars we were talking about in the previous block of code, thus creating a connection to the Freshbooks class and then we’d be able to make calls to the API.
If there is no $_SESSION[‘oauth_token’] or $_SESSION[‘oauth_token_secret’] or $_GET’s as stated above, then no we’re going to need to check if they provided us their subdomain (i.e. http://example.freshbooks.com; “example” would be their subdomain.) if they did, we’ll move on to this chunk code that simply displays a “Login to Freshbooks” link which a user clicks, they put in their username and password then they’ll be redirected to your OAuth Callback URL set in your config (which in this case is handled on the index.php) They send you back 2 parameters in the URL “oauth_token” and “oauth_verifier”; so… the previous block of code will be triggered!
$c = new Freshbooks(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET, OAUTH_CALLBACK, $_SESSION[‘subdomain’]);
If there is no $_SESSION[‘oauth_token’] or $_SESSION[‘oauth_token_secret’] or $_GET’s or subdomain posted, we’ll give them a form where they put in their subdomain:
When all is said and done and the user has authenticated with Freshbooks and you get $_SESSION vars and you make a connection with the Freshbooks class that I wrote, you’ll be able to make calls to the API.
$request = ‘<?xml version=”1.0″ encoding=”utf-8″?><request method=”client.list”><page>1</page><per_page>15</per_page></request>’;
$clients = $c->post($request);
You can do a print_r() on $clients and you’ll see the Simple XML object that is returned. If something goes wrong, I have a check in my class for an error or a “status” => fail which will be caught in an Exception and return an error message from Freshbooks.
** Updated October 1st, 2010
NOTE: The update as of October 1st, 2010 changed this Freshbooks OAuth class to Version 2.0. Version 1.0 does not support multiuser usage.
Some links to check out:
http://developers.freshbooks.com/ — Freshbooks API Reference
* Any questions, please drop a comment or email firstname.lastname@example.org