algolia 2.0.0.pre.alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +146 -0
  3. data/.github/ISSUE_TEMPLATE.md +20 -0
  4. data/.github/PULL_REQUEST_TEMPLATE.md +22 -0
  5. data/.gitignore +38 -0
  6. data/.rubocop.yml +186 -0
  7. data/.rubocop_todo.yml +14 -0
  8. data/CODE_OF_CONDUCT.md +74 -0
  9. data/Gemfile +18 -0
  10. data/LICENSE +21 -0
  11. data/README.md +56 -0
  12. data/Rakefile +45 -0
  13. data/Steepfile +6 -0
  14. data/algolia.gemspec +41 -0
  15. data/bin/console +21 -0
  16. data/bin/setup +8 -0
  17. data/lib/algolia.rb +42 -0
  18. data/lib/algolia/account_client.rb +65 -0
  19. data/lib/algolia/analytics_client.rb +105 -0
  20. data/lib/algolia/config/algolia_config.rb +40 -0
  21. data/lib/algolia/config/analytics_config.rb +20 -0
  22. data/lib/algolia/config/insights_config.rb +20 -0
  23. data/lib/algolia/config/recommendation_config.rb +20 -0
  24. data/lib/algolia/config/search_config.rb +40 -0
  25. data/lib/algolia/defaults.rb +35 -0
  26. data/lib/algolia/enums/call_type.rb +4 -0
  27. data/lib/algolia/enums/retry_outcome_type.rb +5 -0
  28. data/lib/algolia/error.rb +29 -0
  29. data/lib/algolia/helpers.rb +83 -0
  30. data/lib/algolia/http/http_requester.rb +84 -0
  31. data/lib/algolia/http/response.rb +23 -0
  32. data/lib/algolia/insights_client.rb +238 -0
  33. data/lib/algolia/iterators/base_iterator.rb +19 -0
  34. data/lib/algolia/iterators/object_iterator.rb +27 -0
  35. data/lib/algolia/iterators/paginator_iterator.rb +44 -0
  36. data/lib/algolia/iterators/rule_iterator.rb +9 -0
  37. data/lib/algolia/iterators/synonym_iterator.rb +9 -0
  38. data/lib/algolia/logger_helper.rb +14 -0
  39. data/lib/algolia/recommendation_client.rb +60 -0
  40. data/lib/algolia/responses/add_api_key_response.rb +38 -0
  41. data/lib/algolia/responses/base_response.rb +9 -0
  42. data/lib/algolia/responses/delete_api_key_response.rb +40 -0
  43. data/lib/algolia/responses/indexing_response.rb +28 -0
  44. data/lib/algolia/responses/multiple_batch_indexing_response.rb +29 -0
  45. data/lib/algolia/responses/multiple_response.rb +45 -0
  46. data/lib/algolia/responses/restore_api_key_response.rb +36 -0
  47. data/lib/algolia/responses/update_api_key_response.rb +39 -0
  48. data/lib/algolia/search_client.rb +614 -0
  49. data/lib/algolia/search_index.rb +1094 -0
  50. data/lib/algolia/transport/request_options.rb +94 -0
  51. data/lib/algolia/transport/retry_strategy.rb +117 -0
  52. data/lib/algolia/transport/stateful_host.rb +26 -0
  53. data/lib/algolia/transport/transport.rb +161 -0
  54. data/lib/algolia/user_agent.rb +25 -0
  55. data/lib/algolia/version.rb +3 -0
  56. data/sig/config/algolia_config.rbs +24 -0
  57. data/sig/config/analytics_config.rbs +11 -0
  58. data/sig/config/insights_config.rbs +11 -0
  59. data/sig/config/recommendation_config.rbs +11 -0
  60. data/sig/config/search_config.rbs +11 -0
  61. data/sig/enums/call_type.rbs +5 -0
  62. data/sig/helpers.rbs +12 -0
  63. data/sig/http/http_requester.rbs +17 -0
  64. data/sig/http/response.rbs +14 -0
  65. data/sig/interfaces/_connection.rbs +16 -0
  66. data/sig/iterators/base_iterator.rbs +15 -0
  67. data/sig/iterators/object_iterator.rbs +6 -0
  68. data/sig/iterators/paginator_iterator.rbs +8 -0
  69. data/sig/iterators/rule_iterator.rbs +5 -0
  70. data/sig/iterators/synonym_iterator.rbs +5 -0
  71. data/sig/transport/request_options.rbs +33 -0
  72. data/sig/transport/stateful_host.rbs +21 -0
  73. data/test/algolia/integration/account_client_test.rb +47 -0
  74. data/test/algolia/integration/analytics_client_test.rb +113 -0
  75. data/test/algolia/integration/base_test.rb +9 -0
  76. data/test/algolia/integration/insights_client_test.rb +80 -0
  77. data/test/algolia/integration/mocks/mock_requester.rb +45 -0
  78. data/test/algolia/integration/recommendation_client_test.rb +30 -0
  79. data/test/algolia/integration/search_client_test.rb +361 -0
  80. data/test/algolia/integration/search_index_test.rb +698 -0
  81. data/test/algolia/unit/helpers_test.rb +69 -0
  82. data/test/algolia/unit/retry_strategy_test.rb +139 -0
  83. data/test/algolia/unit/user_agent_test.rb +16 -0
  84. data/test/test_helper.rb +89 -0
  85. data/upgrade_guide.md +595 -0
  86. metadata +307 -0
@@ -0,0 +1,20 @@
1
+ module Algolia
2
+ module Analytics
3
+ class Config < AlgoliaConfig
4
+ attr_accessor :region, :default_hosts
5
+
6
+ # Initialize a config
7
+ #
8
+ # @option options [String] :app_id
9
+ # @option options [String] :api_key
10
+ # @option options [String] :region
11
+ #
12
+ def initialize(opts = {})
13
+ super(opts)
14
+
15
+ @region = opts[:region] || 'us'
16
+ @default_hosts = [Transport::StatefulHost.new("analytics.#{region}.algolia.com")]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Algolia
2
+ module Insights
3
+ class Config < AlgoliaConfig
4
+ attr_accessor :region, :default_hosts
5
+
6
+ # Initialize a config
7
+ #
8
+ # @option options [String] :app_id
9
+ # @option options [String] :api_key
10
+ # @option options [String] :region
11
+ #
12
+ def initialize(opts = {})
13
+ super(opts)
14
+
15
+ @region = opts[:region] || 'us'
16
+ @default_hosts = [Transport::StatefulHost.new("insights.#{region}.algolia.io")]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Algolia
2
+ module Recommendation
3
+ class Config < AlgoliaConfig
4
+ attr_accessor :region, :default_hosts
5
+
6
+ # Initialize a config
7
+ #
8
+ # @option options [String] :app_id
9
+ # @option options [String] :api_key
10
+ # @option options [String] :region
11
+ #
12
+ def initialize(opts = {})
13
+ super(opts)
14
+
15
+ @region = opts[:region] || 'us'
16
+ @default_hosts = [Transport::StatefulHost.new("recommendation.#{region}.algolia.com")]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,40 @@
1
+ require 'faraday'
2
+ require 'json'
3
+
4
+ require 'algolia/enums/call_type'
5
+
6
+ module Algolia
7
+ module Search
8
+ class Config < AlgoliaConfig
9
+ include CallType
10
+ attr_accessor :default_hosts
11
+
12
+ # Initialize a config
13
+ #
14
+ # @option options [String] :app_id
15
+ # @option options [String] :api_key
16
+ # @option options [Hash] :custom_hosts
17
+ #
18
+ def initialize(opts = {})
19
+ super(opts)
20
+ @default_hosts = []
21
+ hosts = []
22
+ hosts << Transport::StatefulHost.new("#{app_id}-dsn.algolia.net", accept: READ)
23
+ hosts << Transport::StatefulHost.new("#{app_id}.algolia.net", accept: WRITE)
24
+
25
+ stateful_hosts = 1.upto(3).map do |i|
26
+ Transport::StatefulHost.new("#{app_id}-#{i}.algolianet.com", accept: READ | WRITE)
27
+ end.shuffle
28
+
29
+ if opts.has_key?(:custom_hosts)
30
+ opts[:custom_hosts].each do |host|
31
+ host = Transport::StatefulHost.new(host)
32
+ @default_hosts.push(host)
33
+ end
34
+ else
35
+ @default_hosts = hosts + stateful_hosts
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,35 @@
1
+ module Defaults
2
+ REQUESTER_CLASS = Algolia::Http::HttpRequester
3
+ ADAPTER = 'net_http_persistent'
4
+ TTL = 300
5
+ # The version of the REST API implemented by this module.
6
+ VERSION = 1
7
+
8
+ # HTTP Headers
9
+ # ----------------------------------------
10
+
11
+ # The HTTP header used for passing your application ID to the Algolia API.
12
+ HEADER_APP_ID = 'X-Algolia-Application-Id'.freeze
13
+
14
+ # The HTTP header used for passing your API key to the Algolia API.
15
+ HEADER_API_KEY = 'X-Algolia-API-Key'.freeze
16
+
17
+ # HTTP ERROR CODES
18
+ # ----------------------------------------
19
+
20
+ ERROR_BAD_REQUEST = 400
21
+ ERROR_FORBIDDEN = 403
22
+ ERROR_NOT_FOUND = 404
23
+ ERROR_TIMED_OUT = 408
24
+
25
+ BATCH_SIZE = 1000
26
+ CONNECT_TIMEOUT = 2
27
+ READ_TIMEOUT = 30
28
+ WRITE_TIMEOUT = 5
29
+ USER_AGENT = "Algolia for Ruby (#{Algolia::VERSION}), Ruby (#{RUBY_VERSION})"
30
+
31
+ WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY = 100
32
+
33
+ GZIP_ENCODING = 'gzip'
34
+ NONE_ENCODING = 'none'
35
+ end
@@ -0,0 +1,4 @@
1
+ module CallType
2
+ READ = 1
3
+ WRITE = 2
4
+ end
@@ -0,0 +1,5 @@
1
+ module RetryOutcomeType
2
+ SUCCESS = 'SUCCESS'.freeze
3
+ RETRY = 'RETRY'.freeze
4
+ FAILURE = 'FAILURE'.freeze
5
+ end
@@ -0,0 +1,29 @@
1
+ module Algolia
2
+ # Base exception class for errors thrown by the Algolia
3
+ # client library. AlgoliaError will be raised by any
4
+ # network operation if Algolia.init() has not been called.
5
+ # Exception ... why? A:http://www.skorks.com/2009/09/ruby-exceptions-and-exception-handling/
6
+ #
7
+ class AlgoliaError < StandardError
8
+ end
9
+
10
+ # Used when hosts are unreachable
11
+ #
12
+ class AlgoliaUnreachableHostError < AlgoliaError
13
+ end
14
+
15
+ # An exception class raised when the REST API returns an error.
16
+ # The error code and message will be parsed out of the HTTP response,
17
+ # which is also included in the response attribute.
18
+ #
19
+ class AlgoliaHttpError < AlgoliaError
20
+ attr_accessor :code
21
+ attr_accessor :message
22
+
23
+ def initialize(code, message)
24
+ self.code = code
25
+ self.message = message
26
+ super("#{self.code}: #{self.message}")
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,83 @@
1
+ require 'multi_json'
2
+
3
+ module Helpers
4
+ # Convert an Hash to json
5
+ #
6
+ def to_json(body)
7
+ body.is_a?(String) ? body : MultiJson.dump(body)
8
+ end
9
+
10
+ # Converts each key of a hash to symbols
11
+ #
12
+ def symbolize_hash(hash)
13
+ hash.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
14
+ end
15
+
16
+ # Convert params to a full query string
17
+ #
18
+ def handle_params(params)
19
+ params.nil? || params.empty? ? '' : "?#{to_query_string(params)}"
20
+ end
21
+
22
+ # Create a query string from params
23
+ #
24
+ def to_query_string(params)
25
+ params.map do |key, value|
26
+ "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
27
+ end.join('&')
28
+ end
29
+
30
+ # Convert a json object to an hash
31
+ #
32
+ def json_to_hash(json, symbolize_keys)
33
+ MultiJson.load(json, symbolize_keys: symbolize_keys)
34
+ end
35
+
36
+ # Retrieve the given value associated with a key, in string or symbol format
37
+ #
38
+ def get_option(hash, key)
39
+ hash[key.to_sym] || hash[key] || nil
40
+ end
41
+
42
+ # Build a path with the given arguments
43
+ #
44
+ def path_encode(path, *args)
45
+ arguments = []
46
+ args.each do |arg|
47
+ arguments.push(CGI.escape(CGI.unescape(arg.to_s)))
48
+ end
49
+
50
+ format(path, *arguments)
51
+ end
52
+
53
+ # Support to convert old settings to their new names
54
+ #
55
+ def deserialize_settings(data)
56
+ settings = symbolize_hash(data)
57
+ keys = {
58
+ attributesToIndex: 'searchableAttributes',
59
+ numericAttributesToIndex: 'numericAttributesForFiltering',
60
+ slaves: 'replicas'
61
+ }
62
+
63
+ keys.each do |deprecated_key, current_key|
64
+ if settings.has_key?(deprecated_key)
65
+ settings[current_key.to_sym] = settings.delete(deprecated_key)
66
+ end
67
+ end
68
+
69
+ settings
70
+ end
71
+
72
+ def self.included(base)
73
+ base.extend(Helpers)
74
+ end
75
+
76
+ def hash_includes_subset?(hash, subset)
77
+ res = true
78
+ subset.each do |k, v|
79
+ res &&= hash[k] == v
80
+ end
81
+ res
82
+ end
83
+ end
@@ -0,0 +1,84 @@
1
+ module Algolia
2
+ module Http
3
+ class HttpRequester
4
+ include Helpers
5
+ attr_accessor :adapter, :logger
6
+
7
+ #
8
+ # @param adapter [Object] adapter used to make requests. Defaults to Net::Http
9
+ # @param logger [Object] logger used to log requests. Defaults to Algolia::LoggerHelper
10
+ #
11
+ def initialize(adapter, logger)
12
+ @adapter = adapter
13
+ @logger = logger
14
+ @connection = nil
15
+ end
16
+
17
+ # Sends request to the engine
18
+ #
19
+ # @param host [StatefulHost]
20
+ # @param method [Symbol]
21
+ # @param path [String]
22
+ # @param body [JSON]
23
+ # @param headers [Hash]
24
+ #
25
+ # @return [Http::Response]
26
+ #
27
+ def send_request(host, method, path, body, headers, timeout, connect_timeout)
28
+ connection = connection(host)
29
+ connection.options.timeout = timeout
30
+ connection.options.open_timeout = connect_timeout
31
+
32
+ if ENV['ALGOLIA_DEBUG']
33
+ @logger.info("Sending #{method.to_s.upcase!} request to #{path} with body #{body}")
34
+ end
35
+
36
+ response = connection.run_request(method, path, body, headers)
37
+
38
+ if response.success?
39
+ if ENV['ALGOLIA_DEBUG']
40
+ @logger.info("Request succeeded. Response status: #{response.status}, body: #{response.body}")
41
+ end
42
+ return Http::Response.new(status: response.status, body: response.body, headers: response.headers)
43
+ end
44
+
45
+ if ENV['ALGOLIA_DEBUG']
46
+ @logger.info("Request failed. Response status: #{response.status}, error: #{response.body}")
47
+ end
48
+ Http::Response.new(status: response.status, error: response.body, headers: response.headers)
49
+ rescue Faraday::TimeoutError => e
50
+ if ENV['ALGOLIA_DEBUG']
51
+ @logger.info("Request timed out. Error: #{e.message}")
52
+ end
53
+ Http::Response.new(error: e.message, has_timed_out: true)
54
+ rescue ::StandardError => e
55
+ if ENV['ALGOLIA_DEBUG']
56
+ @logger.info("Request failed. Error: #{e.message}")
57
+ end
58
+ Http::Response.new(error: e.message, network_failure: true)
59
+ end
60
+
61
+ # Retrieve the connection from the @connections
62
+ #
63
+ # @param host [StatefulHost]
64
+ #
65
+ # @return [Faraday::Connection]
66
+ #
67
+ def connection(host)
68
+ @connection ||= Faraday.new(build_url(host)) do |f|
69
+ f.adapter @adapter.to_sym
70
+ end
71
+ end
72
+
73
+ # Build url from host, path and parameters
74
+ #
75
+ # @param host [StatefulHost]
76
+ #
77
+ # @return [String]
78
+ #
79
+ def build_url(host)
80
+ host.protocol + host.url
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,23 @@
1
+ module Algolia
2
+ module Http
3
+ class Response
4
+ attr_reader :status, :body, :error, :headers, :has_timed_out, :network_failure
5
+
6
+ #
7
+ # @option status [String] Response status
8
+ # @option body [String] Response body
9
+ # @option error [String] Response error or caught error
10
+ # @option headers [String] Response headers
11
+ # @option has_timed_out [String] If the request has timed out
12
+ #
13
+ def initialize(opts = {})
14
+ @status = opts[:status]
15
+ @body = opts[:body] || ''
16
+ @error = opts[:error] || ''
17
+ @headers = opts[:headers] || ''
18
+ @has_timed_out = opts[:has_timed_out] || false
19
+ @network_failure = opts[:network_failure] || false
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,238 @@
1
+ module Algolia
2
+ module Insights
3
+ class Client
4
+ include Helpers
5
+
6
+ # Initializes the Insights client
7
+ #
8
+ # @param insights_config [Insights::Config] an Insights::Config object which contains your APP_ID and API_KEY
9
+ # @option adapter [Object] adapter object used for the connection
10
+ # @option logger [Object]
11
+ # @option http_requester [Object] http_requester object used for the connection
12
+ #
13
+ def initialize(insights_config, opts = {})
14
+ @config = insights_config
15
+ adapter = opts[:adapter] || Defaults::ADAPTER
16
+ logger = opts[:logger] || LoggerHelper.create('debug.log')
17
+ requester = opts[:http_requester] || Defaults::REQUESTER_CLASS.new(adapter, logger)
18
+ @transporter = Transport::Transport.new(@config, requester)
19
+ end
20
+
21
+ # Create a new client providing only app ID and API key
22
+ #
23
+ # @param app_id [String] Algolia application ID
24
+ # @param api_key [String] Algolia API key
25
+ #
26
+ # @return self
27
+ #
28
+ def self.create(app_id, api_key)
29
+ config = Insights::Config.new(app_id: app_id, api_key: api_key)
30
+ create_with_config(config)
31
+ end
32
+
33
+ # Create a new client providing only an Analytics::Config object
34
+ #
35
+ # @param config [Insights::Config]
36
+ #
37
+ # @return self
38
+ #
39
+ def self.create_with_config(config)
40
+ new(config)
41
+ end
42
+
43
+ # Create a new Insight User Client
44
+ #
45
+ # @param user_token [String]
46
+ #
47
+ # @return [UserClient]
48
+ #
49
+ def user(user_token)
50
+ UserClient.new(self, user_token)
51
+ end
52
+
53
+ # Push an event to the Insights API.
54
+ #
55
+ # @param event [Hash]
56
+ #
57
+ # @return [Hash]
58
+ #
59
+ def send_event(event, opts = {})
60
+ send_events([event], opts)
61
+ end
62
+
63
+ # Push an array of events to the Insights API.
64
+ #
65
+ # @param events [Array]
66
+ #
67
+ # @return [Hash]
68
+ #
69
+ def send_events(events, opts = {})
70
+ @transporter.write(:POST, '/1/events', { events: events }, opts)
71
+ end
72
+ end
73
+
74
+ class UserClient
75
+ # Initializes the Insights userClient
76
+ #
77
+ # @param insights_client [Insights::Client] Insights Client used to make API calls
78
+ # @param user_token [String] user token used to build the client
79
+ #
80
+ def initialize(insights_client, user_token)
81
+ @insights_client = insights_client
82
+ @user_token = user_token
83
+ end
84
+
85
+ # Send a click event to capture clicked items.
86
+ #
87
+ # @param event_name [String] Name of the event.
88
+ # @param index_name [String] Name of the index related to the click.
89
+ # @param object_ids [Array] A list of objectIDs (limited to 20)
90
+ #
91
+ # @return [Hash]
92
+ #
93
+ def clicked_object_ids(event_name, index_name, object_ids, opts = {})
94
+ @insights_client.send_event({
95
+ eventType: 'click',
96
+ eventName: event_name,
97
+ index: index_name,
98
+ userToken: @user_token,
99
+ objectIds: object_ids
100
+ }, opts)
101
+ end
102
+
103
+ # Send a click event to capture a query and its clicked items and positions.
104
+ #
105
+ # @param event_name [String] Name of the event.
106
+ # @param index_name [String] Name of the index related to the click.
107
+ # @param object_ids [Array] A list of objectIDs (limited to 20)
108
+ # @param positions [Array] Position of the click in the list of Algolia search results.
109
+ # @param query_id [String] Algolia queryID that can be found in the search response when using clickAnalytics
110
+ #
111
+ # @return [Hash]
112
+ #
113
+ def clicked_object_ids_after_search(event_name, index_name,
114
+ object_ids, positions, query_id, opts = {})
115
+ @insights_client.send_event({
116
+ eventType: 'click',
117
+ eventName: event_name,
118
+ index: index_name,
119
+ userToken: @user_token,
120
+ objectIds: object_ids,
121
+ positions: positions,
122
+ queryId: query_id
123
+ }, opts)
124
+ end
125
+
126
+ # Send a click event to capture the filters a user clicks on.
127
+ #
128
+ # @param event_name [String] Name of the event.
129
+ # @param index_name [String] Name of the index related to the click.
130
+ # @param filters [Array] A list of filters (limited to 10)
131
+ #
132
+ # @return [Hash]
133
+ #
134
+ def clicked_filters(event_name, index_name, filters, opts = {})
135
+ @insights_client.send_event({
136
+ eventType: 'click',
137
+ eventName: event_name,
138
+ index: index_name,
139
+ userToken: @user_token,
140
+ filters: filters
141
+ }, opts)
142
+ end
143
+
144
+ # Send a conversion event to capture clicked items.
145
+ #
146
+ # @param event_name [String] Name of the event.
147
+ # @param index_name [String] Name of the index related to the click.
148
+ # @param object_ids [Array] A list of objectIDs (limited to 20)
149
+ #
150
+ # @return [Hash]
151
+ #
152
+ def converted_object_ids(event_name, index_name, object_ids, opts = {})
153
+ @insights_client.send_event({
154
+ eventType: 'conversion',
155
+ eventName: event_name,
156
+ index: index_name,
157
+ userToken: @user_token,
158
+ objectIds: object_ids
159
+ }, opts)
160
+ end
161
+
162
+ # Send a conversion event to capture a query and its clicked items.
163
+ #
164
+ # @param event_name [String] Name of the event.
165
+ # @param index_name [String] Name of the index related to the click.
166
+ # @param object_ids [Array] A list of objectIDs (limited to 20)
167
+ # @param query_id [String] Algolia queryID, format: [a-z1-9]{32}.
168
+ #
169
+ # @return [Hash]
170
+ #
171
+ def converted_object_ids_after_search(event_name, index_name,
172
+ object_ids, query_id, opts = {})
173
+ @insights_client.send_event({
174
+ eventType: 'conversion',
175
+ eventName: event_name,
176
+ index: index_name,
177
+ userToken: @user_token,
178
+ objectIds: object_ids,
179
+ queryId: query_id
180
+ }, opts)
181
+ end
182
+
183
+ # Send a conversion event to capture the filters a user uses when converting.
184
+ #
185
+ # @param event_name [String] Name of the event.
186
+ # @param index_name [String] Name of the index related to the click.
187
+ # @param filters [Array] A list of filters (limited to 10)
188
+ #
189
+ # @return [Hash]
190
+ #
191
+ def converted_filters(event_name, index_name, filters, opts = {})
192
+ @insights_client.send_event({
193
+ eventType: 'conversion',
194
+ eventName: event_name,
195
+ index: index_name,
196
+ userToken: @user_token,
197
+ filters: filters
198
+ }, opts)
199
+ end
200
+
201
+ # Send a view event to capture clicked items.
202
+ #
203
+ # @param event_name [String] Name of the event.
204
+ # @param index_name [String] Name of the index related to the click.
205
+ # @param object_ids [Array] A list of objectIDs (limited to 20)
206
+ #
207
+ # @return [Hash]
208
+ #
209
+ def viewed_object_ids(event_name, index_name, object_ids, opts = {})
210
+ @insights_client.send_event({
211
+ eventType: 'view',
212
+ eventName: event_name,
213
+ index: index_name,
214
+ userToken: @user_token,
215
+ objectIds: object_ids
216
+ }, opts)
217
+ end
218
+
219
+ # Send a view event to capture the filters a user uses when viewing.
220
+ #
221
+ # @param event_name [String] Name of the event.
222
+ # @param index_name [String] Name of the index related to the click.
223
+ # @param filters [Array] A list of filters (limited to 10)
224
+ #
225
+ # @return [Hash]
226
+ #
227
+ def viewed_filters(event_name, index_name, filters, opts = {})
228
+ @insights_client.send_event({
229
+ eventType: 'view',
230
+ eventName: event_name,
231
+ index: index_name,
232
+ userToken: @user_token,
233
+ filters: filters
234
+ }, opts)
235
+ end
236
+ end
237
+ end
238
+ end