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!
Before we jump in, make sure you've got:
httparty
and dotenv
gems (your new best friends)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!
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
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
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
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
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
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
Remember to cache your access token and reuse it until it expires. Also, consider implementing a retry mechanism for failed requests.
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!
Now go forth and integrate with confidence!