Tarpon
A Ruby interface to RevenueCat's REST API.
Installation | Usage | API Reference
Installation
Add this line to your application's Gemfile:
gem 'tarpon'And then execute:
$ bundle
Or install it yourself as:
$ gem install tarpon
Usage
Configuration
Tarpon::Client.configure do |c|
c.public_api_key = 'your-public-key'
c.secret_api_key = 'your-secret-key'
c.timeout = 5 # a global timeout in seconds for http requests to RevenueCat server, default is 5 seconds
endGet your credentials from the RevenueCat dashboard. Read more about authentication on the RevenueCat docs.
Configuring multiple clients
If you need to support different configurations (e.g. to target different RevenueCat projects), you can instantiate different Tarpon clients. For example:
PROJECT_1_RC_CLIENT = Tarpon::Client.new do |c|
c.public_api_key = 'project-1-public-key'
c.secret_api_key = 'project-1-secret-key'
end
PROJECT_2_RC_CLIENT = Tarpon::Client.new do |c|
c.public_api_key = 'project-2-public-key'
c.secret_api_key = 'project-2-secret-key'
endAnd then you can use them instead of calling methods on Tarpon::Client. For example:
PROEJCT_1_RC_CLIENT
.subscriber('app_user_id')
.get_or_createYou can also pass configuration values as a Hash to the Tarpon::Client constructor, if desired:
Tarpon::Client.new(public_api_key: 'public-key', private_api_key: 'private-key')Performing requests
Get or create a subscriber
Tarpon::Client
.subscriber('app_user_id')
.get_or_createUpdate subscriber attributes
Tarpon::Client
.subscriber('app_user_id')
.attributes
.update('$email': {
value: 'test@example.com'
})Delete a subscriber
Tarpon::Client
.subscriber('app_user_id')
.deleteGrant a promotional entitlement
Tarpon::Client
.subscriber('app_user_id')
.entitlements('entitlement_id')
.grant_promotional(duration: 'daily', start_time_ms: 1582023714931)Be aware that RevenueCat doesn't create the subscriber automatically. If the app_user_id doesn't exist, the request will fail with a 404 Not Found. Perform a Tarpon::Client.subscriber('app_user_id').get_or_create beforehand to make sure the subscriber exists when granting promotional entitlements:
Tarpon::Client.subscriber('app_user_id').get_or_create # subscriber is created
Tarpon::Client
.subscriber('app_user_id')
.entitlements('entitlement_id')
.grant_promotional(duration: 'daily', start_time_ms: 1582023714931)Check the endpoint reference for valid duration values, Tarpon does not perform any input validation.
List offerings available to subscriber
Tarpon::Client
.subscriber('app_user_id')
.offerings
.list(platform)Where platform is one either ios, android, macos, uikitformac or stripe.
Read more about offerings here
Revoke a promotional entitlement
Tarpon::Client
.subscriber('app_user_id')
.entitlements('entitlement_id')
.revoke_promotionalCreate a purchase
platform = 'ios' # possible values: android|ios|stripe
payload = {
app_user_id: 'app_user_id',
fetch_token: 'fetch_token',
}
Tarpon::Client
.receipt
.create(platform: platform, payload)Check the endpoint reference for a valid purchase payload.
Defer billing (android)
Tarpon::Client
.subscriber('app_user_id')
.subscriptions('product_id')
.defer(expiry_time_ms: 1582023715118)Handling responses
By default, Tarpon will raise custom errors in the following occasions:
-
Tarpon::NotFoundErrorwill be raised when RevenueCat server responds with a not found status code. -
Tarpon::InvalidCredentialsErrorwill be raised when RevenueCat server responds with unauthorized status code, e.g. invalid API key. -
Tarpon::ServerErrorwill be raised when RevenueCat server responds with internal error status code (5xx). -
Tarpon::TimeoutErrorwill be raised when RevenueCat server takes too long to respond, based onTarpon::Client.timeout. -
Tarpon::TooManyRequestswill be raise when RevenueCat server responds with 429 status code.
For success and client error status codes, Tarpon will parse it to the response object.
The Response object
response = Tarpon::Client
.subscriber('app_user_id')
.get_or_createThe plain response body from RevenueCat is stored in the raw attribute:
response.raw
# {
# request_date_ms: 1582029851163,
# subscriber: {
# original_app_user_id: 'app_user_id',
# ...
# }
# }Use the success? method to know whether the request was successful:
response.success? # booleanThe subscriber entity is stored in the subscriber attribute when the subscriber object is returned by RevenueCat:
response.subscriber # <Tarpon::Entity::Subscriber>The subscriber entity
The subscriber entity comes with a few goodies that might save you some time.
Get the user entitlements:
response.subscriber.entitlementsGet only active user entitlements:
response.subscriber.entitlements.activeThe entitlement entity
response.subscriber.entitlements.each do |entitlement|
entitlement.expires_date # Ruby time parsed from iso8601
entitlement.active? # true if expires_date > Time.now.utc
endAdvanced HTTP configuration
You can access the HTTP requests as they are performed for advanced configuration, allowing you to configure things such as logging, instrumentation, more granular timeouts, or using an HTTP proxy.
Under the hood, Tarpon uses the HTTP.rb library, which provides an easy to extend API to configure HTTP requests. You can access this by providing a custom http_middleware Proc when configuring a Tarpon::Client that receives and returns an HTTP::Client.
Tarpon::Client.configure do |c|
c.http_middleware = ->(http_client) do
http_client
.use(instrumentation: { instrumenter: ActiveSupport::Notifications.instrumenter })
.via('https://custom.proxy.com', 8080)
end
endContributing
Bug reports and pull requests are welcome on GitHub at https://github.com/fishbrain/tarpon.
Clone the repository using
$ git clone https://github.com/fishbrain/tarpon.git && cd tarpon
Install development dependencies through Bundler
$ bundle install
Run tests and linter using
$ bundle exec rspec && bundle exec rubocop
License
The gem is available as open source under the terms of the MIT License.