/
actions_manager.coffee
115 lines (90 loc) · 3.88 KB
/
actions_manager.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
define [
'settings'
'reporter'
'runnable'
'validator'
'analytics_url'
], (Settings, Reporter, Runnable, Validator, AnalyticsUrl) ->
class ActionsManager
ActionsManager::[key] = method for key, method of Runnable
constructor: (@session, @plugins_manager) ->
@reporter = new Reporter()
@pageview_timeout = null
@reported_line_items = 0
@_setPageViewTimeout() if Settings.send_auto_pageview
_setPageViewTimeout: ->
@pageview_timeout = setTimeout (=> @_commands.site.sendPageView.call(@)),
Settings.auto_pageview_timeout
_commands:
yogurt:
productClick: (data, redirect_callback, redirect_url, url_mode = { type: 'default' }) ->
clearTimeout @pageview_timeout
@_reportAction 'yogurt', 'productClick', data, () =>
if redirect_callback and redirect_url
redirect_url = new AnalyticsUrl(redirect_url).format_params(url_mode, @session.analytics_session, @session.metadata)
try redirect_callback(redirect_url) catch then Settings.redirectTo(redirect_url)
ecommerce:
addOrder: (data, callback) ->
clearTimeout @pageview_timeout
try
new Validator(data, 'addOrder').present('order_id')
catch e
if e.name == 'ValidationError'
return console?.error? "#{Settings.flavor}Analytics | #{e.message}"
else
throw e
@_reportAction 'ecommerce', 'addOrder', data, -> callback() if callback
# Do not display OrderStash widget for users that haven't opted in for full experience
@plugins_manager.notify('order', data) if @session.cookie_policy == 'full'
addItem: (data, callback) ->
clearTimeout @pageview_timeout
try
data = new Validator(data, 'addItem').present('order_id', 'product_id').data
catch e
if e.name == 'ValidationError'
return console?.error? "#{Settings.flavor}Analytics | #{e.message}"
else
throw e
data.rpos = @reported_line_items++ # line item reported position
@_reportAction 'ecommerce', 'addItem', data, -> callback() if callback
site:
sendPageView: ->
@_reportAction 'site', 'sendPageView'
_reportAction: (category, type, data, cb) ->
url = Settings.url.beacon(@session.analytics_session)
payload = @_buildBeaconPayload(category, type, data)
## TODO: HANDLE ERROR ON REJECT
@reporter.sendBeacon(url, payload).then => cb and cb()
# TODO: implement multiple actions per beacon maybe??
_buildBeaconPayload: (category, type, data = '{}') ->
data = JSON.stringify data if typeof data != 'string'
payload = {}
params = Settings.params
payload[params.url] = Settings.url.current
payload[params.referrer] = Settings.url.referrer
payload[params.shop_code] = @session.shop_code
payload[params.metadata] = @_buildMetadata(JSON.parse(data))
payload[params.cookie_policy] = @session.cookie_policy
payload[params.actions] = [{
category: category
type: type
data: data
}]
payload
_buildMetadata: (data) ->
# When using 3rd-party cookies, metadata will be undefined
# In this case, the server will fallback to using the meta cookie
return '' unless @session.metadata
sbm = data.sbm
sbm_tag = data.sbm_tag
# Return metadata as is if sbm is not present
return @session.metadata unless sbm || sbm_tag
# Clone
meta = JSON.parse(JSON.stringify(@session.metadata))
tags = if meta.tags then meta.tags.split(',') else []
if sbm || sbm_tag
tags.push('sbm') if sbm && !('sbm' in tags)
tags.push(sbm_tag) if sbm_tag && !(sbm_tag in tags)
meta.tags = tags.join() if tags
meta
return ActionsManager