promoted-ruby-client 0.1.0 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4494d298c8907ddb04588f1430d93ff2e83dd1978df0cfcb419df63db0cf302a
4
- data.tar.gz: ab8105ad6c2dc8c8fc6992f5a312b240dcda3f13624fa3258fc769685ba9bdf3
3
+ metadata.gz: 6638e3f3f180e08d693f00d9d53caae30cfc737b2023adf0d181c18c1e379369
4
+ data.tar.gz: 429c6c2cfc5022ea9f38913cbc0e4b7d218787f817152661f2624d8265fd1f8b
5
5
  SHA512:
6
- metadata.gz: 97a95326b32122f9d81292881c139cd0902f98c92dded7015d8ab7483c83b322f1e668f999da981a59e7c686523c74bf2ece6443e3dab26307cf44470f6a0cb9
7
- data.tar.gz: 703316787c03c1e30eec766fda2f2247d357b8ad4e8c9b99765421a7d0fc119f998ba2cbb342044e229ad8067672a174a2f31f8cf62ce9206f545ba005fc1a11
6
+ metadata.gz: 9e9e040d1c232767af0004c92c7b3a79277b7ac0e5a3c45509c46bf869a6a51ed7b5ad4273c68c03c86833482607a2b63da8c43f819f73e069ca6a3caf24ddd3
7
+ data.tar.gz: 973bbfd858e00e5f81a42f221c5d2a90c8c2fb3bec93e5b1d8f38ca58c42c47382aa4ed777852ec3bee51483ff211b5da9041a075e285b738107be5f8c08567d
data/.gitignore CHANGED
@@ -55,3 +55,6 @@ build-iPhoneSimulator/
55
55
 
56
56
  # Used by RuboCop. Remote config files pulled in from inherit_from directive.
57
57
  # .rubocop-https?--*
58
+
59
+ # IDE
60
+ .vscode/
data/Gemfile CHANGED
@@ -6,4 +6,15 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
6
6
  gemspec
7
7
 
8
8
  gem 'faraday', '~> 1.4.1'
9
- gem 'byebug'
9
+ gem 'faraday_middleware'
10
+ gem 'faraday-net_http'
11
+ gem 'concurrent-ruby', require: 'concurrent'
12
+
13
+ group :development do
14
+ gem 'ruby-debug-ide', group: :development
15
+ gem 'debase', '>= 0.2.5.beta2', group: :development
16
+ gem 'jaro_winkler', group: :development
17
+ gem 'solargraph', group: :development
18
+ end
19
+
20
+ gem 'simplecov', require: false, group: :test
data/Gemfile.lock CHANGED
@@ -1,24 +1,56 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- promoted-ruby-client (0.1.0)
4
+ promoted-ruby-client (0.1.5)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- byebug (11.1.3)
9
+ ast (2.4.2)
10
+ backport (1.2.0)
11
+ benchmark (0.1.1)
12
+ concurrent-ruby (1.1.9)
13
+ debase (0.2.5.beta2)
14
+ debase-ruby_core_source (>= 0.10.12)
15
+ debase-ruby_core_source (0.10.12)
10
16
  diff-lcs (1.4.4)
11
- faraday (1.4.1)
17
+ docile (1.4.0)
18
+ e2mmap (0.1.0)
19
+ faraday (1.4.3)
20
+ faraday-em_http (~> 1.0)
21
+ faraday-em_synchrony (~> 1.0)
12
22
  faraday-excon (~> 1.1)
13
23
  faraday-net_http (~> 1.0)
14
24
  faraday-net_http_persistent (~> 1.1)
15
25
  multipart-post (>= 1.2, < 3)
16
26
  ruby2_keywords (>= 0.0.4)
27
+ faraday-em_http (1.0.0)
28
+ faraday-em_synchrony (1.0.0)
17
29
  faraday-excon (1.1.0)
18
30
  faraday-net_http (1.0.1)
19
31
  faraday-net_http_persistent (1.1.0)
32
+ faraday_middleware (1.0.0)
33
+ faraday (~> 1.0)
34
+ jaro_winkler (1.5.4)
35
+ kramdown (2.3.1)
36
+ rexml
37
+ kramdown-parser-gfm (1.1.0)
38
+ kramdown (~> 2.0)
39
+ mini_portile2 (2.5.3)
20
40
  multipart-post (2.1.1)
41
+ nokogiri (1.11.7)
42
+ mini_portile2 (~> 2.5.0)
43
+ racc (~> 1.4)
44
+ parallel (1.20.1)
45
+ parser (3.0.1.1)
46
+ ast (~> 2.4.1)
47
+ racc (1.5.2)
48
+ rainbow (3.0.0)
21
49
  rake (10.5.0)
50
+ regexp_parser (2.1.1)
51
+ reverse_markdown (2.0.0)
52
+ nokogiri
53
+ rexml (3.2.5)
22
54
  rspec (3.10.0)
23
55
  rspec-core (~> 3.10.0)
24
56
  rspec-expectations (~> 3.10.0)
@@ -32,18 +64,64 @@ GEM
32
64
  diff-lcs (>= 1.2.0, < 2.0)
33
65
  rspec-support (~> 3.10.0)
34
66
  rspec-support (3.10.2)
67
+ rubocop (1.17.0)
68
+ parallel (~> 1.10)
69
+ parser (>= 3.0.0.0)
70
+ rainbow (>= 2.2.2, < 4.0)
71
+ regexp_parser (>= 1.8, < 3.0)
72
+ rexml
73
+ rubocop-ast (>= 1.7.0, < 2.0)
74
+ ruby-progressbar (~> 1.7)
75
+ unicode-display_width (>= 1.4.0, < 3.0)
76
+ rubocop-ast (1.7.0)
77
+ parser (>= 3.0.1.1)
78
+ ruby-debug-ide (0.7.2)
79
+ rake (>= 0.8.1)
80
+ ruby-progressbar (1.11.0)
35
81
  ruby2_keywords (0.0.4)
82
+ simplecov (0.21.2)
83
+ docile (~> 1.1)
84
+ simplecov-html (~> 0.11)
85
+ simplecov_json_formatter (~> 0.1)
86
+ simplecov-html (0.12.3)
87
+ simplecov_json_formatter (0.1.3)
88
+ solargraph (0.42.3)
89
+ backport (~> 1.2)
90
+ benchmark
91
+ bundler (>= 1.17.2)
92
+ diff-lcs (~> 1.4)
93
+ e2mmap
94
+ jaro_winkler (~> 1.5)
95
+ kramdown (~> 2.3)
96
+ kramdown-parser-gfm (~> 1.1)
97
+ parser (~> 3.0)
98
+ reverse_markdown (>= 1.0.5, < 3)
99
+ rubocop (>= 0.52)
100
+ thor (~> 1.0)
101
+ tilt (~> 2.0)
102
+ yard (~> 0.9, >= 0.9.24)
103
+ thor (1.1.0)
104
+ tilt (2.0.10)
105
+ unicode-display_width (2.0.0)
106
+ yard (0.9.26)
36
107
 
37
108
  PLATFORMS
38
109
  ruby
39
110
 
40
111
  DEPENDENCIES
41
112
  bundler (~> 1.17)
42
- byebug
113
+ concurrent-ruby
114
+ debase (>= 0.2.5.beta2)
43
115
  faraday (~> 1.4.1)
116
+ faraday-net_http
117
+ faraday_middleware
118
+ jaro_winkler
44
119
  promoted-ruby-client!
45
120
  rake (~> 10.0)
46
121
  rspec (~> 3.0)
122
+ ruby-debug-ide
123
+ simplecov
124
+ solargraph
47
125
 
48
126
  BUNDLED WITH
49
- 1.17.2
127
+ 1.17.3
data/README.md CHANGED
@@ -2,45 +2,166 @@
2
2
 
3
3
  Ruby client designed for calling Promoted's Delivery and Metrics API.
4
4
 
5
- This version of the library only supports preparing objects for logging. TODO - support Delivery API.
5
+ More information at [http://www.promoted.ai](http://www.promoted.ai)
6
6
 
7
- ## Expected pseudo-code flow for Metrics logging
7
+ ## Installation
8
+ ```gem 'promoted-ruby-client'```
8
9
 
9
- This example is for the integration where we do not want to modify the list of items to include `insertionId`. TODO - add this example too.
10
+ ## Local Development
11
+ 1. Clone or fork the repo on your local machine
12
+ 2. `cd promoted-ruby-client`
13
+ 3. `bundle`
14
+ 4. To test interactively: `irb -Ilib -rpromoted/ruby/client`
10
15
 
16
+ ## Dependencies
17
+
18
+ ### [Faraday](https://github.com/lostisland/faraday)
19
+ HTTP client for calling Promoted.
20
+ ### [Concurrent Ruby](https://github.com/ruby-concurrency/concurrent-ruby)
21
+ Provides a thread pool for making shadow traffic requests to Delivery API in the background on a subset of calls to ```prepare_for_logging```
22
+ ## Creating a Client
23
+ ```rb
24
+ client = Promoted::Ruby::Client::PromotedClient.new
11
25
  ```
12
- def get_items args
13
- items = retrieve_items((args))
14
- async_log_request(items)
15
- return items
16
- end
17
26
 
18
- # Done async
19
- def log_request items
20
- log_request = Promoted::Ruby::Client.prepare_for_logging(input)
21
- # Send JSON to Metrics API.
22
- log_to_promoted_event_api(log_request)
23
- end
27
+ This client will suffice for building log requests. To send actually send traffing to the API, some configuration is required.
28
+
29
+ ```rb
30
+ client = Promoted::Ruby::Client::PromotedClient.new({
31
+ :metrics_endpoint = "https://<get this from Promoted>",
32
+ :delivery_endpoint = "https://<get this from Promoted>",
33
+ :metrics_api_key = "<get this from Promoted>",
34
+ :delivery_api_key = "<get this from Promoted>"
35
+ })
24
36
  ```
25
37
 
26
- ## Naming details
38
+ ### Client Configuration Parameters
39
+ Name | Type | Description
40
+ ---- | ---- | -----------
41
+ ```:delivery_endpoint``` | String | POST URL for the Promoted Delivery API (get this from Promoted)
42
+ ```:metrics_endpoint``` | String | POST URL for the Promoted Metrics API (get this from Promoted)
43
+ ```:metrics_api_key``` | String | Used as the ```x-api-key``` header on Metrics API requests to Promoted (get this value from Promoted)
44
+ ```:delivery_api_key``` | String | Used as the ```x-api-key``` header on Delivery API requests to Promoted (get this value from Promoted)
45
+ ```:delivery_timeout_millis``` | Number | Timeout on the Delivery API call. Defaults to 3000.
46
+ ```:metrics_timeout_millis``` | Number | Timeout on the Metrics API call. Defaults to 3000.
47
+ ```:perform_checks``` | Boolean | Whether or not to perform detailed input validation, defaults to true but may be disabled for performance
48
+ ```:logger``` | Ruby Logger-compatible logger | Defaults to nil (no logging). Example: ```Logger.new(STDERR, :progname => 'promotedai')```
49
+ ```:shadow_traffic_delivery_percent``` | Number between 0 and 1 | % of ```prepare_for_logging``` traffic that gets directed to Delivery API as "shadow traffic". Defaults to 0 (no shadow traffic).
50
+ ```:default_request_headers``` | Hash | Additional headers to send on the request beyond ```x-api-key```. Defaults to {}
51
+ ```:default_only_log``` | Boolean | If true, the ```deliver``` method will not direct traffic to Delivery API but rather return a request suitable for logging. Defaults to false.
52
+ ```:should_apply_treatment_func``` | Proc | Called during delivery, accepts an experiment and returns a Boolean indicating whether the request should be considered part of the control group (false) or in the experiment (true). If nil, the default behavior of checking the experiement ```:arm``` is applied.
53
+
54
+ ## Data Types
27
55
 
28
- `fullInsertion` - for `prepare_for_logging`, this is the current page of `Insertion`s with full `Insertion.properties` filled with the item details. For v1 integrations, it is fine to not fill in the full properties.
56
+ ### UserInfo
57
+ Basic information about the request user.
58
+ Field Name | Type | Optional? | Description
59
+ ---------- | ---- | --------- | -----------
60
+ ```:user_id``` | String | Yes | The platform user id, cleared from Promoted logs.
61
+ ```:log_user_id``` | String | Yes | A different user id (presumably a UUID) disconnected from the platform user id, good for working with unauthenticated users or implementing right-to-be-forgotten.
29
62
 
30
- ## Pagination
63
+ ---
64
+ ### CohortMembership
65
+ Useful fields for experimentation during the delivery phase.
66
+ Field Name | Type | Optional? | Description
67
+ ---------- | ---- | --------- | -----------
68
+ ```:user_info``` | UserInfo | Yes | The user info structure.
69
+ ```:arm``` | String | Yes | 'CONTROL' or one of the TREATMENT values (see [constants.rb](https://github.com/promotedai/promoted-ruby-client/blob/main/lib/promoted/ruby/client/constants.rb)).
70
+ ---
71
+ ### Properties
72
+ Properties bag. Has the structure:
31
73
 
32
- The `prepare_for_logging` call assumes the client has already handled pagination. It needs a `Request.paging.from` to be passed in for the number of items deep that the page is.
74
+ ```rb
75
+ :struct => {
76
+ :product => {
77
+ "id": "product3",
78
+ "title": "Product 3",
79
+ "url": "www.mymarket.com/p/3"
80
+ # other key-value pairs...
81
+ }
82
+ }
83
+ ```
84
+ ---
85
+ ### Insertion
86
+ Content being served at a certain position.
87
+ Field Name | Type | Optional? | Description
88
+ ---------- | ---- | --------- | -----------
89
+ ```:user_info``` | UserInfo | Yes | The user info structure.
90
+ ```:insertion_id``` | String | Yes | Generated by the SDK (*do not set*)
91
+ ```:request_id``` | String | Yes | Generated by the SDK (*do not set*)
92
+ ```:content_id``` | String | No | Identifier for the content to be shown, must be set.
93
+ ```:properties``` | Properties | Yes | Any additional custom properties to associate. For v1 integrations, it is fine not to fill in all the properties.
33
94
 
34
- ## Example to run the client
95
+ ---
96
+ ### Paging
97
+ #### TODO
98
+ ---
99
+ ### Request
100
+ A request for content insertions.
101
+ Field Name | Type | Optional? | Description
102
+ ---------- | ---- | --------- | -----------
103
+ ```:user_info``` | UserInfo | Yes | The user info structure.
104
+ ```:request_id``` | String | Yes | Generated by the SDK (*do not set*)
105
+ ```:use_case``` | String | Yes | One of the use case values, i.e. 'FEED' (see [constants.rb](https://github.com/promotedai/promoted-ruby-client/blob/main/lib/promoted/ruby/client/constants.rb)).
106
+ ```:properties``` | Properties | Yes | Any additional custom properties to associate.
107
+ ```:paging``` | Paging | Yes | Paging parameters (see TODO)
108
+ ---
109
+ ### MetricsRequest
110
+ Input to ```prepare_for_logging```
111
+ Field Name | Type | Optional? | Description
112
+ ---------- | ---- | --------- | -----------
113
+ ```:request``` | Request | No | The underlying request for content.
114
+ ```:full_insertion``` | [] of Insertion | No | The proposed list of insertions.
115
+ ---
35
116
 
36
- 1. Clone the repo on your local machine
37
- 2. `cd promoted-ruby-client`
38
- 3. `bundle`
39
- 4. `irb -Ilib -rpromoted/ruby/client`
117
+ ### DeliveryRequest
118
+ Input to ```deliver```
119
+ Field Name | Type | Optional? | Description
120
+ ---------- | ---- | --------- | -----------
121
+ ```:experiment``` | CohortMembership | Yes | A cohort to evaluation in experimentation.
122
+ ```:request``` | Request | No | The underlying request for content.
123
+ ```:full_insertion``` | [] of Insertion | No | The proposed list of insertions with all metadata, will be compacted before forwarding to Promoted.
124
+ ```:only_log``` | Boolean | Yes | Defaults to false. Set to true to override whether Delivery API is called for this request.
125
+ ---
40
126
 
41
- A console will launch with the library loaded. Here is example code to use.
127
+ ### LogRequest
128
+
129
+ Output of ```prepare_for_logging``` as well as an ouput of an SDK call to ```deliver```, input to ```send_log_request``` to log to Promoted
130
+ Field Name | Type | Optional? | Description
131
+ ---------- | ---- | --------- | -----------
132
+ ```:request``` | Request | No | The underlying request for content to log.
133
+ ```:insertion``` | [] of Insertion | No | The insertions, which are either the original request insertions or the insertions resulting from a call to ```deliver``` if such call occurred.
134
+ ---
135
+
136
+ ### ClientResponse
137
+ Output of ```deliver```, includes the insertions as well as a suitable ```LogRequest``` for forwarding to Metrics API.
138
+ Field Name | Type | Optional? | Description
139
+ ---------- | ---- | --------- | -----------
140
+ ```:insertion``` | [] of Insertion | No | The insertions, which are from Delivery API (when ```deliver``` was called, i.e. we weren't either only-log or part of an experiment) or the input insertions (when the other conditions don't hold).
141
+ ```:log_request``` | LogRequest | Yes | A message suitable for logging to Metrics API via ```send_log_request```. If the call to ```deliver``` was made (i.e. the request was not part of the CONTROL arm of an experiment or marked to only log), ```:log_request``` will not be set, as you can assume logging was performed on the server-side by Promoted.
142
+ ---
143
+
144
+ ### PromotedClient
145
+ Method | Input | Output | Description
146
+ ------ | ----- | ------ | -----------
147
+ ```prepare_for_logging``` | MetricsRequest | LogRequest | Builds a request suitable for logging locally and/or to Promoted, either via a subsequent call to ```send_log_request``` in the SDK client or by using this structure to make the call yourself. Optionally, based on client configuration may send a random subset of requests to Delivery API as shadow traffic for integration purposes.
148
+ ```send_log_request``` | LogRequest | n/a | Forwards a LogRequest to Promoted using an HTTP client.
149
+ ```deliver``` | DeliveryRequest | ClientResponse | Makes a request (subject to experimentation) to Delivery API for insertions, which are then returned along with a LogRequest.
150
+ ```close``` | n/a | n/a | Closes down the client at shutdown, currently this is just to drain the thread pool that handles shadow traffic.
151
+ ---
152
+
153
+ ## Metrics API
154
+ ### Pagination
155
+
156
+ The `prepare_for_logging` call assumes the client has already handled pagination. It needs a `Request.paging.offset` to be passed in for the number of items deep that the page is.
157
+ TODO: Needs more details.
158
+
159
+ ### Expected flow for Metrics logging
160
+
161
+ ```rb
162
+ # Retrieve a list of content (i.e. products)
163
+ # products = fetch_my_marketplace_products()
42
164
 
43
- ```
44
165
  products = [
45
166
  {
46
167
  id: "123",
@@ -62,136 +183,91 @@ products = [
62
183
  }
63
184
  ]
64
185
 
65
- # Converts the Products to a list of Insertions.
66
- def to_insertions products
67
- @to_insertions = []
68
- products.each_with_index do |product, index|
69
- @to_insertions << {
70
- content_id: product[:id],
71
- properties: {
72
- struct: {
73
- product: product.reject { |k, v| [:id].include? k }
74
- }
186
+ # Transform them into an [] of Insertions.
187
+ insertions = products.map { |product|
188
+ {
189
+ :content_id => product[:id],
190
+ :properties => {
191
+ :struct => {
192
+ :type => product[:type],
193
+ :name => product[:name]
194
+ # etc
75
195
  }
76
196
  }
77
- end
78
- @to_insertions
79
- end
197
+ }
198
+ }
80
199
 
81
- request_input = {
82
- request: {
83
- user_info: { user_id: "912", log_user_id: "912191"},
84
- use_case: "FEED",
85
- paging: {
86
- from: 10,
87
- size: 5
200
+ # Form a MetricsRequest
201
+ metrics_request = {
202
+ :request => {
203
+ :user_info => { :user_id => "912", :log_user_id => "912191"},
204
+ :use_case => "FEED",
205
+ :paging => {
206
+ :offset => 0,
207
+ :size => 5
88
208
  },
89
- properties: {
90
- struct: {
91
- active: true
209
+ :properties => {
210
+ :struct => {
211
+ :active => true
92
212
  }
93
213
  }
94
214
  },
95
- fullInsertion: to_insertions(products)
215
+ :full_insertion => insertions
96
216
  }
97
217
 
98
- log_request = Promoted::Ruby::Client.prepare_for_logging(request_input)
99
- log_request.to_json
100
- ```
218
+ # OPTIONAL: You can pass a custom function to "compact" insertions before metrics logging.
219
+ # Note that the PromotedClient has a class method helper, copy_and_remove_properties, that does just this.
220
+ to_compact_metrics_insertion_func = Proc.new do |insertion|
221
+ insertion.delete(:properties)
222
+ insertion
223
+ end
224
+ # metrics_request[:to_compact_metrics_insertion_func] = to_compact_metrics_insertion
101
225
 
102
- `log_request.to_json` returns a result that looks like the following
103
- ```
104
- => "{\"user_info\":{\"user_id\":\"912\",\"log_user_id\":\"912191\"},\"timing\":{\"client_log_timestamp\":1623306198},\"request\":[{\"user_info\":{\"user_id\":\"912\",\"log_user_id\":\"912191\"},\"use_case\":\"FEED\",\"paging\":{\"from\":10,\"size\":10},\"properties\":{\"struct\":{\"active\":true}}}],\"insertion\":[{\"content_id\":\"123\",\"properties\":{\"struct\":{\"product\":{\"type\":\"SHOE\",\"name\":\"Blue shoe\",\"total_sales\":1000}}},\"user_info\":{\"user_id\":\"912\",\"log_user_id\":\"912191\"},\"timing\":{\"client_log_timestamp\":1623306198},\"insertion_id\":\"a87e1b57-a574-424f-8af6-10e0250aa7ab\",\"request_id\":\"54ff4884-2192-4180-8c72-a805a436980f\",\"position\":10},{\"content_id\":\"124\",\"properties\":{\"struct\":{\"product\":{\"type\":\"SHIRT\",\"name\":\"Green shirt\",\"total_sales\":800}}},\"user_info\":{\"user_id\":\"912\",\"log_user_id\":\"912191\"},\"timing\":{\"client_log_timestamp\":1623306198},\"insertion_id\":\"4495f72a-8101-4cb8-94ce-4db76839b8b6\",\"request_id\":\"54ff4884-2192-4180-8c72-a805a436980f\",\"position\":11},{\"content_id\":\"125\",\"properties\":{\"struct\":{\"product\":{\"type\":\"DRESS\",\"name\":\"Red dress\",\"total_sales\":1200}}},\"user_info\":{\"user_id\":\"912\",\"log_user_id\":\"912191\"},\"timing\":{\"client_log_timestamp\":1623306198},\"insertion_id\":\"d1e4f3f6-1783-4059-8fab-fdf2ba343cdf\",\"request_id\":\"54ff4884-2192-4180-8c72-a805a436980f\",\"position\":12}]}"
105
- ```
226
+ # Create a client
227
+ client = Promoted::Ruby::Client::PromotedClient.new
106
228
 
107
- ## Other input syntaxes
229
+ # Build a log request
230
+ log_request = client.prepare_for_logging(metrics_request)
108
231
 
109
- The client should also work if Hash rocket too.
232
+ # Log (assuming you have configured your client with a :metrics_endpoint)
233
+ client.send_log_request(log_request)
110
234
  ```
111
- products = [
112
- {
113
- "id"=>"123",
114
- "type"=>"SHOE",
115
- "name"=>"Blue shoe",
116
- "totalSales"=>1000
117
- },
118
- {
119
- "id"=>"124",
120
- "type"=>"SHIRT",
121
- "name"=>"Green shirt",
122
- "totalSales"=>800
123
- },
124
- {
125
- "id"=>"125",
126
- "type"=>"DRESS",
127
- "name"=>"Red dress",
128
- "totalSales"=>1200
129
- }
130
- ]
131
235
 
132
- input = {
133
- "request"=>{
134
- "user_info"=>{"user_id"=> "912", "log_user_id"=> "912191"},
135
- "use_case"=>"FEED",
136
- "properties"=>{
137
- "struct"=>{
138
- "active"=>true
236
+ ## Delivery API
237
+
238
+ ### Expected flow for Delivery
239
+
240
+ ```rb
241
+ # (continuing from the above example for Metrics)
242
+
243
+ # Form a DeliveryRequest
244
+ delivery_request = {
245
+ :request => {
246
+ :user_info => { :user_id => "912", :log_user_id => "912191"},
247
+ :use_case => "FEED",
248
+ :paging => {
249
+ :offset => 0,
250
+ :size => 5
251
+ },
252
+ :properties => {
253
+ :struct => {
254
+ :active => true
139
255
  }
140
256
  }
141
257
  },
142
- "fullInsertion"=>to_insertions(products)
258
+ :full_insertion => insertions,
259
+ :only_log => false
143
260
  }
144
- ```
145
261
 
146
- Or inlined full request.
262
+ # Request insertions from Delivery API
263
+ client_response = client.deliver(delivery_request)
264
+
265
+ # Use the resulting insertions
266
+ client_response[:insertion]
267
+
268
+ # Log if a log request was provided (if not, deliver was called successfully
269
+ # and Promoted logged on the server-side).)
270
+ client.send_log_request(client_response[:log_request]) if client_response[:log_request]
147
271
  ```
148
- input = {
149
- "request"=>{
150
- "user_info"=>{"user_id"=> "912", "log_user_id"=> "912191"},
151
- "use_case"=>"FEED",
152
- "properties"=>{
153
- "struct"=>{
154
- "active"=>true
155
- }
156
- }
157
- },
158
- "fullInsertion"=>[
159
- {
160
- "contentId"=>"123",
161
- "properties"=>{
162
- "struct"=>{
163
- "product"=>{
164
- "type"=>"SHOE",
165
- "name"=>"Blue shoe",
166
- "totalSales"=>1000
167
- }
168
- }
169
- }
170
- },
171
- {
172
- "contentId"=>"124",
173
- "properties"=>{
174
- "struct"=>{
175
- "product"=>{
176
- "type"=>"SHIRT",
177
- "name"=>"Green shirt",
178
- "totalSales"=>800
179
- }
180
- }
181
- }
182
- },
183
- {
184
- "contentId"=>"125",
185
- "properties"=>{
186
- "struct"=>{
187
- "product"=>{
188
- "type"=>"DRESS",
189
- "name"=>"Red dress",
190
- "totalSales"=>1200
191
- }
192
- }
193
- }
194
- }
195
- ]
196
- }
197
- ```
272
+
273
+ ### TODO Experimentation example