class Snov::Client

Constants

ERROR_CLASSES

Attributes

client_id[RW]
client_secret[RW]
timeout_seconds[RW]

Public Class Methods

new(client_id:, client_secret:, access_token: nil, timeout_seconds: 90) click to toggle source
# File lib/snov/client.rb, line 46
def initialize(client_id:, client_secret:, access_token: nil, timeout_seconds: 90)
  self.client_id = client_id.to_str
  self.client_secret = client_secret.to_str
  @access_token = access_token
  @timeout_seconds = timeout_seconds.to_int
end
select_error_class(resp, fallback: ResponseError) click to toggle source
# File lib/snov/client.rb, line 38
def self.select_error_class(resp, fallback: ResponseError)
  if resp&.body.to_s.include?('you ran out of credits')
    OutOfCreditsError
  else
    ERROR_CLASSES.fetch(resp.status, fallback)
  end
end

Public Instance Methods

get(path, params = {}) click to toggle source
# File lib/snov/client.rb, line 53
def get(path, params = {})
  resp = conn.get(path) do |req|
    req.body = MultiJson.dump(params.merge('access_token' => access_token))
    req.options.timeout = timeout_seconds # open/read timeout in seconds
    req.options.open_timeout = timeout_seconds # connection open timeout in seconds
  end
  parse_response(resp, path, params)
rescue Faraday::TimeoutError, Timeout::Error => e
  raise TimedOut, e.message
end
post(path, params = {}) click to toggle source
# File lib/snov/client.rb, line 64
def post(path, params = {})
  resp = conn.post(path) do |req|
    req.body = MultiJson.dump(params.merge('access_token' => access_token))
    req.options.timeout = timeout_seconds # open/read timeout in seconds
    req.options.open_timeout = timeout_seconds # connection open timeout in seconds
  end
  parse_response(resp, path, params)
rescue Faraday::TimeoutError, Timeout::Error => e
  raise TimedOut, e.message
end

Private Instance Methods

access_token() click to toggle source
# File lib/snov/client.rb, line 87
def access_token
  return @access_token if @access_token

  @access_token = generate_access_token
end
access_token_params() click to toggle source
# File lib/snov/client.rb, line 93
def access_token_params
  { 'grant_type' => 'client_credentials', 'client_id' => client_id, 'client_secret' => client_secret }
end
conn() click to toggle source
# File lib/snov/client.rb, line 117
def conn
  @conn ||= Faraday.new(
    url: 'https://api.snov.io',
    headers: { 'Content-Type' => 'application/json' }
  )
end
generate_access_token() click to toggle source
# File lib/snov/client.rb, line 97
def generate_access_token
  resp = conn.post('/v1/oauth/access_token') do |req|
    req.body = MultiJson.dump(access_token_params)
    req.options.timeout = timeout_seconds # open/read timeout in seconds
    req.options.open_timeout = timeout_seconds # connection open timeout in seconds
  end
  handle_error(resp, "POST /v1/oauth/access_token")
  raise AuthError, 'Snov auth failed' if resp.body.blank?

  MultiJson.load(resp.body).fetch("access_token")
rescue Timeout::Error => e
  raise TimedOut, e.message
end
handle_error(resp, prefix) click to toggle source
# File lib/snov/client.rb, line 111
def handle_error(resp, prefix)
  return if resp.success?

  raise ERROR_CLASSES.fetch(resp.status, SnovError), "#{prefix} (#{resp.status})"
end
parse_response(resp, path, _params) click to toggle source
# File lib/snov/client.rb, line 77
def parse_response(resp, path, _params)
  unless resp.success?
    error_class = Client.select_error_class(resp, fallback: ResponseError)
    raise error_class.new("#{path} (#{resp.status})", response: resp&.body)
  end
  MultiJson.load(resp.body)
end