Ruby SDK

Integrate Perly churn prevention into your Ruby on Rails application with Rack middleware, an initializer, and a user resolver.

perly-rubyv1.0.05 minutes

Installation

Add the gem to your Gemfile:

gem 'perly-ruby'

Then install:

bundle install

Usage

Register the Perly middleware in your Rails application and configure it with an initializer.

# config/application.rb
module MyApp
  class Application < Rails::Application
    config.middleware.use Perly::Middleware, api_key: ENV['PERLY_API_KEY']
  end
end
# config/initializers/perly.rb
Perly.configure do |config|
  config.api_key = ENV['PERLY_API_KEY']
  config.resolver = AppPerlyResolver.new
end

User Resolver

Create a resolver class that inherits from Perly::UserResolver. The resolve method receives the Rack request and returns a Perly user built with the builder pattern.

# app/resolvers/app_perly_resolver.rb
class AppPerlyResolver < Perly::UserResolver
  def resolve(request)
    user = request.env['warden'].user
    return nil unless user

    Perly::Builder.new
      .set_id(user.id.to_s)
      .set_metadata({
        plan: user.plan,
        region: user.region,
        company_id: user.company_id
      })
      .link_stripe_by_id(user.stripe_customer_id)
      .link_hubspot_by_id(user.hubspot_contact_id)
      .build
  end
end

If you use Devise, the user is available through request.env['warden'].user. For other auth libraries, pull the user from the appropriate source.

Tracking Events

Use Perly.client anywhere in your application to track customer engagement events.

# app/controllers/onboarding_controller.rb
class OnboardingController < ApplicationController
  def complete
    Perly.client.track(current_user.id, 'onboarding_completed')
    render json: { success: true }
  end
end

# app/controllers/reports_controller.rb
class ReportsController < ApplicationController
  def export
    Perly.client.track(current_user.id, 'report_exported', {
      format: params[:format]
    })
    send_data report_data, filename: "report.#{params[:format]}"
  end
end

# app/controllers/teams_controller.rb
class TeamsController < ApplicationController
  def invite
    Perly.client.track(current_user.id, 'team_member_invited', {
      email: params[:email]
    })
    render json: { invited: true }
  end
end

Expansion Signals

Send signals when customers approach their plan limits to trigger expansion workflows.

# app/services/usage_check_service.rb
class UsageCheckService
  def check_seat_limit(user)
    seats = user.company.seat_count
    limit = user.company.seat_limit

    if seats > limit * 0.9
      Perly.client.signal(user.id, 'seat_limit_near', {
        current: seats,
        limit: limit
      })
    end
  end
end

# Other signal types
Perly.client.signal(user_id, 'api_usage_high', { current: 9500, limit: 10000 })
Perly.client.signal(user_id, 'rate_limit_hit', { endpoint: '/api/search' })
Perly.client.signal(user_id, 'storage_limit_near', { used_gb: 9.2, limit_gb: 10 })
Perly.client.signal(user_id, 'billing_retry_failed', { attempt: 3 })