Back

Step by Step Guide to Building a Planning Center API Integration in Ruby

Aug 16, 20246 minute read

Introduction

Hey there, fellow developer! Ready to dive into the world of Planning Center API integration? You're in for a treat. This guide will walk you through building a robust integration using Ruby, and I promise it'll be smoother than your morning coffee.

Planning Center's API is a powerhouse for church management software, and we're about to harness that power. Let's get cracking!

Prerequisites

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

  • Ruby 2.7+ (because we're not savages)
  • Your favorite HTTP client gem (I'm partial to httparty, but you do you)
  • Planning Center API credentials (if you don't have these, time to sweet-talk your admin)

Setting up the project

First things first, let's get our project off the ground:

mkdir planning_center_integration cd planning_center_integration bundle init

Now, crack open that Gemfile and add:

gem 'httparty' gem 'dotenv'

Run bundle install, and we're cooking with gas!

Authentication

Planning Center uses OAuth 2.0, because they're fancy like that. Here's how we'll tackle it:

require 'httparty' require 'dotenv/load' class PlanningCenterAPI include HTTParty base_uri 'https://api.planningcenteronline.com' def initialize @options = { headers: { 'Authorization' => "Bearer #{ENV['PLANNING_CENTER_ACCESS_TOKEN']}", 'Content-Type' => 'application/json' } } end # We'll add more methods here soon! end

Pro tip: Use a .env file to store your access token. Your future self will thank you.

Making API requests

Now for the fun part - let's start making some requests:

def get_people self.class.get('/people/v2/people', @options) end def create_person(data) self.class.post('/people/v2/people', @options.merge(body: data.to_json)) end

Boom! You're now GET-ting and POST-ing like a champ.

Working with specific endpoints

Planning Center has a bunch of APIs. Let's focus on the People API for now:

def get_person(id) self.class.get("/people/v2/people/#{id}", @options) end def update_person(id, data) self.class.patch("/people/v2/people/#{id}", @options.merge(body: data.to_json)) end

Error handling and rate limiting

Let's not be that person who crashes the app. Add some error handling:

def handle_response(response) case response.code when 200...300 response when 429 raise "Rate limit exceeded. Try again in #{response.headers['Retry-After']} seconds." else raise "API request failed: #{response.code} - #{response.message}" end end

Wrap your API calls with this method, and you'll be catching errors like a pro.

Data processing and storage

Now that we're getting data, let's do something with it:

def process_people response = handle_response(get_people) people = JSON.parse(response.body)['data'] people.each do |person| # Do something cool with each person puts "Processing #{person['attributes']['name']}" end end

Building a simple CLI tool

Let's wrap this all up in a neat little CLI package:

#!/usr/bin/env ruby require_relative 'planning_center_api' api = PlanningCenterAPI.new case ARGV[0] when 'list_people' api.process_people when 'get_person' puts api.get_person(ARGV[1]).body else puts "Unknown command. Try 'list_people' or 'get_person <id>'." end

Testing the integration

Don't forget to test! Here's a quick RSpec example to get you started:

RSpec.describe PlanningCenterAPI do let(:api) { PlanningCenterAPI.new } it "fetches people successfully" do response = api.get_people expect(response.code).to eq(200) end end

Best practices and optimization

Remember, with great power comes great responsibility. Be kind to the API:

  • Cache responses when you can
  • Use pagination for large datasets
  • Don't hammer the API with requests - space them out

Conclusion

And there you have it! You've just built a Planning Center API integration that would make any developer proud. Remember, this is just the tip of the iceberg. There's a whole world of Planning Center APIs out there waiting for you to explore.

Keep coding, keep learning, and most importantly, keep being awesome. You've got this!