Advertisement
Guest User

Roku GoogleAnalytics4 XML and BRS

a guest
May 13th, 2022
540
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.73 KB | None | 0 0
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- GoogleAnalytics4.xml -->
  3. <!-- ************************************ -->
  4. <!-- Copyright 2021-2021 FutureSoft, Inc. -->
  5. <!-- ************************************ -->
  6.  
  7. <component name="GoogleAnalytics4" extends="Task">
  8.  
  9. <interface>
  10.  
  11. <field id="RokuAnalyticsPlayerTitle" type="string" />
  12. <field id="RokuAnalyticsPlayerState" type="string" />
  13. <field id="RokuAnalyticsEventCategory" type="string" />
  14. <field id="RokuAnalyticsEventValue" type="string" />
  15. <field id="RokuAnalyticsLoginUserID" type="string" />
  16.  
  17. <!-- Public -->
  18. <function name="initialize" />
  19. <function name="setConfig" />
  20. <function name="setOptions" />
  21. <function name="start" />
  22. <function name="logEvent" />
  23. <function name="logScreenView" />
  24. <function name="setUserProperties" />
  25. <function name="setCurrentScreen" />
  26. <function name="setUserId" />
  27. <function name="resetAnalyticsData" />
  28.  
  29. <field id="httpMethod" type="string" />
  30. <field id="httpUrl" type="string" />
  31.  
  32. </interface>
  33.  
  34. <script type="text/brightscript" uri="GoogleAnalytics4.brs" />
  35.  
  36. </component>
  37.  
  38. <!-- ************************************
  39. Usage
  40.  
  41. Bunch of functions used by many screens:
  42. <script type="text/brightscript" uri="pkg:/components/compUtils.brs" />
  43.  
  44. Containing:
  45. Function utilPostAnalytics(passedTitle, passedState, passedCategory, passedUserID, passedEvtCnt)
  46. ?"utilPostAnalytics()", passedTitle, passedState, passedCategory, passedUserID
  47. m.GoogleAnalytics4Obj = createObject("roSGNode", "GoogleAnalytics4")
  48. m.GoogleAnalytics4Obj.setField("RokuAnalyticsPlayerTitle", passedTitle)
  49. m.GoogleAnalytics4Obj.setField("RokuAnalyticsPlayerState", passedState)
  50. m.GoogleAnalytics4Obj.setField("RokuAnalyticsEventValue", passedEvtCnt)
  51. m.GoogleAnalytics4Obj.setField("RokuAnalyticsEventCategory", passedCategory)
  52. m.GoogleAnalytics4Obj.setField("RokuAnalyticsLoginUserID", passedUserID)
  53. 'STOP
  54. m.GoogleAnalytics4Obj.control = "RUN"
  55. End Function
  56.  
  57. Examples:
  58.  
  59. sTmpClientID = WhateverCustomerIDYouAssign
  60. sTmpEventCnt = 1
  61. utilPostAnalytics(m.videoPlayer.content.Title, "start", "media player", sTmpClientID, sTmpEventCnt)
  62.  
  63. sTmpClientID = WhateverCustomerIDYouAssign
  64. sTmpEventCnt = m.sixtySecTimePassed / 60
  65. utilPostAnalytics(m.videoPlayer.content.Title, "playing", "media player", sTmpClientID, sTmpEventCnt)
  66.  
  67. sTmpClientID = WhateverCustomerIDYouAssign
  68. sTmpEventCnt = m.sixtySecTimePassed / 60
  69. utilPostAnalytics(m.audioPlayer.content.Title, "finished", "media player", sTmpClientID, sTmpEventCnt)
  70.  
  71. ************************************ -->
  72.  
  73.  
  74. <!-- ************************************
  75. examples debug output sent to Google...
  76. [GoogleAnalytics4] https://analytics.google.com/g/collect
  77. ?sid=1611237152&_p=1490261140&_s=1&seg=1&ec=media_player&sr=1280x720&uid=1%3A999999999999%3Aweb%3A7777777777777777777777
  78. &v=2&en=start&sct=279&cid=420d8a2a-d34b-5dd6-9d2f-4305921dacb3&upn.first_open_time=1610744400000
  79. &dl=https%3A%2F%2FBIGQUERY-DBNAME.firebaseio.com&av=4.0.9&custom=unset&ea=start&up.userPropA=USERPROPA
  80. &tid=G-ABCDEFGHIJKLMNOP&ul=en_us&cd=media_player&up.id=1%3A999999999999%3Aweb%3A7777777777777777777777
  81. &el=Live%20Stream%20-%20Auf%20Deutsch&an=RokuApp
  82.  
  83. POST https://analytics.google.com/g/collect
  84. ?_p=406324644&_s=1&seg=1&sr=1280x720&uid=1%3A999999999999%3Aweb%3A7777777777777777777777&v=2&en=start
  85. &cid=420d8a2a-d34b-5dd6-9d2f-4305921dacb3&upn.first_open_time=1610744400000&dl=https%3A%2F%2FBIGQUERY-DBNAME.firebaseio.com
  86. &av=4.0.9&up.userPropA=SET%20USER%20PROPERTIES%20HERE&tid=G-ABCDEFGHIJKLMNOABCDEFGHIJKLMNOP&ul=en_us
  87. &up.id=1%3A999999999999%3Aweb%3A7777777777777777777777&EXAMPLEPROPERTY=HERE%20YOU%20CAN%20PUT%20ANY%20CUSTOM%20ARG...
  88. &an=RokuApp
  89. ************************************ -->
  90.  
  91.  
  92.  
  93.  
  94. ' GoogleAnalytics4.brs
  95. ' ************************************
  96. ' Copyright 2021-2021 FutureSoft, Inc.
  97. ' ************************************
  98.  
  99. ' see https://github.com/vixtech/roku-google-analytics-4
  100. ' Implementation based on https://gist.github.com/IjzerenHein/df3f65093038dd70ad871f926be6f45e
  101.  
  102. sub Init()
  103. ?"[GoogleAnalytics4] Init()"
  104.  
  105. initAnalytics()
  106.  
  107. end sub
  108.  
  109. sub initAnalytics()
  110.  
  111. m.endpoint = "https://analytics.google.com/g/collect"
  112. m.config = invalid
  113. m.options = invalid
  114. m.codedUserProperties = {}
  115. m.userId = invalid
  116. m.screenName = invalid
  117. m.lastEventTime = invalid
  118. m.sessionHitsCount = 0
  119. 'm.top.functionName = "startTask"
  120. m.top.functionName = "doLogAnalyticsEvent"
  121. m.userEngagementIntervalSeconds = 30
  122. 'STOP
  123. 'Not used
  124. 'm.timer = CreateObject("roSgnode", "Timer")
  125. 'm.timer.observeField("fire","logUserEngagement")
  126. 'm.timer.duration = m.userEngagementIntervalSeconds
  127. 'm.timer.repeat = true
  128.  
  129. myMeasurementId = "G-ABCDEFGHIJKLMNOP"
  130. myUserId = "1:999999999999:web:7777777777777777777777" 'NOT NEEDED?
  131. initObj = {
  132. appName: "RokuAppName"
  133. measurementId: myMeasurementId
  134. docLocation: "https://BIGQUERY-DBNAME.firebaseio.com"
  135. 'customArgs: { "custom": "unset" }
  136. userId: myUserId
  137. 'userProperties: { "userPropA": "USERPROPA" }
  138. }
  139.  
  140. initialize(initObj)
  141.  
  142. customArgs = m.options.customArgs
  143.  
  144. gaSessionId = getGaSessionId()
  145. gaSessionNumber = getGaSessionNumber()
  146.  
  147. customArgs["sid"] = gaSessionId
  148. customArgs["sct"] = gaSessionNumber
  149.  
  150. options = m.options
  151. options.customArgs = customArgs
  152.  
  153. m.options = options
  154.  
  155. m.pendingSessionStart = true
  156. m.pendingFirstVisit = false
  157.  
  158. if isFirstOpen()
  159. m.pendingFirstVisit = true
  160. end if
  161.  
  162. end sub
  163.  
  164. function initialize(params as object)
  165. ' Analytics stuff
  166. appInfo = CreateObject("roAppInfo")
  167. deviceInfo = CreateObject("roDeviceInfo")
  168. displaySize = deviceInfo.GetDisplaySize()
  169. screenRes = invalid
  170.  
  171. if displaySize <> invalid and displaySize.w <> invalid and displaySize.h <> invalid
  172. screenRes = Str(displaySize.w).Trim() + "x" + Str(displaySize.h).Trim()
  173. end if
  174. 'STOP
  175. setConfig({
  176. measurementId: params.measurementId
  177. })
  178.  
  179. setOptions({
  180. appName: params.appName
  181. appVersion: appInfo.GetVersion()
  182. screenRes: screenRes
  183. clientId: deviceInfo.GetChannelClientId()
  184. docLocation: params.docLocation
  185. userLanguage: deviceInfo.GetCurrentLocale()
  186. customArgs: params.customArgs
  187. isFirstOpen: params.isFirstOpen
  188. })
  189.  
  190. if params.userId <> invalid
  191. setUserId(params.userId)
  192. end if
  193.  
  194. if params.userProperties <> invalid
  195. setUserProperties(params.userProperties)
  196. end if
  197. end function
  198.  
  199. function setConfig(config as object)
  200. ' Config Properties
  201. ' - measurementId
  202. m.config = config
  203. end function
  204.  
  205. sub setOptions(options as object)
  206. ' Options Properties
  207. ' - clientId
  208. ' - docTitle
  209. ' - docLocation
  210. ' - screenRes
  211. ' - appName
  212. ' - appVersion
  213. ' - userLanguage
  214. ' - origin
  215. ' - customArgs
  216.  
  217. if options.customArgs = invalid
  218. options.customArgs = {}
  219. end if
  220.  
  221. m.options = options
  222. end sub
  223.  
  224. sub startTask()
  225. ' The only async method is "sendHttpRequest"
  226. ? "ANALYTICS: The only async method is sendHttpRequest"
  227. 'STOP
  228. end sub
  229.  
  230. sub doLogAnalyticsEvent()
  231. ?m.top
  232. 'STOP
  233. logEvent(m.top.RokuAnalyticsEventCategory, {})
  234.  
  235. end sub
  236.  
  237. sub OnChangeAnalyticsDoEvent()
  238. ?m.top
  239. 'STOP
  240. 'logEvent("page_view", {})
  241.  
  242. logEvent(m.top.RokuAnalyticsPlayerState, {})
  243.  
  244. end sub
  245.  
  246. function start()
  247. customArgs = m.options.customArgs
  248. 'STOP
  249. gaSessionId = getGaSessionId()
  250. gaSessionNumber = getGaSessionNumber()
  251.  
  252. customArgs["sid"] = gaSessionId
  253. customArgs["sct"] = gaSessionNumber
  254.  
  255. options = m.options
  256. options.customArgs = customArgs
  257.  
  258. m.options = options
  259.  
  260. m.pendingSessionStart = true
  261. m.pendingFirstVisit = false
  262.  
  263. if isFirstOpen()
  264. m.pendingFirstVisit = true
  265. end if
  266.  
  267. logEvent("page_view", {})
  268.  
  269. 'm.timer.control = "start"
  270. end function
  271.  
  272. function getGaSessionId() as integer
  273. return CreateObject("roDateTime").AsSeconds()
  274. end function
  275.  
  276. function getGaSessionNumber() as integer
  277. registry = getRegistry()
  278.  
  279. lastSessionNumber = registry.read("lastSessionNumber")
  280.  
  281. newSessionNumber = 1
  282.  
  283. if lastSessionNumber <> invalid and lastSessionNumber <> ""
  284. newSessionNumber = lastSessionNumber.toInt() + 1
  285. end if
  286.  
  287. registry.write("lastSessionNumber", newSessionNumber.toStr())
  288.  
  289. return newSessionNumber
  290. end function
  291.  
  292. function getFirstOpenTimeSeconds() as integer
  293. registry = getRegistry()
  294.  
  295. firstOpenTimeSeconds = registry.read("firstOpenTimeSeconds")
  296.  
  297. if firstOpenTimeSeconds <> "" and firstOpenTimeSeconds <> invalid
  298. return firstOpenTimeSeconds.toInt()
  299. end if
  300.  
  301. firstOpenTimeSeconds = CreateObject("roDateTime").AsSeconds()
  302.  
  303. registry.write("firstOpenTimeSeconds", firstOpenTimeSeconds.toStr())
  304.  
  305. return firstOpenTimeSeconds
  306. end function
  307.  
  308. function isFirstOpen() as boolean
  309. if m.options.isFirstOpen <> invalid
  310. return m.options.isFirstOpen
  311. end if
  312.  
  313. registry = getRegistry()
  314.  
  315. if registry.exists("firstOpenMark")
  316. return false
  317. else
  318. registry.write("firstOpenMark", "ok")
  319. return true
  320. end if
  321. end function
  322.  
  323. function getRegistry() as object
  324. return CreateObject("roRegistrySection", "googleanalytics")
  325. end function
  326.  
  327. sub logUserEngagement()
  328. logEvent("user_engagement", {
  329. _et: m.userEngagementIntervalSeconds * 1000
  330. })
  331.  
  332. logEvent("app_time", {
  333. time_difference: m.userEngagementIntervalSeconds * 1000
  334. })
  335. end sub
  336.  
  337. function send(codedEvent as Object)
  338.  
  339. nowTime = CreateObject("roDateTime")
  340.  
  341. queryArgs = {}
  342.  
  343. if m.options.customArgs <> invalid
  344. for each key in m.options.customArgs
  345. queryArgs[key] = m.options.customArgs[key]
  346. end for
  347. end if
  348.  
  349. m.sessionHitsCount = m.sessionHitsCount + 1
  350.  
  351. queryArgs.v = 2
  352. queryArgs.tid = m.config.measurementId
  353. queryArgs.cid = m.options.clientId
  354. queryArgs._p = Rnd(CreateObject("roDateTime").AsSeconds())
  355. queryArgs._s = m.sessionHitsCount
  356.  
  357. if m.options.userLanguage <> invalid
  358. queryArgs.ul = LCase(m.options.userLanguage)
  359. end if
  360.  
  361. if m.options.appName <> invalid
  362. queryArgs.an = m.options.appName
  363. end if
  364.  
  365. if m.options.appVersion <> invalid
  366. queryArgs.av = m.options.appVersion
  367. end if
  368.  
  369. if m.options.docTitle <> invalid
  370. queryArgs.dt = m.options.docTitle
  371. end if
  372.  
  373. if m.options.docLocation <> invalid
  374. queryArgs.dl = m.options.docLocation
  375. end if
  376.  
  377. if m.options.screenRes <> invalid
  378. queryArgs.sr = m.options.screenRes
  379. end if
  380.  
  381. if codedEvent.en = "page_view"
  382. queryArgs.seg = 0
  383.  
  384. if m.pendingFirstVisit = true
  385. queryArgs._fv = 2
  386. m.pendingFirstVisit = false
  387. end if
  388.  
  389. if m.pendingSessionStart = true
  390. queryArgs._ss = 2
  391. m.pendingSessionStart = false
  392. end if
  393. else
  394. queryArgs.seg = 1
  395. end if
  396.  
  397. codedEvent = addFSFireBaseFields(codedEvent, queryArgs) 'slc added
  398.  
  399. for each key in codedEvent
  400. queryArgs[key] = codedEvent[key]
  401. end for
  402.  
  403. queryParts = []
  404. for each key in queryArgs
  405. queryParts.Push(key.EncodeUriComponent() + "=" + convertToString(queryArgs[key]).EncodeUriComponent())
  406. end for
  407. 'STOP
  408. ?queryArgs
  409.  
  410. queryString = queryParts.Join("&")
  411.  
  412. m.lastEventTime = nowTime
  413. 'STOP
  414. doSendHttpRequest(m.endpoint, queryString)
  415.  
  416. return(0)
  417.  
  418. 'NOT USED
  419. request = CreateObject("roSGNode", "GoogleAnalytics4")
  420. request.functionName = "sendHttpRequest"
  421. request.httpMethod = "POST"
  422. request.httpUrl = m.endpoint + "?" + queryString
  423.  
  424. ?"[GoogleAnalytics4] url:" m.endpoint
  425. ?"[GoogleAnalytics4] post:" queryString
  426.  
  427. request.control = "RUN"
  428. end function
  429.  
  430. function addFSFireBaseFields(codedEvent, queryArgs)
  431.  
  432. codedEvent["ep.origin"] = "firebase"
  433. codedEvent["ep.action"] = m.top.RokuAnalyticsPlayerState
  434. codedEvent["_s"] = m.top.RokuAnalyticsEventValue
  435. codedEvent["ec"] = m.top.RokuAnalyticsEventCategory.Replace(" ", "_")
  436. codedEvent["dt"] = m.top.RokuAnalyticsPlayerTitle
  437. codedEvent["ep.label"] = m.top.RokuAnalyticsPlayerTitle
  438. codedEvent["epn.value"] = "1"
  439. codedEvent["cd"] = m.top.RokuAnalyticsEventCategory.Replace(" ", "_")
  440. codedEvent["uid"] = m.top.RokuAnalyticsLoginUserID
  441. codedEvent["up.aid"] = "appIDhere"
  442. codedEvent["up.an"] = queryArgs.an
  443. codedEvent["up.av"] = queryArgs.av
  444. codedEvent["up.ds"] = "roku"
  445. codedEvent["ds"] = "roku"
  446. codedEvent["z"] = queryArgs._p
  447.  
  448. return(codedEvent)
  449. end function
  450.  
  451. Function doSendHttpRequest(sPostEndPt, sPostData)
  452.  
  453. ?"[GoogleAnalytics4] url:";sPostEndPt
  454. ?"[GoogleAnalytics4] dat:";sPostData
  455.  
  456. di=createobject("roDeviceInfo")
  457. tmpVer=di.GetOsVersion()
  458. 'STOP
  459. verMajor=tmpVer["major"]
  460. verMinor=tmpVer["minor"]
  461. verBuild=tmpVer["build"]
  462. 'STOP
  463. myDVPstr = "Roku/DVP-"+verMajor+"."+verMinor+" ("+di.GetModel()+")"
  464. myUserAgent = "Mozilla/5.0 (RokuOS) AppleWebKit/537.36 (KHTML, like Gecko) " + myDVPstr
  465.  
  466. method = "POST"
  467. url = sPostEndPt + "?" + sPostData
  468.  
  469. port = CreateObject("roMessagePort")
  470. xfer = CreateObject("roUrlTransfer")
  471. xfer.SetCertificatesFile("common:/certs/ca-bundle.crt")
  472. 'Examples
  473. 'xfer.AddHeader("user-agent", "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0" )
  474. 'xfer.AddHeader("user-agent", "Mozilla/5.0 (compatible; Roku OS) AppleWebKit/533.3 (KHTML, like Gecko) Qt/4.7.0 Safari/533.3 Netflix/3.2 (DEVTYPE=RKU-42XXX-; CERTVER=0) QtWebKit/2.2, Roku 3/7.0 (Roku, 4200X, Wireless)")
  475. 'xfer.AddHeader("user-agent", "Mozilla/5.0 (Windows 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 Roku/DVP (147.53E04068A)")
  476. 'xfer.AddHeader("user-agent", "Mozilla/5.0 (Windows 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 Roku/DVP (147.53E04068A)")
  477. 'xfer.AddHeader("user-agent", "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543 Safari/419.3")
  478. 'xfer.AddHeader("user-agent", "Mozilla/5.0 (Android 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36 Roku/DVP")
  479. 'xfer.AddHeader("user-agent", "Mozilla/5.0 (Roku 9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36 Roku/DVP")
  480. 'xfer.AddHeader("user-agent", "Mozilla/5.0 (RokuOS) AppleWebKit/537.36 (KHTML, like Gecko) Roku/DVP")
  481. 'xfer.AddHeader("user-agent", "Mozilla/5.0 (compatible; U; NETFLIX) AppleWebKit/533.3 (KHTML, like Gecko) Qt/4.7.0 Safari/533.3 Netflix/3.2 (DEVTYPE=RKU-42XXX-; CERTVER=0) QtWebKit/2.2, Roku 3/7.0 (Roku, 4200X, Wireless)")
  482. xfer.AddHeader("user-agent", myUserAgent)
  483. 'STOP
  484. xfer.SetMessagePort(port)
  485. xfer.SetRequest(method)
  486. xfer.SetUrl(url)
  487.  
  488. ?"[GoogleAnalytics4] all:";url
  489.  
  490. requestSent = xfer.AsyncPostFromString("")
  491. if (requestSent)
  492. msg = wait(0, port)
  493. if (type(msg) = "roUrlEvent")
  494. statusCode = msg.GetResponseCode()
  495. if statusCode < 200 or statusCode > 299
  496. ?"ANALYTICS: ERROR - " msg.GetFailureReason()
  497. 'STOP
  498. end if
  499. end if
  500. end if
  501.  
  502. end function
  503.  
  504. function sendHttpRequest() 'see above
  505. method = m.top.httpMethod
  506. url = m.top.httpUrl
  507.  
  508. port = CreateObject("roMessagePort")
  509.  
  510. request = CreateObject("roUrlTransfer")
  511. request.SetCertificatesFile("common:/certs/ca-bundle.crt")
  512. request.SetMessagePort(port)
  513. request.SetRequest(method)
  514. request.SetUrl(url)
  515.  
  516. requestSent = request.AsyncPostFromString("")
  517.  
  518. if (requestSent)
  519. msg = wait(0, port)
  520.  
  521. if (type(msg) = "roUrlEvent")
  522. statusCode = msg.GetResponseCode()
  523.  
  524. if statusCode < 200 or statusCode > 299
  525. ? "ANALYTICS: ERROR - " msg.GetFailureReason()
  526. 'STOP
  527. end if
  528. end if
  529. end if
  530. end function
  531.  
  532. function parseEvent(eventName as String, eventParams as Object) as object
  533.  
  534. codedEvent = {
  535. en: eventName.Replace(" ", "_")
  536. }
  537.  
  538. if m.options.origin <> invalid
  539. codedEvent["ep.origin"] = m.options.origin
  540. end if
  541.  
  542. for each key in eventParams
  543. value = eventParams[key]
  544.  
  545. if value <> invalid
  546. codedKey = "ep." + key
  547. codedValue = value
  548.  
  549. if GetInterface(value, "ifInt") <> invalid or GetInterface(value, "ifFloat") <> invalid or GetInterface(value, "ifDouble") <> invalid
  550. codedKey = "epn." + key
  551. end if
  552.  
  553. if Type(codedValue) = "roInt" Or Type(codedValue) = "roInteger"
  554. if key.Instr("_") = -1
  555. ' convert integers to double (for custom parameters only)
  556. codedValue = Cdbl(codedValue)
  557. end if
  558. end if
  559.  
  560. if key = "ec" or key = "_et"
  561. codedKey = key
  562. end if
  563.  
  564. if key = "currency"
  565. codedKey = "cu"
  566. end if
  567.  
  568. codedEvent[codedKey] = codedValue
  569. end if
  570. end for
  571.  
  572. return codedEvent
  573. end function
  574.  
  575. sub logEvent(eventName as String, eventParams as Object)
  576. 'STOP
  577. codedEvent = parseEvent(eventName, eventParams)
  578.  
  579. if m.userId <> invalid and m.userId <> ""
  580. codedEvent.uid = m.userId
  581. end if
  582.  
  583. if m.screenName <> invalid and m.screenName <> ""
  584. codedEvent["ep.screen_name"] = m.screenName
  585. end if
  586.  
  587. if m.codedUserProperties <> invalid
  588. for each key in m.codedUserProperties
  589. codedEvent[key] = m.codedUserProperties[key]
  590. end for
  591. end if
  592.  
  593. send(codedEvent)
  594.  
  595. end sub
  596.  
  597. sub logScreenView(screenName as String)
  598. params = {
  599. firebase_screen: screenName
  600. }
  601.  
  602. if m.screenName <> invalid and m.screenName <> ""
  603. params.firebase_previous_screen = m.screenName
  604. end if
  605.  
  606. if m.screenName <> screenName
  607. setCurrentScreen(screenName)
  608. logEvent("screen_view", params)
  609. end if
  610. end sub
  611.  
  612. function parseUserProperties(userProperties as Object) as Object
  613. codedUserProperties = {}
  614.  
  615. for each key in userProperties
  616. value = userProperties[key]
  617. if value <> invalid
  618. if key.Instr("up.") = 0 or key.Instr("upn.") = 0
  619. ' already coded
  620. codedKey = key
  621. else
  622. codedKey = "up." + key
  623.  
  624. if GetInterface(value, "ifInt") <> invalid or GetInterface(value, "ifFloat") <> invalid or GetInterface(value, "ifDouble") <> invalid
  625. codedKey = "upn." + key
  626. end if
  627. end if
  628.  
  629. codedUserProperties[codedKey] = value
  630. end if
  631. end for
  632.  
  633. return codedUserProperties
  634. end function
  635.  
  636. sub setUserProperties(userProperties as Object)
  637. m.codedUserProperties = parseUserProperties(userProperties)
  638.  
  639. firstOpenTimeSeconds = getFirstOpenTimeSeconds()
  640.  
  641. m.codedUserProperties["up.id"] = m.userId
  642. m.codedUserProperties["upn.first_open_time"] = (roundFloatToInteger(firstOpenTimeSeconds / 3600) * 3600).ToStr() + "000"
  643. end sub
  644.  
  645. sub setUserId(userId)
  646. m.userId = userId
  647. end sub
  648.  
  649. sub setCurrentScreen(screenName as String)
  650. m.screenName = screenName
  651. end sub
  652.  
  653. sub resetAnalyticsData ()
  654. m.screenName = invalid
  655. m.userId = invalid
  656. m.codedUserProperties = invalid
  657. end sub
  658.  
  659. function convertToString(variable As Dynamic) As String
  660. if GetInterface(variable, "ifIntOps") <> invalid then
  661. return variable.ToStr()
  662. else if Type(variable) = "roInt" Or Type(variable) = "roInteger" Then
  663. return Str(variable).Trim()
  664. else if Type(variable) = "roFloat" Or Type(variable) = "Float" Then
  665. strValue = Str(variable).Trim()
  666.  
  667. if strValue.Instr(".") = -1
  668. strValue = strValue + ".0"
  669. end if
  670.  
  671. return strValue
  672. else if Type(variable) = "roBoolean" Or Type(variable) = "Boolean" Then
  673. if variable = True Then
  674. return "true"
  675. end If
  676. return "false"
  677. else if Type(variable) = "roString" Or Type(variable) = "String" Then
  678. Return variable
  679. else if variable = invalid then
  680. return ""
  681. else
  682. return Type(variable)
  683. end if
  684. end function
  685.  
  686. function roundFloatToInteger(number as Float) as Integer
  687. truncateValue = Fix(number)
  688. decimalValue = number - truncateValue
  689.  
  690. if decimalValue > 0.5
  691. return truncateValue + 1
  692. else
  693. return truncateValue
  694. end if
  695. end function
  696.  
  697.  
  698.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement