Jump to content
Server Maintenance This Week. ×

Freshbooks API integration


This topic is 3046 days old. Please don't post here. Open a new topic instead.

Recommended Posts

Been doing a bit of work so one of my staff can work from home and log time onto Freshbooks using iPhone app (MiniBooks Lite) but then I can query the account and pull down the data as XML and get it into FM

Have a couple of functions that will generate the necessary XML to POST to Freshbooks and then one to actually do that

All works but you will need the API docs to hand while you are building queries

Create, Get, Update, Delete


// FreshUpdate_SMB ( fb_type ; fb_request ; fb_id ; fields ; values )

// 2011/01/20 JR

// v1

// returns XML to feed to FreshList_XML

// fb_type is delete, get, create, update

// fb_id is item ID

// fields is list of fields to add/ update

// values is matching list of values to put into fields

// time_entry, task, project, item, client, category



import groovy.xml.StreamingMarkupBuilder



fb_update = fb_request

list = fields.tokenize("\n")

vlist = values.tokenize("\n")

int i = 0

fb_idType = fb_request + '_id'

fb_request = fb_request + '.' + fb_type

smb = new StreamingMarkupBuilder()

smb.encoding = "UTF-8"

def req = {

mkp.xmlDeclaration()

request(method:fb_request){ 

if (fb_type == 'get' || fb_type == 'delete' ){

	"$fb_idType"(fb_id)

} else

	"$fb_update"{

	if (fb_type == 'update'){

	"$fb_idType"(fb_id)

	list.each{ "$it"(vlist[i])

		i++

		}

	} else {

	list.each{ "$it"(vlist[i])

		i++

		}

	} //end if

}

}

}

return smb.bind(req)







List



// FreshList_SMB ( fb_request ; fb_paged ; fb_num )

// 2011/01/20 JR

// v1

// returns XML to feed to FreshList_XML

// fb_request is API section (e.g. expense, time_record)

// fb_paged is flag to add paged values if more than 100 entries (output is paginated)

// fb_num is page number to insert, call multiple times if reqd

 

import groovy.xml.StreamingMarkupBuilder



fb_request = fb_request + '.list'

smb = new StreamingMarkupBuilder()

smb.encoding = "UTF-8"

def req = {

mkp.xmlDeclaration()

if (fb_paged =='1'){

	request(method:fb_request){

	page(fb_num)

	per_page(100)

}

} else{

	request(method:fb_request)

}

}

return smb.bind(req)







Return XML



// FreshList_XML ( fb_query ; fbq_type ; fm_query ; list )

// 2011/01/20 JR

// v1

// returns XML response from FreshBooks

// fb_query is XMl query generated from FreshXX_SMB function

// fbq_type is what type of values are returned plural (e.g. time_entries)

// and will otuput pages and per_page variables if it is what is being returned

// fm_query is all for all values, or (e.g. time_record_id)

// suggest running once for each page of results with ID selected

// then once with all selected and use XPath functions to parse returned XML

// saves on API calls which are limied to 5000 per day

// list is flag for returning pages and per_page output variables when fm_query is NOT 'all'

// requires commons.httpclient.3.0.1.jar



import org.apache.commons.httpclient.HttpClient

import org.apache.commons.httpclient.UsernamePasswordCredentials

import org.apache.commons.httpclient.methods.PostMethod

import org.apache.commons.httpclient.auth.AuthScope

import javax.xml.xpath.*

//import javax.xml.parsers.*

import javax.xml.parsers.DocumentBuilderFactory

import org.w3c.dom.*



client = new HttpClient()

client.getState().setCredentials(new AuthScope(null, 443, null), new UsernamePasswordCredentials("YOUR_API_KEY_HERE", null) )

get = new PostMethod("https://YOUR_ACCOUNT.freshbooks.com/api/2.1/xml-in")

get.setDoAuthentication( true )

get.setRequestBody(fb_query)

int status = client.executeMethod( get )

String xmlString = get.getResponseBodyAsString()

get.releaseConnection()



values= new XmlSlurper().parseText(xmlString)

pages = "${values."${fbq_type}".@pages}"

per_page = "${values."${fbq_type}".@per_page}"

if(fm_query == 'all' || fm_query == null) {

	return xmlString

} else if (list != '1') {

	pages = '0'

	per_page= '0'

} // end if



builder = DocumentBuilderFactory.newInstance().newDocumentBuilder()

inputStream = new ByteArrayInputStream( xmlString.getBytes() )

records = builder.parse(inputStream).getDocumentElement()

xpath = XPathFactory.newInstance().newXPath()

nodes = (NodeList)xpath.evaluate( '//' + fm_query, records, XPathConstants.NODESET )

return nodes.collect { node -> node.getTextContent() }

If anyone know how to get this to work with httpclient-4.1 that would be cool, some of the calls have changed a lot and can't get the authentication or set request body to work

Link to comment
Share on other sites

  • 4 years later...
  • Newbies

Hello John,

I have a little time this holiday weekend to piddle around with Freshbooks/Filemaker integration and I was wondering if you have done any more along these lines? There is some skills/knowledge that I am lacking to do what I want. Presently I can 'cURL' Freshbooks and get my client list, etc., and I have re-familiarized myself with XSLT transforms and such. This allows me to import, but I don't know how I could make a transition from this cURL method to building the import more directly into my solution.

Do you continue to integrate Filemaker and Freshbooks?

 

-James

Link to comment
Share on other sites

This topic is 3046 days old. Please don't post here. Open a new topic instead.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.