promoted-ruby-client 0.1.0 → 0.1.5

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.
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