Hey there, fellow Ruby enthusiast! Ready to dive into the world of Teachable API integration? Let's roll up our sleeves and get coding!
Teachable's API is a powerful tool that lets you tap into their platform's functionality. Whether you're looking to automate course management, sync user data, or pull sales reports, this guide will have you up and running in no time.
Before we jump in, make sure you've got:
httparty
and dotenv
gemsFirst things first, let's get our project structure set up:
mkdir teachable_api_integration cd teachable_api_integration bundle init
Now, add these gems to your Gemfile:
gem 'httparty' gem 'dotenv'
Run bundle install
, and we're off to the races!
Teachable uses API key authentication. Create a .env
file in your project root:
TEACHABLE_API_KEY=your_api_key_here
Now, let's create a base class for our API calls:
require 'httparty' require 'dotenv/load' class TeachableAPI include HTTParty base_uri 'https://api.teachable.com/v1' headers 'Accept' => 'application/json' headers 'Content-Type' => 'application/json' def initialize @options = { headers: { 'Authorization' => "Bearer #{ENV['TEACHABLE_API_KEY']}" } } end end
With our base class set up, making requests is a breeze:
class TeachableAPI # ... previous code ... def get_courses self.class.get('/courses', @options) end def create_user(user_data) self.class.post('/users', @options.merge(body: user_data.to_json)) end end
Let's implement methods for the main endpoints:
class TeachableAPI # ... previous code ... def get_course(id) self.class.get("/courses/#{id}", @options) end def get_users self.class.get('/users', @options) end def get_enrollments self.class.get('/enrollments', @options) end def get_sales self.class.get('/sales', @options) end end
Robust error handling is crucial. Let's add some magic:
class TeachableAPI # ... previous code ... private def handle_response(response) case response.code when 200..299 response when 401 raise "Unauthorized: Check your API key" when 404 raise "Not Found: The requested resource doesn't exist" else raise "API Error: #{response.code} - #{response.message}" end end end
Now, wrap your API calls with this method:
def get_courses handle_response(self.class.get('/courses', @options)) end
Teachable has rate limits, so let's be good citizens:
class TeachableAPI # ... previous code ... def initialize @options = { headers: { 'Authorization' => "Bearer #{ENV['TEACHABLE_API_KEY']}" } } @last_request_time = Time.now - 1 # Initialize to 1 second ago end private def respect_rate_limit elapsed = Time.now - @last_request_time sleep(1 - elapsed) if elapsed < 1 @last_request_time = Time.now end end
Call respect_rate_limit
before each API request to ensure you're not hammering the API.
Teachable uses cursor-based pagination. Here's how to handle it:
def get_all_courses courses = [] next_cursor = nil loop do response = get_courses(next_cursor) courses += response['courses'] next_cursor = response['meta']['next_cursor'] break if next_cursor.nil? end courses end def get_courses(cursor = nil) params = cursor ? { cursor: cursor } : {} handle_response(self.class.get('/courses', @options.merge(query: params))) end
Don't forget to test! Here's a quick example using RSpec:
RSpec.describe TeachableAPI do let(:api) { TeachableAPI.new } describe '#get_courses' do it 'returns a list of courses' do VCR.use_cassette('get_courses') do response = api.get_courses expect(response).to be_success expect(response['courses']).to be_an(Array) end end end end
And there you have it! You're now equipped to build a robust Teachable API integration in Ruby. Remember, the key to a great integration is not just making it work, but making it reliable and maintainable.
Happy coding, and may your courses always be full and your students always engaged!