ShopCircle Orbit Ruby SDK

Server-side Ruby SDK for ShopCircle Orbit analytics. Track events, identify users, and measure engagement from any Ruby backend.

  • Thread-safe background batching with automatic retry
  • Zero runtime dependencies (Ruby stdlib only)
  • Optional Rails integration with auto page view tracking

Installation

# Gemfile
gem "shopcircle-orbit"
bundle install

Quick Start

Plain Ruby

require "shopcircle_orbit"

orbit = ShopCircle::Orbit::Client.new(
  client_id: "your-client-id",
  api_url: "https://orbit.shopcircle.co"
)

orbit.identify("user_123", first_name: "John", email: "john@example.com")
orbit.track("purchase", amount: 99.99, currency: "USD")
orbit.shutdown!

Rails

Generate the initializer:

rails generate shopcircle_orbit:install

This creates config/initializers/shopcircle_orbit.rb. Then use anywhere:

ShopCircle::Orbit.identify(current_user.id, first_name: current_user.first_name, email: current_user.email)
ShopCircle::Orbit.track("order_created", order_id: order.id, amount: order.total)

Configuration

ShopCircle::Orbit.configure do |config|
  config.client_id       = ENV.fetch("SHOPCIRCLE_CLIENT_ID")
  config.client_secret   = ENV["SHOPCIRCLE_CLIENT_SECRET"]   # optional
  config.api_url         = "https://orbit.shopcircle.co"
  config.device_id       = nil                                # optional device identifier
  config.flush_interval  = 2                                  # seconds between flushes
  config.max_batch_size  = 10                                 # events per HTTP request
  config.max_queue_size  = 1_000                              # max queued events
  config.max_retries     = 3                                  # retry attempts for failures
  config.request_timeout = 10                                 # HTTP timeout in seconds
  config.stub            = Rails.env.test?                    # test mode (no HTTP)
  config.on_error        = ->(msg, detail) { Rails.logger.error("[Orbit] #{msg}") }
end

API

track(name, properties = {})

Track a custom event:

ShopCircle::Orbit.track("button_click", label: "Sign Up", page: "/pricing")
ShopCircle::Orbit.track("purchase", amount: 49.99, currency: "USD", product_id: "prod_abc")

identify(profile_id, traits = {})

Identify a user with profile attributes:

ShopCircle::Orbit.identify("user_123",
  first_name: "John",
  last_name: "Doe",
  email: "john@example.com",
  plan: "premium"
)

reset!

Clear the current user identity (e.g. on logout):

ShopCircle::Orbit.reset!

set_device_id(device_id)

Set a device identifier for cross-session linking:

ShopCircle::Orbit.set_device_id("device-fingerprint-from-frontend")

flush

Force an immediate flush of queued events:

ShopCircle::Orbit.flush

shutdown!

Flush remaining events and stop the background worker:

ShopCircle::Orbit.shutdown!

Multiple Clients

For multi-tenant or multi-project use cases, create separate client instances:

project_a = ShopCircle::Orbit::Client.new(client_id: "id-a", api_url: "https://orbit.shopcircle.co")
project_b = ShopCircle::Orbit::Client.new(client_id: "id-b", api_url: "https://orbit.shopcircle.co")

project_a.track("event_a")
project_b.track("event_b")

Testing

Enable stub mode to record events without making HTTP calls:

# test/test_helper.rb
ShopCircle::Orbit.configure do |config|
  config.stub = true
end

# In your test
class OrderTest < ActiveSupport::TestCase
  setup do
    ShopCircle::Orbit.shutdown!  # reset between tests
  end

  test "tracks purchase event" do
    OrderService.create!(user: users(:alice), amount: 99.99)

    events = ShopCircle::Orbit.client.events
    purchase = events.find { |e| e[:payload][:name] == "purchase" }
    assert purchase
    assert_equal 99.99, purchase[:payload][:properties]["amount"]
  end
end

Rails Middleware

The SDK automatically inserts Rack middleware that tracks page_view events for HTML GET requests. Asset paths, XHR, and JSON requests are excluded.

To disable:

# config/application.rb
config.middleware.delete ShopCircle::Orbit::Rails::Middleware

License

MIT