Back

Step by Step Guide to Building a Simpro API Integration in Ruby

Aug 18, 20246 minute read

Introduction

Hey there, fellow developer! Ready to dive into the world of Simpro API integration? You're in for a treat. We'll be building a robust integration that'll have you pulling data from Simpro like a pro in no time. Let's get cracking!

Prerequisites

Before we jump in, make sure you've got:

  • Ruby 2.7+ (because who doesn't love the latest and greatest?)
  • The httparty and dotenv gems (your new best friends)
  • Simpro API credentials (if you don't have these, go bug your Simpro admin!)

Setting up the project

First things first, let's get our project set up:

mkdir simpro_integration cd simpro_integration bundle init

Now, add these gems to your Gemfile:

gem 'httparty' gem 'dotenv'

Run bundle install, and you're good to go!

Authentication

Alright, time to get that sweet, sweet access token. Create a .env file in your project root:

SIMPRO_CLIENT_ID=your_client_id
SIMPRO_CLIENT_SECRET=your_client_secret
SIMPRO_COMPANY_ID=your_company_id

Now, let's write a method to grab that token:

require 'httparty' require 'dotenv/load' def get_access_token response = HTTParty.post('https://auth.simpro.co/oauth/token', { body: { grant_type: 'client_credentials', client_id: ENV['SIMPRO_CLIENT_ID'], client_secret: ENV['SIMPRO_CLIENT_SECRET'], company_id: ENV['SIMPRO_COMPANY_ID'] } }) response.parsed_response['access_token'] end

Making API requests

Now that we've got our token, let's make some requests! Here's a basic GET example:

def get_customers access_token = get_access_token response = HTTParty.get('https://api.simpro.co/v2/customers', { headers: { 'Authorization' => "Bearer #{access_token}" } }) response.parsed_response end

Working with Simpro resources

Let's create a simple class to handle our Simpro operations:

class SimproClient include HTTParty base_uri 'https://api.simpro.co/v2' def initialize @options = { headers: { 'Authorization' => "Bearer #{get_access_token}" } } end def customers self.class.get('/customers', @options) end def jobs self.class.get('/jobs', @options) end # Add more methods for other resources end

Error handling and logging

Always expect the unexpected! Let's add some error handling:

def make_request(endpoint) response = self.class.get(endpoint, @options) if response.success? response.parsed_response else puts "Error: #{response.code} - #{response.message}" nil end rescue StandardError => e puts "An error occurred: #{e.message}" nil end

Pagination and rate limiting

Simpro uses cursor-based pagination. Here's how to handle it:

def get_all_customers customers = [] cursor = nil loop do response = self.class.get('/customers', @options.merge(query: { cursor: cursor })) break unless response.success? customers += response.parsed_response['data'] cursor = response.parsed_response['meta']['cursor'] break if cursor.nil? sleep(1) # Be nice to the API! end customers end

Testing the integration

Don't forget to test! Here's a simple RSpec example:

RSpec.describe SimproClient do let(:client) { SimproClient.new } describe '#customers' do it 'returns a list of customers' do VCR.use_cassette('customers') do customers = client.customers expect(customers).to be_an(Array) expect(customers.first).to have_key('name') end end end end

Best practices and optimization

Remember to cache your access token and reuse it until it expires. Also, consider implementing a retry mechanism for failed requests.

Conclusion

And there you have it! You've just built a solid foundation for your Simpro API integration. From here, you can expand on this base, add more resources, and tailor it to your specific needs. Happy coding!

Additional resources

Now go forth and integrate with confidence!