algolia 2.0.0.pre.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
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