class Plivo::BaseClient

Attributes

auth_credentials[R]

Base stuff

headers[R]

Base stuff

Public Class Methods

new(auth_id = nil, auth_token = nil, proxy_options = nil, timeout=5) click to toggle source
# File lib/plivo/base_client.rb, line 16
def initialize(auth_id = nil, auth_token = nil, proxy_options = nil, timeout=5)
  configure_credentials(auth_id, auth_token)
  configure_proxies(proxy_options)
  configure_timeout(timeout)
  configure_headers
  configure_connection
end

Public Instance Methods

auth_id() click to toggle source
# File lib/plivo/base_client.rb, line 24
def auth_id
  @auth_credentials[:auth_id]
end
process_response(method, response) click to toggle source
# File lib/plivo/base_client.rb, line 28
def process_response(method, response)
  handle_response_exceptions(response)
  if method == 'DELETE'
    if !([200, 204].include? response[:status])
      raise Exceptions::PlivoRESTError, "Resource at #{response[:url]} "\
      'couldn\'t be deleted'
    end
  elsif !([200, 201, 202, 204, 207, 206].include? response[:status])
    raise Exceptions::PlivoRESTError, "Received #{response[:status]} for #{method}"
  end
  @@voice_retry_count = 0
  response[:body]
end
send_request(resource_path, method = 'GET', data = {}, timeout = nil, use_multipart_conn = false, options = nil) click to toggle source
# File lib/plivo/base_client.rb, line 42
def send_request(resource_path, method = 'GET', data = {}, timeout = nil, use_multipart_conn = false, options = nil)
  timeout ||= @timeout

  if options[:is_voice_request] == true
    response = case method
               when 'GET' then send_get(resource_path, data, timeout, is_voice_request: options[:is_voice_request], voice_retry_count: @@voice_retry_count)
               when 'POST' then send_post(resource_path, data, timeout, use_multipart_conn, is_voice_request: options[:is_voice_request], voice_retry_count: @@voice_retry_count)
               when 'DELETE' then send_delete(resource_path, data, timeout, is_voice_request: options[:is_voice_request], voice_retry_count: @@voice_retry_count)
               else raise_invalid_request("#{method} not supported by Plivo, yet")
               end

    if response.status >= 500
      @@voice_retry_count += 1
      if @@voice_retry_count > 2
        return process_response(method, response.to_hash)
      end
      is_voice_request = true
      send_request(resource_path, method, data, timeout, use_multipart_conn, is_voice_request: is_voice_request)
    else
      process_response(method, response.to_hash)
    end
  elsif options[:is_lookup_request] == true
    response = case method
               when 'GET' then send_get(resource_path, data, timeout, is_lookup_request: options[:is_lookup_request])
               else raise_invalid_request("#{method} not supported by Plivo, yet")
               end
    process_response(method, response.to_hash)
  else
    response = case method
               when 'GET' then send_get(resource_path, data, timeout)
               when 'POST' then send_post(resource_path, data, timeout, use_multipart_conn)
               when 'DELETE' then send_delete(resource_path, data, timeout)
               else raise_invalid_request("#{method} not supported by Plivo, yet")
               end

    process_response(method, response.to_hash)
  end
end

Private Instance Methods

auth_token() click to toggle source
# File lib/plivo/base_client.rb, line 83
def auth_token
  @auth_credentials[:auth_token]
end
configure_connection() click to toggle source
# File lib/plivo/base_client.rb, line 132
def configure_connection
  @conn = Faraday.new(@base_uri) do |faraday|
    faraday.headers = @headers

    # DANGER: Basic auth should always come after headers, else
    # The headers will replace the basic_auth

    faraday.headers['Authorization'] = "Basic #{Base64.strict_encode64("#{auth_id}:#{auth_token}")}"

    faraday.proxy=@proxy_hash if @proxy_hash
    faraday.response :json, content_type: /\bjson$/
    faraday.adapter Faraday.default_adapter
  end

  @voice_conn_no_retry = Faraday.new(@voice_base_uri) do |faraday|
    faraday.headers = @headers

    # DANGER: Basic auth should always come after headers, else
    # The headers will replace the basic_auth

    faraday.headers['Authorization'] = "Basic #{Base64.strict_encode64("#{auth_id}:#{auth_token}")}"

    faraday.proxy=@proxy_hash if @proxy_hash
    faraday.response :json, content_type: /\bjson$/
    faraday.adapter Faraday.default_adapter
  end

  @voice_conn_retry_1 = Faraday.new(@voice_base_uri_fallback_1) do |faraday|
    faraday.headers = @headers

    # DANGER: Basic auth should always come after headers, else
    # The headers will replace the basic_auth

    faraday.headers['Authorization'] = "Basic #{Base64.strict_encode64("#{auth_id}:#{auth_token}")}"

    faraday.proxy=@proxy_hash if @proxy_hash
    faraday.response :json, content_type: /\bjson$/
    faraday.adapter Faraday.default_adapter
  end

  @voice_conn_retry_2 = Faraday.new(@voice_base_uri_fallback_2) do |faraday|
    faraday.headers = @headers

    # DANGER: Basic auth should always come after headers, else
    # The headers will replace the basic_auth

    faraday.headers['Authorization'] = "Basic #{Base64.strict_encode64("#{auth_id}:#{auth_token}")}"

    faraday.proxy=@proxy_hash if @proxy_hash
    faraday.response :json, content_type: /\bjson$/
    faraday.adapter Faraday.default_adapter
  end

  @callinsights_conn = Faraday.new(@callinsights_base_uri) do |faraday|
    faraday.headers = @headers

    # DANGER: Basic auth should always come after headers, else
    # The headers will replace the basic_auth

    faraday.headers['Authorization'] = "Basic #{Base64.strict_encode64("#{auth_id}:#{auth_token}")}"

    faraday.proxy=@proxy_hash if @proxy_hash
    faraday.response :json, content_type: /\bjson$/
    faraday.adapter Faraday.default_adapter
  end

  @lookup_conn = Faraday.new(@lookup_base_uri) do |faraday|
    faraday.headers = @headers

    # DANGER: Basic auth should always come after headers, else
    # The headers will replace the basic_auth

    faraday.headers['Authorization'] = "Basic #{Base64.strict_encode64("#{auth_id}:#{auth_token}")}"

    faraday.proxy=@proxy_hash if @proxy_hash
    faraday.response :json, content_type: /\bjson$/
    faraday.adapter Faraday.default_adapter
  end
end
configure_credentials(auth_id, auth_token) click to toggle source
# File lib/plivo/base_client.rb, line 87
def configure_credentials(auth_id, auth_token)
  # Fetches and sets the right credentials
  auth_id ||= ENV['PLIVO_AUTH_ID']
  auth_token ||= ENV['PLIVO_AUTH_TOKEN']

  raise Exceptions::AuthenticationError, 'Couldn\'t find auth credentials' unless
      auth_id && auth_token

  raise Exceptions::AuthenticationError, "Invalid auth_id: '#{auth_id}'" unless
      Utils.valid_account?(auth_id)

  @auth_credentials = {
      auth_id: auth_id,
      auth_token: auth_token
  }
end
configure_headers() click to toggle source
# File lib/plivo/base_client.rb, line 123
def configure_headers
  @headers = {
      'User-Agent' => user_agent,
      'Content-Type' => 'application/json',
      'Accept' => 'application/json'
  }
end
configure_proxies(proxy_dict) click to toggle source
# File lib/plivo/base_client.rb, line 104
def configure_proxies(proxy_dict)
  @proxy_hash = nil
  return unless proxy_dict

  @proxy_hash = {
      uri: "#{proxy_dict[:proxy_host]}:#{proxy_dict[:proxy_port]}",
      user: proxy_dict[:proxy_user],
      password: proxy_dict[:proxy_pass]
  }
end
configure_timeout(timeout) click to toggle source
# File lib/plivo/base_client.rb, line 115
def configure_timeout(timeout)
  @timeout = timeout
end
handle_response_exceptions(response) click to toggle source
# File lib/plivo/base_client.rb, line 344
def handle_response_exceptions(response)
  exception_mapping = {
    400 => [
      Exceptions::ValidationError,
      'A parameter is missing or is invalid while accessing resource'
    ],
    401 => [
      Exceptions::AuthenticationError,
      'Failed to authenticate while accessing resource'
    ],
    404 => [
      Exceptions::ResourceNotFoundError,
      'Resource not found'
    ],
    405 => [
      Exceptions::InvalidRequestError,
      'HTTP method used is not allowed to access resource'
    ],
    409 => [
      Exceptions::InvalidRequestError,
      'Conflict'
    ],
    422 => [
      Exceptions::InvalidRequestError,
      'Unprocessable Entity'
    ],
    500 => [
      Exceptions::PlivoServerError,
      'A server error occurred while accessing resource'
    ]
  }

  response_json = response[:body]
  return unless exception_mapping.key?(response[:status])

  exception_now = exception_mapping[response[:status]]
  error_message = if response_json.is_a?(Hash) && response_json.key?('error')
                    response_json['error']
                  else
                    exception_now[1] + " at: #{response[:url]}"
                  end
  if error_message.is_a?(Hash) && error_message.key?('error')
    error_message = error_message['error']
  end

  # Add api_id to the error message if present
  if response_json.is_a?(Hash) && response_json.key?('api_id')
    error_message += " (api_id: #{response_json['api_id']})"
  end
  raise exception_now[0], error_message.to_s
end
send_delete(resource_path, data, timeout, options = nil) click to toggle source
# File lib/plivo/base_client.rb, line 313
def send_delete(resource_path, data, timeout, options = nil)
  if options
    if options[:voice_retry_count] == 0 and options[:is_voice_request] == true
      response = @voice_conn_no_retry.delete do |req|
        req.url resource_path
        req.options.timeout = timeout if timeout
        req.body = JSON.generate(data) if data
      end
    elsif options[:voice_retry_count] == 1 and options[:is_voice_request] == true
      response = @voice_conn_retry_1.delete do |req|
        req.url resource_path
        req.options.timeout = timeout if timeout
        req.body = JSON.generate(data) if data
      end
    elsif options[:voice_retry_count] == 2 and options[:is_voice_request] == true
      response = @voice_conn_retry_2.delete do |req|
        req.url resource_path
        req.options.timeout = timeout if timeout
        req.body = JSON.generate(data) if data
      end
    end
  else
    response = @conn.delete do |req|
      req.url resource_path
      req.options.timeout = timeout if timeout
      req.body = JSON.generate(data) if data
    end
  end
  response
end
send_get(resource_path, data, timeout, options = nil) click to toggle source
# File lib/plivo/base_client.rb, line 212
def send_get(resource_path, data, timeout, options = nil)
  if options
    if options[:voice_retry_count] == 0 and options[:is_voice_request] == true
      response = @voice_conn_no_retry.get do |req|
        req.url resource_path, data
        req.options.timeout = timeout if timeout
      end
    elsif options[:voice_retry_count] == 1 and options[:is_voice_request] == true
      response = @voice_conn_retry_1.get do |req|
        req.url resource_path, data
        req.options.timeout = timeout if timeout
      end
    elsif options[:voice_retry_count] == 2 and options[:is_voice_request] == true
      response = @voice_conn_retry_2.get do |req|
        req.url resource_path, data
        req.options.timeout = timeout if timeout
      end
    elsif options[:is_lookup_request] == true
      response = @lookup_conn.get do |req|
        req.url resource_path, data
        req.options.timeout = timeout if timeout
      end
    end
  else
    response = @conn.get do |req|
      req.url resource_path, data
      req.options.timeout = timeout if timeout
    end
  end
  response
end
send_post(resource_path, data, timeout, use_multipart_conn, options = nil) click to toggle source
# File lib/plivo/base_client.rb, line 244
def send_post(resource_path, data, timeout, use_multipart_conn, options = nil)
  if use_multipart_conn
    multipart_conn = Faraday.new(@base_uri) do |faraday|
      faraday.headers = {
          'User-Agent' => @headers['User-Agent'],
          'Accept' => @headers['Accept']
      }

      # DANGER: Basic auth should always come after headers, else
      # The headers will replace the basic_auth

      faraday.request :multipart
      faraday.request :url_encoded
      faraday.headers['Authorization'] = "Basic #{Base64.strict_encode64("#{auth_id}:#{auth_token}")}"

      faraday.proxy=@proxy_hash if @proxy_hash
      faraday.response :json, content_type: /\bjson$/
      faraday.adapter Faraday.default_adapter
    end

    response = multipart_conn.post do |req|
      req.url resource_path
      req.options.timeout = timeout if timeout
      req.body = data
      puts req
    end
  else
    if !data.nil? && (data.has_key? 'is_callinsights_request')
      callinsight_base_url = data['callinsight_base_url']
      resource_path = data['request_url']
      data.delete('is_callinsights_request')
      data.delete('request_url')

      response = @callinsights_conn.post do |req|
        req.url resource_path
        req.options.timeout = timeout if timeout
        req.body = JSON.generate(data) if data
      end
    elsif options
      if options[:voice_retry_count] == 0 and options[:is_voice_request] == true
        response = @voice_conn_no_retry.post do |req|
          req.url resource_path
          req.options.timeout = timeout if timeout
          req.body = JSON.generate(data) if data
        end
      elsif options[:voice_retry_count] == 1 and options[:is_voice_request] == true
        response = @voice_conn_retry_1.post do |req|
          req.url resource_path
          req.options.timeout = timeout if timeout
          req.body = JSON.generate(data) if data
        end
      elsif options[:voice_retry_count] == 2 and options[:is_voice_request] == true
        response = @voice_conn_retry_2.post do |req|
          req.url resource_path
          req.options.timeout = timeout if timeout
          req.body = JSON.generate(data) if data
        end
      end
    else
      response = @conn.post do |req|
        req.url resource_path
        req.options.timeout = timeout if timeout
        req.body = JSON.generate(data) if data
      end
    end
  end
  response
end
user_agent() click to toggle source
# File lib/plivo/base_client.rb, line 119
def user_agent
  "plivo-ruby/#{Plivo::VERSION} (Ruby #{RUBY_VERSION})"
end