Class: Altertable::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/altertable/client.rb,
sig/altertable/client.rbs

Constant Summary collapse

DEFAULT_BASE_URL =

Returns:

  • (String)
"https://api.altertable.ai"
DEFAULT_TIMEOUT =

Returns:

  • (Integer)
5
DEFAULT_ENVIRONMENT =

Returns:

  • (String)
"production"

Instance Method Summary collapse

Constructor Details

#initialize(api_key, options = {}) ⇒ Client

Returns a new instance of Client.

Parameters:

  • api_key (String)
  • options (::Hash[Symbol, untyped]) (defaults to: {})

Raises:



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/altertable/client.rb', line 14

def initialize(api_key, options = {})
  raise ConfigurationError, "API Key is required" if api_key.nil? || api_key.empty?

  @api_key = api_key
  @base_url = options[:base_url] || DEFAULT_BASE_URL
  @environment = options[:environment] || DEFAULT_ENVIRONMENT
  @timeout = options[:request_timeout] || DEFAULT_TIMEOUT
  @release = options[:release]
  @debug = options[:debug] || false
  @on_error = options[:on_error]

  # Initialize adapter
  adapter_name = options[:adapter]
  headers = {
    "X-API-Key" => @api_key,
    "Content-Type" => "application/json"
  }
  @adapter = select_adapter(adapter_name, { base_url: @base_url, timeout: @timeout, headers: headers, proxy: options[:proxy] })
end

Instance Method Details

#alias(distinct_id, new_user_id, **options) ⇒ Object

Parameters:

  • distinct_id (String)
  • new_user_id (String)
  • options (Object)

Returns:

  • (Object)


69
70
71
72
73
74
75
76
77
78
79
# File 'lib/altertable/client.rb', line 69

def alias(distinct_id, new_user_id, **options)
  timestamp = options[:timestamp] || Time.now.utc.iso8601(3)
  payload = {
    timestamp: timestamp,
    environment: @environment,
    distinct_id: distinct_id,
    new_user_id: new_user_id
  }

  post("/alias", payload)
end

#handle_error(error) ⇒ Object

Parameters:

  • error (Exception)

Returns:

  • (Object)


137
138
139
140
141
142
143
144
145
146
# File 'lib/altertable/client.rb', line 137

def handle_error(error)
  wrapped_error = if error.is_a?(AltertableError)
                    error
                  else
                    AltertableError.new(error.message, error)
                  end

  @on_error&.call(wrapped_error)
  raise wrapped_error
end

#handle_response(res) ⇒ Object

Parameters:

  • res (Object)

Returns:

  • (Object)


117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/altertable/client.rb', line 117

def handle_response(res)
  case res.status
  when 200..299
    begin
      JSON.parse(res.body)
    rescue StandardError
      {}
    end
  when 422
    error_data = begin
                   JSON.parse(res.body)
    rescue StandardError
                   {}
    end
    raise ApiError.new("Unprocessable Entity: #{error_data['message']}", res.status, error_data)
  else
    raise ApiError.new("HTTP Error: #{res.status}", res.status)
  end
end

#identify(user_id, **options) ⇒ Object

Parameters:

  • user_id (String)
  • options (Object)

Returns:

  • (Object)


54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/altertable/client.rb', line 54

def identify(user_id, **options)
  traits = options[:traits] || {}
  timestamp = options[:timestamp] || Time.now.utc.iso8601(3)
  payload = {
    timestamp: timestamp,
    environment: @environment,
    distinct_id: user_id,
    traits: traits
  }
  payload[:anonymous_id] = options[:anonymous_id] if options.key?(:anonymous_id)
  payload[:device_id] = options[:device_id] if options.key?(:device_id)

  post("/identify", payload)
end

#post(path, payload) ⇒ Object

Parameters:

  • path (String)
  • payload (::Hash[Symbol | String, untyped])

Returns:

  • (Object)


110
111
112
113
114
115
# File 'lib/altertable/client.rb', line 110

def post(path, payload)
  res = @adapter.post(path, body: payload.to_json)
  handle_response(res)
rescue StandardError => e
  handle_error(e)
end

#select_adapter(name, options) ⇒ Object

Parameters:

  • name (Symbol, nil)
  • options (::Hash[Symbol, untyped])

Returns:

  • (Object)


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/altertable/client.rb', line 83

def select_adapter(name, options)
  case name
  when :faraday
    Adapters::FaradayAdapter.new(**options)
  when :httpx
    Adapters::HttpxAdapter.new(**options)
  when :net_http
    Adapters::NetHttpAdapter.new(**options)
  else
    # Auto-detect
    if defined?(Faraday) || try_require("faraday")
      Adapters::FaradayAdapter.new(**options)
    elsif defined?(HTTPX) || try_require("httpx")
      Adapters::HttpxAdapter.new(**options)
    else
      Adapters::NetHttpAdapter.new(**options)
    end
  end
end

#track(event, distinct_id, **options) ⇒ Object

Parameters:

  • event (String)
  • distinct_id (String)
  • options (Object)

Returns:

  • (Object)


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/altertable/client.rb', line 34

def track(event, distinct_id, **options)
  properties = options[:properties] || {}
  timestamp = options[:timestamp] || Time.now.utc.iso8601(3)
  payload = {
    timestamp: timestamp,
    event: event,
    environment: @environment,
    distinct_id: distinct_id,
    properties: {
      '$lib': "altertable-ruby",
      '$lib_version': Altertable::VERSION
    }.merge(properties)
  }
  payload[:properties]["$release"] = @release if @release
  payload[:anonymous_id] = options[:anonymous_id] if options.key?(:anonymous_id)
  payload[:device_id] = options[:device_id] if options.key?(:device_id)

  post("/track", payload)
end

#try_require(gem_name) ⇒ Boolean

Parameters:

  • gem_name (String)

Returns:

  • (Boolean)


103
104
105
106
107
108
# File 'lib/altertable/client.rb', line 103

def try_require(gem_name)
  require gem_name
  true
rescue LoadError
  false
end