diff --git a/lib/snowplow-tracker/tracker.rb b/lib/snowplow-tracker/tracker.rb index 585fef0..02e6ba1 100644 --- a/lib/snowplow-tracker/tracker.rb +++ b/lib/snowplow-tracker/tracker.rb @@ -26,7 +26,7 @@ class Tracker @@required_transaction_keys = Set.new(%w(order_id total_value)) @@recognised_transaction_keys = Set.new(%w(order_id total_value affiliation tax_value shipping city state country currency)) - + @@Transaction = lambda { |x| return false unless x.class == Hash transaction_keys = Set.new(x.keys) @@ -63,6 +63,11 @@ class Tracker 'No address associated with name', 'No address associated with hostname'] + @@base_schema_path = "iglu:com.snowplowanalytics.snowplow" + @@schema_tag = "jsonschema" + @@context_schema = "#{@@base_schema_path}/contexts/#{@@schema_tag}/1-0-0" + @@unstruct_event_schema = "#{@@base_schema_path}/unstruct_event/#{@@schema_tag}/1-0-0" + Contract String, Maybe[String], Maybe[String], Maybe[String], Bool => Tracker def initialize(endpoint, namespace=nil, app_id=nil, context_vendor=nil, encode_base64=@@default_encode_base64) @collector_uri = as_collector_uri(endpoint) @@ -125,7 +130,7 @@ def http_get(payload) # Setter methods # Specify the platform - # + # Contract String => String def set_platform(value) if @@supported_platforms.include?(value) @@ -150,7 +155,7 @@ def set_screen_resolution(width, height) end # Set the dimensions of the current viewport - # + # Contract Num, Num => String def set_viewport(width, height) @standard_nv_pairs['vp'] = "#{width}x#{height}" @@ -291,23 +296,36 @@ def track_struct_event(category, action, label=nil, property=nil, value=nil, con # Contract String, Maybe[String], Maybe[Hash], Maybe[Num] => [Bool, Num] def track_screen_view(name, id=nil, context=nil, tstamp=nil) - self.track_unstruct_event('screen_view', {'name' => name, 'id' => id}, @@default_vendor, context, tstamp) + screen_view_properties = {'name' => name, 'id' => id} + screen_view_schema = "#{@@base_schema_path}/screen_view/#{@@schema_tag}/1-0-0" + event_json = {schema: screen_view_schema, data: screen_view_properties} + + self.track_unstruct_event(event_json, context, tstamp) end # Track an unstructured event # - Contract String, Hash, Maybe[String], Maybe[Hash], Maybe[Num] => [Bool, Num] - def track_unstruct_event(event_name, dict, event_vendor=nil, context=nil, tstamp=nil) + Contract Hash, Maybe[Hash], Maybe[Num] => [Bool, Num] + def track_unstruct_event(event_json, context=nil, tstamp=nil) pb = Payload.new pb.add('e', 'ue') - pb.add('ue_na', event_name) - pb.add_json(dict, @config['encode_base64'], 'ue_px', 'ue_pr') - pb.add('evn', event_vendor) - pb.add_json(context, @config['encode_base64'], 'cx', 'co') + + envelope = { + schema: @@unstruct_event_schema, + data: event_json + } + pb.add_json(envelope, @config['encode_base64'], 'ue_px', 'ue_pr') + if tstamp.nil? tstamp = get_timestamp end pb.add('dtm', tstamp) + + if context + context_envelope = {schema: @@context_schema, data: context} + pb.add_json(context_envelope, @config['encode_base64'], 'cx', 'co') + end + track(pb) end diff --git a/spec/integration/integration_spec.rb b/spec/integration/integration_spec.rb index d5020ac..4a4d34b 100644 --- a/spec/integration/integration_spec.rb +++ b/spec/integration/integration_spec.rb @@ -144,27 +144,26 @@ def get_last_querystring(n=1) param_hash = CGI.parse(t.get_last_querystring(1)) expected_fields = { - 'e' => 'se', - 'se_ca' => 'Ecomm', - 'se_ac' => 'add-to-basket', - 'se_pr' => 'hd', + 'e' => 'se', + 'se_ca' => 'Ecomm', + 'se_ac' => 'add-to-basket', + 'se_pr' => 'hd', 'se_va' => '13.99' } for pair in expected_fields expect(param_hash[pair[0]][0]).to eq(pair[1]) - end + end end it 'tracks an unstructured event (no base64)' do t = SnowplowTracker::Tracker.new('localhost', nil, nil, nil, false) - t.track_unstruct_event('viewed_product', {'product_id' => 'ASO01043', 'price' => 49.95}, 'com.example') + t.track_unstruct_event({'event_name' => 'viewed_product', 'event_vendor' => 'com.example', 'product_id' => 'ASO01043', 'price' => 49.95}) param_hash = CGI.parse(t.get_last_querystring(1)) expected_fields = { - 'e' => 'ue', - 'ue_pr' => "{\"product_id\":\"ASO01043\",\"price\":49.95}", - 'evn' => 'com.example' + 'e' => 'ue', + 'ue_pr' => "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"event_name\":\"viewed_product\",\"event_vendor\":\"com.example\",\"product_id\":\"ASO01043\",\"price\":49.95}}", } for pair in expected_fields expect(param_hash[pair[0]][0]).to eq(pair[1]) @@ -174,13 +173,12 @@ def get_last_querystring(n=1) it 'tracks an unstructured event (base64)' do t = SnowplowTracker::Tracker.new('localhost') - t.track_unstruct_event('viewed_product', {'product_id' => 'ASO01043', 'price' => 49.95}, 'com.example') + t.track_unstruct_event({'event_name' => 'viewed_product', 'event_vendor' => 'com.example', 'product_id' => 'ASO01043', 'price' => 49.95}) param_hash = CGI.parse(t.get_last_querystring(1)) expected_fields = { - 'e' => 'ue', - 'ue_px' => 'eyJwcm9kdWN0X2lkIjoiQVNPMDEwNDMiLCJwcmljZSI6NDkuOTV9', - 'evn' => 'com.example' + 'e' => 'ue', + 'ue_px' => 'eyJzY2hlbWEiOiJpZ2x1OmNvbS5zbm93cGxvd2FuYWx5dGljcy5zbm93cGxvdy91bnN0cnVjdF9ldmVudC9qc29uc2NoZW1hLzEtMC0wIiwiZGF0YSI6eyJldmVudF9uYW1lIjoidmlld2VkX3Byb2R1Y3QiLCJldmVudF92ZW5kb3IiOiJjb20uZXhhbXBsZSIsInByb2R1Y3RfaWQiOiJBU08wMTA0MyIsInByaWNlIjo0OS45NX19', } for pair in expected_fields expect(param_hash[pair[0]][0]).to eq(pair[1]) @@ -194,9 +192,8 @@ def get_last_querystring(n=1) param_hash = CGI.parse(t.get_last_querystring(1)) expected_fields = { - 'e' => 'ue', - 'ue_pr' => "{\"name\":\"Game HUD 2\",\"id\":\"e89a34b2f\"}", - 'evn' => 'com.snowplowanalytics' + 'e' => 'ue', + 'ue_pr' => "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"iglu:com.snowplowanalytics.snowplow/screen_view/jsonschema/1-0-0\",\"data\":{\"name\":\"Game HUD 2\",\"id\":\"e89a34b2f\"}}}", } for pair in expected_fields expect(param_hash[pair[0]][0]).to eq(pair[1])