├── lib ├── .gitkeep └── index.js ├── _config.yml ├── .babelrc ├── .gitignore ├── .eslintrc ├── .travis.yml ├── LICENSE.md ├── package.json ├── README.md ├── test └── index.js └── src └── index.js /lib/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-hacker -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/env"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .git/ 3 | .idea/ 4 | dist/ 5 | npm-debug.log 6 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ "airbnb-base" ], 3 | "rules": { 4 | "comma-dangle": ["error", "never"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | language: node_js 3 | node_js: 4 | - node 5 | env: 6 | - CXX=g++-4.8 7 | addons: 8 | apt: 9 | sources: 10 | - ubuntu-toolchain-r-test 11 | packages: 12 | - g++-4.8 13 | install: 14 | - export CXX="g++-4.8" 15 | - npm install -g npm@latest 16 | - npm install 17 | 18 | script: 19 | - npm test 20 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017, Calin Stefanescu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-google-analytics", 3 | "version": "1.0.2", 4 | "description": "A library to implement Google Analytics in desktop apps.", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "build": "babel src -d lib", 8 | "test": "cross-env NODE_ENV=test mocha --require @babel/register" 9 | }, 10 | "keywords": [ 11 | "google", 12 | "analytics", 13 | "google analytics", 14 | "electron" 15 | ], 16 | "author": "Eastercow (http://eastercowz.com)", 17 | "license": "MIT", 18 | "repository": { 19 | "type": "git", 20 | "url": "git@github.com:vacu/electron-google-analytics.git" 21 | }, 22 | "publishConfig": { 23 | "registry": "https://registry.npmjs.org/" 24 | }, 25 | "devDependencies": { 26 | "@babel/cli": "^7.11.6", 27 | "@babel/core": "^7.11.6", 28 | "@babel/preset-env": "^7.11.5", 29 | "@babel/register": "^7.11.5", 30 | "braces": ">=3.0.2", 31 | "chai": "^4.2.0", 32 | "cross-env": "^7.0.2", 33 | "eslint": "^7.9.0", 34 | "eslint-config-airbnb-base": "^14.2.0", 35 | "eslint-plugin-import": "^2.22.0", 36 | "mocha": "^8.1.3" 37 | }, 38 | "dependencies": { 39 | "electron-fetch": "^1.7.1", 40 | "uuid": "^8.3.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Google Analytics - [Measurement Protocol API](https://developers.google.com/analytics/devguides/collection/protocol/v1/) 2 | 3 | [![travis-ci](https://travis-ci.org/vacu/electron-google-analytics.svg?branch=master)](https://travis-ci.org/vacu/electron-google-analytics) 4 | [![dependencies Status](https://david-dm.org/vacu/electron-google-analytics/status.svg)](https://david-dm.org/vacu/electron-google-analytics) 5 | ![](https://img.shields.io/badge/code%20style-airbnb-green.svg) 6 | 7 | 8 | The main purpose of this was to be used with [Electron](http://electron.atom.io/) built apps. 9 | 10 | #### Features 11 | * Pageview 12 | * Event 13 | * Screenview 14 | * Transaction 15 | * Social 16 | * Exception 17 | * Refund 18 | * Purchase 19 | * Checkout Steps 20 | * Checkout Options 21 | * Item 22 | * User Timing Tracking 23 | * Custom function for the rest (send) 24 | 25 | #### [Github Page - Docs](https://vacu.github.io/electron-google-analytics/) 26 | https://vacu.github.io/electron-google-analytics/ 27 | 28 | #### Getting started 29 | Installation 30 | ``` 31 | npm i electron-google-analytics 32 | ``` 33 | 34 | * Init 35 | 36 | `Analytics(trackingID, { userAgent, debug, version })` 37 | ```javascript 38 | import Analytics from 'electron-google-analytics'; 39 | const analytics = new Analytics('UA-XXXXXXXX-X'); 40 | ``` 41 | * Set (custom params) 42 | 43 | `Analytics#set(key, value)` 44 | ```javascript 45 | analytics.set('uid', 123); 46 | ``` 47 | * Remove parameter: 48 | 49 | ```javascript 50 | analytics.set('uid', null); 51 | ``` 52 | 53 | * Pageview 54 | 55 | `Analytics#pageview(hostname, url, title, clientID, sessionDuration)` 56 | ```javascript 57 | return analytics.pageview('http://example.com', '/home', 'Example') 58 | .then((response) => { 59 | return response; 60 | }).catch((err) => { 61 | return err; 62 | }); 63 | ``` 64 | If you want to keep the session you need to specify the `clientID`. The `clientID` can be found in the promise `response` above. 65 | 66 | * Event 67 | 68 | `Analytics#event(evCategory, evAction, { evLabel, evValue, clientID })` 69 | ```javascript 70 | return analytics.event('Video', 'play', { evLabel: 'holiday', evValue: 300}) 71 | .then((response) => { 72 | return response; 73 | }).catch((err) => { 74 | return err; 75 | }); 76 | ``` 77 | 78 | * Screenview 79 | 80 | `Analytics#screen(appName, appVer, appID, appInstallerID, screenName, clientID)` 81 | ```javascript 82 | return analytics.screen('test', '1.0.0', 'com.app.test', 'com.app.installer', 'Test') 83 | .then((response) => { 84 | return response; 85 | }).catch((err) => { 86 | return err; 87 | }); 88 | ``` 89 | 90 | * Transaction 91 | 92 | `Analytics#transaction(trnID, { trnAffil, trnRev, trnShip, trnTax, currCode } = {}, clientID)` 93 | ```javascript 94 | return analytics.transaction(123).then((response) => { 95 | return response; 96 | }).catch((err) => { 97 | return err; 98 | }); 99 | ``` 100 | 101 | * Social 102 | 103 | `Analytics#social(socialAction, socialNetwork, socialTarget, clientID)` 104 | ```javascript 105 | return analytics.social('like', 'facebook', 'home').then((response) => { 106 | return response; 107 | }).catch((err) => { 108 | return err; 109 | }); 110 | ``` 111 | 112 | * Exception 113 | 114 | `Analytics#exception(exDesc, exFatal, clientID)` 115 | ```javascript 116 | return analytics.exception('IOException', 1).then((response) => { 117 | return response; 118 | }).catch((err) => { 119 | return err; 120 | }); 121 | ``` 122 | 123 | * Refund 124 | 125 | `Analytics#refund(trnID, evCategory = 'Ecommerce', evAction = 'Refund', nonInteraction = 1, { prdID, prdQty } = {}, clientID)` 126 | ```javascript 127 | return analytics.refund('T123').then((response) => { 128 | return response; 129 | }).catch((err) => { 130 | return err; 131 | }); 132 | ``` 133 | 134 | * Purchase 135 | 136 | `Analytics#purchase(hostname, url, title, transactionID, { 137 | trnAffil, trnRev, trnTax, trnShip, trnCoupon, 138 | prdID, prdName, prdCtg, prdBrand, prdVar, prdPos 139 | } = {}, clientID)` 140 | ```javascript 141 | return analytics.purchase('http://example.com', '/test', 'Test', 'T123', { prdID: 'P123' }).then((response) => { 142 | return response; 143 | }).catch((err) => { 144 | return err; 145 | }); 146 | ``` 147 | 148 | * Checkout Steps 149 | 150 | `Analytics#checkout(hostname, url, title, checkoutStep, checkoutOpt, { 151 | prdID, prdName, prdCtg, prdBrand, prdVar, prdPrice, prdQty 152 | } = {}, clientID)` 153 | ```javascript 154 | return analytics.checkout('http://example.com', '/test', 'Test', '1', 'Visa').then((response) => { 155 | return response; 156 | }).catch((err) => { 157 | return err; 158 | }); 159 | ``` 160 | 161 | * Checkout Options 162 | 163 | `Analytics#checkoutOpt(evCategory, evAction, checkoutStep, checkoutOpt, clientID)` 164 | ```javascript 165 | return analytics.checkoutOpt('Checkout', 'Option', '2', 'FedEx').then((response) => { 166 | return response; 167 | }).catch((err) => { 168 | return err; 169 | }); 170 | ``` 171 | 172 | * Item 173 | 174 | `Analytics#item(trnID, itemName, { itemPrice, itemQty, itemSku, itemVariation, currCode } = {}, clientID)` 175 | ```javascript 176 | return analytics.item(123, 'Test item').then((response) => { 177 | return response; 178 | }).catch((err) => { 179 | return err; 180 | }); 181 | ``` 182 | 183 | * User Timing Tracking 184 | 185 | `Analytics#timingTrk(timingCtg, timingVar, timingTime, { timingLbl, dns, pageDownTime, redirTime, tcpConnTime, serverResTime } = {}, clientID)` 186 | ```javascript 187 | return analytics.timingTrk('Category', 'jsonLoader').then((response) => { 188 | return response; 189 | }).catch((err) => { 190 | return err; 191 | }); 192 | ``` 193 | 194 | * Send (for everything else for now) 195 | 196 | `Analytics#send(hitType, params, clientID)` 197 | ```javascript 198 | return analytics.send('social', { sa: 'social', sn: 'facebook', st: 'home' }) 199 | .then((response) => { 200 | return response; 201 | }).catch((err) => { 202 | return err; 203 | }); 204 | ``` 205 | #### es5 usage 206 | If you are not using tools like babel to use es6 with your application, you'll have to modify your code slightly. Below is an example of a test screen view that you can use out of the box with node.js 207 | 208 | ```javascript 209 | const Analytics = require('electron-google-analytics'); 210 | const analytics = new Analytics.default('UA-XXXXXXXX-X'); 211 | 212 | function test(){ 213 | return analytics.screen('test', '1.0.0', 'com.app.test', 'com.app.installer', 'Test') 214 | .then((response) => { 215 | return response; 216 | }).catch((err) => { 217 | return err; 218 | }); 219 | } 220 | test(); 221 | ``` 222 | 223 | #### Tests 224 | ``` 225 | cross-env TRACKING_ID='UA-XXXXXXXX-X' npm test 226 | ``` 227 | 228 | [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VXUG7T2PHHMV4) 229 | 230 | # MIT 231 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | import chai from 'chai'; 2 | import Analytics from '../src/index'; 3 | 4 | const expect = chai.expect; 5 | const trackingID = (process.env.TRACKING_ID) ? process.env.TRACKING_ID : ''; 6 | 7 | describe('Analytics', function() { 8 | if (trackingID) { 9 | it('should send a pageview request', function() { 10 | const analytics = new Analytics(trackingID, { debug: true }); 11 | 12 | return analytics.pageview('http://example.com', '/test', 'Test') 13 | .then((response) => { 14 | return expect(response).to.have.property('clientID'); 15 | }).catch((err) => { 16 | return expect(err).to.be.empty; 17 | }); 18 | }); 19 | 20 | it('should send a event request', function() { 21 | const analytics = new Analytics(trackingID, { debug: true }); 22 | 23 | return analytics.event('category', 'view').then((response) => { 24 | return expect(response).to.have.property('clientID'); 25 | }).catch((err) => { 26 | return expect(err).to.be.empty; 27 | }); 28 | }); 29 | 30 | it('should send a screenview request', function() { 31 | const analytics = new Analytics(trackingID, { debug: true }); 32 | 33 | return analytics.screen('test', '1.0.0', 'com.app.test', 'com.app.installer', 'Test') 34 | .then((response) => { 35 | return expect(response).to.have.property('clientID'); 36 | }).catch((err) => { 37 | return expect(err).to.be.empty; 38 | }); 39 | }); 40 | 41 | it('should send a transaction request', function() { 42 | const analytics = new Analytics(trackingID, { debug: true }); 43 | 44 | return analytics.transaction(123).then((response) => { 45 | return expect(response).to.have.property('clientID'); 46 | }).catch((err) => { 47 | return expect(err).to.be.empty; 48 | }); 49 | }); 50 | 51 | it('should send a social request', function() { 52 | const analytics = new Analytics(trackingID, { debug: true }); 53 | 54 | return analytics.social('like', 'facebook', 'home').then((response) => { 55 | return expect(response).to.have.property('clientID'); 56 | }).catch((err) => { 57 | return expect(err).to.be.empty; 58 | }); 59 | }); 60 | 61 | it('should send a exception request', function() { 62 | const analytics = new Analytics(trackingID, { debug: true }); 63 | 64 | return analytics.exception('IOException', 1).then((response) => { 65 | return expect(response).to.have.property('clientID'); 66 | }).catch((err) => { 67 | return expect(err).to.be.empty; 68 | }); 69 | }); 70 | 71 | it('should send a refund request', function() { 72 | const analytics = new Analytics(trackingID, { debug: true }); 73 | 74 | return analytics.refund('T123').then((response) => { 75 | return expect(response).to.have.property('clientID'); 76 | }).catch((err) => { 77 | return expect(err).to.be.empty; 78 | }); 79 | }); 80 | 81 | it('should send a purchase request', function() { 82 | const analytics = new Analytics(trackingID, { debug: true }); 83 | 84 | return analytics.purchase('http://example.com', '/test', 'Test', 'T123', { prdID: 'P123' }) 85 | .then((response) => { 86 | return expect(response).to.have.property('clientID'); 87 | }).catch((err) => { 88 | return expect(err).to.be.empty; 89 | }); 90 | }); 91 | 92 | it('should send a checkout request', function() { 93 | const analytics = new Analytics(trackingID, { debug: true }); 94 | 95 | return analytics.checkout('http://example.com', '/test', 'Test', '1', 'Visa') 96 | .then((response) => { 97 | return expect(response).to.have.property('clientID'); 98 | }).catch((err) => { 99 | return expect(err).to.be.empty; 100 | }); 101 | }); 102 | 103 | it('should send a checkoutOpt request', function() { 104 | const analytics = new Analytics(trackingID, { debug: true }); 105 | 106 | return analytics.checkoutOpt('Checkout', 'Option', '2', 'FedEx') 107 | .then((response) => { 108 | return expect(response).to.have.property('clientID'); 109 | }).catch((err) => { 110 | return expect(err).to.be.empty; 111 | }); 112 | }); 113 | 114 | it('should send a item request', function() { 115 | const analytics = new Analytics(trackingID, { debug: true }); 116 | 117 | return analytics.item(123, 'Test item').then((response) => { 118 | return expect(response).to.have.property('clientID'); 119 | }).catch((err) => { 120 | return expect(err).to.be.empty; 121 | }); 122 | }); 123 | 124 | it('should send a timing tracking request', function() { 125 | const analytics = new Analytics(trackingID, { debug: true }); 126 | 127 | return analytics.timingTrk('Category', 'jsonLoader').then((response) => { 128 | return expect(response).to.have.property('clientID'); 129 | }).catch((err) => { 130 | return expect(err).to.be.empty; 131 | }); 132 | }); 133 | 134 | it('should send a custom request', function() { 135 | const analytics = new Analytics(trackingID, { debug: true }); 136 | 137 | return analytics.send('social', { sa: 'social', sn: 'facebook', st: 'home' }) 138 | .then((response) => { 139 | return expect(response).to.have.property('clientID'); 140 | }).catch((err) => { 141 | return expect(err).to.be.empty; 142 | }); 143 | }); 144 | } 145 | 146 | 147 | it('should fail sending a pageview request', function() { 148 | const analytics = new Analytics('', { debug: true }); 149 | 150 | return analytics.pageview('http://example.com', 'test', 'test') 151 | .then((response) => { 152 | return expect(response).to.be.empty; 153 | }).catch((err) => { 154 | return expect(err).to.not.be.empty; 155 | }); 156 | }); 157 | 158 | it('should fail sending a event request', function() { 159 | const analytics = new Analytics('', { debug: true }); 160 | 161 | return analytics.event('category', 'view').then((response) => { 162 | return expect(response).to.be.empty; 163 | }).catch((err) => { 164 | return expect(err).to.not.be.empty; 165 | }); 166 | }); 167 | 168 | it('should fail sending a screenview request', function() { 169 | const analytics = new Analytics('', { debug: true }); 170 | 171 | return analytics.screen('test', '1.0.0', 'com.app.test', 'com.app.installer', 'Test') 172 | .then((response) => { 173 | return expect(response).to.be.empty; 174 | }).catch((err) => { 175 | return expect(err).to.not.be.empty; 176 | }); 177 | }); 178 | 179 | it('should fail sending a transaction request', function() { 180 | const analytics = new Analytics('', { debug: true }); 181 | 182 | return analytics.transaction(123).then((response) => { 183 | return expect(response).to.be.empty; 184 | }).catch((err) => { 185 | return expect(err).to.not.be.empty; 186 | }); 187 | }); 188 | 189 | it('should fail sending a social request', function() { 190 | const analytics = new Analytics('', { debug: true }); 191 | 192 | return analytics.social('like', 'facebook', 'home').then((response) => { 193 | return expect(response).to.be.empty; 194 | }).catch((err) => { 195 | return expect(err).to.not.be.empty; 196 | }); 197 | }); 198 | 199 | it('should fail sending a exception request', function() { 200 | const analytics = new Analytics('', { debug: true }); 201 | 202 | return analytics.exception('IOException', 1).then((response) => { 203 | return expect(response).to.be.empty; 204 | }).catch((err) => { 205 | return expect(err).to.not.be.empty; 206 | }); 207 | }); 208 | 209 | it('should fail sending a refund request', function() { 210 | const analytics = new Analytics('', { debug: true }); 211 | 212 | return analytics.refund('T123').then((response) => { 213 | return expect(response).to.be.empty; 214 | }).catch((err) => { 215 | return expect(err).to.not.be.empty; 216 | }); 217 | }); 218 | 219 | it('should fail sending a purchase request', function() { 220 | const analytics = new Analytics('', { debug: true }); 221 | 222 | return analytics.purchase('http://example.com', '/test', 'Test', 'T123', { prdID: 'P123' }) 223 | .then((response) => { 224 | return expect(response).to.be.empty; 225 | }).catch((err) => { 226 | return expect(err).to.not.be.empty; 227 | }); 228 | }); 229 | 230 | it('should fail sending a checkout request', function() { 231 | const analytics = new Analytics('', { debug: true }); 232 | 233 | return analytics.checkout('http://example.com', '/test', 'Test', '1', 'Visa') 234 | .then((response) => { 235 | return expect(response).to.be.empty; 236 | }).catch((err) => { 237 | return expect(err).to.not.be.empty; 238 | }); 239 | }); 240 | 241 | it('should fail sending a checkoutOpt request', function() { 242 | const analytics = new Analytics('', { debug: true }); 243 | 244 | return analytics.checkoutOpt('Checkout', 'Option', '2', 'FedEx') 245 | .then((response) => { 246 | return expect(response).to.be.empty; 247 | }).catch((err) => { 248 | return expect(err).to.not.be.empty; 249 | }); 250 | }); 251 | 252 | it('should fail sending a item request', function() { 253 | const analytics = new Analytics('', { debug: true }); 254 | 255 | return analytics.item(123, 'Test item').then((response) => { 256 | return expect(response).to.be.empty; 257 | }).catch((err) => { 258 | return expect(err).to.not.be.empty; 259 | }); 260 | }); 261 | 262 | it('should fail sending a timing tracking request', function() { 263 | const analytics = new Analytics('', { debug: true }); 264 | 265 | return analytics.timingTrk('Category', 'jsonLoader').then((response) => { 266 | return expect(response).to.be.empty; 267 | }).catch((err) => { 268 | return expect(err).to.not.be.empty; 269 | }); 270 | }); 271 | 272 | it('should fail sending a custom request', function() { 273 | const analytics = new Analytics('', { debug: true }); 274 | 275 | return analytics.send('social', { sa: 'social', sn: 'facebook', st: 'home' }) 276 | .then((response) => { 277 | return expect(response).to.be.empty; 278 | }).catch((err) => { 279 | return expect(err).to.not.be.empty; 280 | }); 281 | }); 282 | }); 283 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import fetch from 'electron-fetch'; 2 | import { v4 as uuidv4 } from 'uuid'; 3 | 4 | class Analytics { 5 | /** 6 | * Constructor 7 | * 8 | * @param {string} trackingID 9 | * @param {Object} param1 10 | */ 11 | constructor(trackingID, { 12 | userAgent = '', 13 | debug = false, 14 | version = 1 15 | } = {}) { 16 | // Debug 17 | this.globalDebug = debug; 18 | // User-agent 19 | this.globalUserAgent = userAgent; 20 | // Links 21 | this.globalBaseURL = 'https://www.google-analytics.com'; 22 | this.globalDebugURL = '/debug'; 23 | this.globalCollectURL = '/collect'; 24 | this.globalBatchURL = '/batch'; 25 | // Google generated ID 26 | this.globalTrackingID = trackingID; 27 | // Google API version 28 | this.globalVersion = version; 29 | // Custom parameters 30 | this.customParams = {}; 31 | } 32 | 33 | /** 34 | * Adds custom parameters to requests 35 | * if value is null, then parameter will be removed 36 | * 37 | * @param {string} key Parameter name 38 | * @param {string} value Parameter value 39 | */ 40 | set(key, value) { 41 | if (value !== null) { 42 | this.customParams[key] = value; 43 | } else { 44 | delete this.customParams[key]; 45 | } 46 | } 47 | 48 | /** 49 | * Send a "pageview" request 50 | * 51 | * @param {string} url Url of the page 52 | * @param {string} title Title of the page 53 | * @param {string} hostname Document hostname 54 | * @param {string} clientID uuidV4 55 | * @param {string} sessDuration A string to force start or end a session 56 | * 57 | * @return {Promise} 58 | */ 59 | pageview(hostname, url, title, clientID, sessDuration) { 60 | const params = { 61 | dh: hostname, 62 | dp: url, 63 | dt: title 64 | }; 65 | 66 | if (typeof sessDuration !== 'undefined') { 67 | params.sc = sessDuration; 68 | } 69 | 70 | return this.send('pageview', params, clientID); 71 | } 72 | 73 | /** 74 | * Send a "event" request 75 | * 76 | * @param {string} evCategory Event category 77 | * @param {string} evAction Event action 78 | * @param {string} clientID uuidV4 79 | * @param {string} evLabel Event label 80 | * @param {string} evValue Event description 81 | * 82 | * @return {Promise} 83 | */ 84 | event(evCategory, evAction, { evLabel, evValue, clientID } = {}) { 85 | const params = { ec: evCategory, ea: evAction }; 86 | 87 | if (evLabel) params.el = evLabel; 88 | if (evValue) params.ev = evValue; 89 | 90 | return this.send('event', params, clientID); 91 | } 92 | 93 | /** 94 | * Send a "screenview" request 95 | * 96 | * @param {string} appName App name 97 | * @param {string} appVer App version 98 | * @param {string} appID App Id 99 | * @param {string} appInstallerID App Installer Id 100 | * @param {string} screenName Screen name / Content description 101 | * @param {string} clientID uuidV4 102 | * 103 | * @return {Promise} 104 | */ 105 | screen(appName, appVer, appID, appInstallerID, screenName, clientID) { 106 | const params = { 107 | an: appName, 108 | av: appVer, 109 | aid: appID, 110 | aiid: appInstallerID, 111 | cd: screenName 112 | }; 113 | 114 | return this.send('screenview', params, clientID); 115 | } 116 | 117 | /** 118 | * Send a "transaction" request 119 | * 120 | * @param {string} trnID Transaction ID 121 | * @param {string} trnAffil Transaction affiliation 122 | * @param {string} trnRev Transaction Revenue 123 | * @param {Number} trnShip Transaction shipping 124 | * @param {Number} trnTax Transaction tax 125 | * @param {string} currCode Currency code 126 | * @param {string} clientID uuidV4 127 | * 128 | * @return {Promise} 129 | */ 130 | transaction(trnID, { 131 | trnAffil, trnRev, trnShip, trnTax, currCode 132 | } = {}, clientID) { 133 | const params = { ti: trnID }; 134 | 135 | if (trnAffil) params.ta = trnAffil; 136 | if (trnRev) params.tr = trnRev; 137 | if (trnShip) params.ts = trnShip; 138 | if (trnTax) params.tt = trnTax; 139 | if (currCode) params.cu = currCode; 140 | 141 | return this.send('transaction', params, clientID); 142 | } 143 | 144 | /** 145 | * Send a "social" request 146 | * 147 | * @param {string} socialAction Social Action 148 | * @param {string} socialNetwork Social Network 149 | * @param {string} socialTarget Social Target 150 | * @param {string} clientID uuidV4 151 | * 152 | * @return {Promise} 153 | */ 154 | social(socialAction, socialNetwork, socialTarget, clientID) { 155 | const params = { sa: socialAction, sn: socialNetwork, st: socialTarget }; 156 | 157 | return this.send('social', params, clientID); 158 | } 159 | 160 | /** 161 | * Send a "exception" request 162 | * 163 | * @param {string} exDesc Exception description 164 | * @param {Number} exFatal Exception is fatal? 165 | * @param {string} clientID uuidV4 166 | * 167 | * @return {Promise} 168 | */ 169 | exception(exDesc, exFatal, clientID) { 170 | const params = { exd: exDesc, exf: exFatal }; 171 | 172 | return this.send('exception', params, clientID); 173 | } 174 | 175 | /** 176 | * Send a "refund" request 177 | * 178 | * @param {string} trnID Transaction ID 179 | * @param {string} evCategory Event category 180 | * @param {string} evAction Event action 181 | * @param {Number} nonInteraction Non-interaction parameter 182 | * @param {string} prdID Product ID 183 | * @param {Number} prdQty Product quantity 184 | * @param {string} clientID uuidV4 185 | * 186 | * @returns {Promise} 187 | */ 188 | refund(trnID, evCategory = 'Ecommerce', evAction = 'Refund', nonInteraction = 1, { prdID, prdQty } = {}, clientID) { 189 | const params = { 190 | ec: evCategory, 191 | ea: evAction, 192 | ni: nonInteraction, 193 | ti: trnID, 194 | pa: 'refund' 195 | }; 196 | 197 | if (prdID) params.pr1id = prdID; 198 | if (prdQty) params.pr1qt = prdQty; 199 | 200 | return this.send('event', params, clientID); 201 | } 202 | 203 | /** 204 | * Send a "purchase" request 205 | * @param {string} hostname Document hostname 206 | * @param {string} url Url of the page 207 | * @param {string} title Title of the page 208 | * @param {string} transactionID Transaction ID 209 | * @param {string} trnAffil Transaction affiliation 210 | * @param {string} trnRev Transaction Revenue 211 | * @param {Number} trnTax Transaction tax 212 | * @param {Number} trnShip Transaction shipping 213 | * @param {string} trnCoupon Transaction coupon 214 | * @param {string} prdID Product ID 215 | * @param {string} prdName Product name 216 | * @param {string} prdCtg Product category 217 | * @param {string} prdBrand Product brand 218 | * @param {string} prdVar Product variant 219 | * @param {string} prdPos Product position 220 | * @param {string} clientID uuidV4 221 | * @return {Promise} 222 | */ 223 | purchase(hostname, url, title, transactionID, { 224 | trnAffil, trnRev, trnTax, trnShip, trnCoupon, 225 | prdID, prdName, prdCtg, prdBrand, prdVar, prdPos 226 | } = {}, clientID) { 227 | const params = { 228 | dh: hostname, 229 | dp: url, 230 | dt: title, 231 | ti: transactionID, 232 | pa: 'purchase' 233 | }; 234 | 235 | // Transaction params 236 | if (trnAffil) params.ta = trnAffil; 237 | if (trnRev) params.tr = trnRev; 238 | if (trnTax) params.tt = trnTax; 239 | if (trnShip) params.ts = trnShip; 240 | if (trnCoupon) params.tcc = trnCoupon; 241 | // Product params 242 | if (prdID) params.pr1id = prdID; 243 | if (prdName) params.pr1nm = prdName; 244 | if (prdCtg) params.pr1ca = prdCtg; 245 | if (prdBrand) params.pr1br = prdBrand; 246 | if (prdVar) params.pr1va = prdVar; 247 | if (prdPos) params.pr1p = prdPos; 248 | 249 | return this.send('pageview', params, clientID); 250 | } 251 | 252 | /** 253 | * Send a "checkout" request 254 | * @param {string} hostname Document hostname 255 | * @param {string} url Url of the page 256 | * @param {string} title Title of the page 257 | * @param {string} checkoutStep Checkout step 258 | * @param {string} checkoutOpt Checkout step option 259 | * @param {string} prdID Product ID 260 | * @param {string} prdName Product name 261 | * @param {string} prdCtg Product category 262 | * @param {string} prdBrand Product brand 263 | * @param {string} prdVar Product variant 264 | * @param {Number} prdPrice Product price 265 | * @param {Number} prdQty Product category 266 | * @param {string} clientID uuidV4 267 | * @return {Promise} 268 | */ 269 | checkout(hostname, url, title, checkoutStep, checkoutOpt, { 270 | prdID, prdName, prdCtg, prdBrand, prdVar, prdPrice, prdQty 271 | } = {}, clientID) { 272 | const params = { 273 | dh: hostname, 274 | dp: url, 275 | dt: title, 276 | pa: 'checkout', 277 | cos: checkoutStep, 278 | col: checkoutOpt 279 | }; 280 | 281 | if (prdID) params.pr1id = prdID; 282 | if (prdName) params.pr1nm = prdName; 283 | if (prdCtg) params.pr1ca = prdCtg; 284 | if (prdBrand) params.pr1br = prdBrand; 285 | if (prdVar) params.pr1va = prdVar; 286 | if (prdPrice) params.pr1pr = prdPrice; 287 | if (prdQty) params.pr1qt = prdQty; 288 | 289 | return this.send('pageview', params, clientID); 290 | } 291 | 292 | /** 293 | * Send a "checkout_option" request 294 | * @param {string} evCategory Event category 295 | * @param {string} evAction Event action 296 | * @param {string} checkoutStep Checkout step 297 | * @param {string} checkoutOpt Checkout step option 298 | * @param {string} clientID uuidV4 299 | * @return {Promise} 300 | */ 301 | checkoutOpt(evCategory, evAction, checkoutStep, checkoutOpt, clientID) { 302 | const params = { 303 | ec: evCategory, 304 | ea: evAction, 305 | pa: 'checkout_option' 306 | }; 307 | 308 | if (checkoutStep) params.cos = checkoutStep; 309 | if (checkoutOpt) params.col = checkoutOpt; 310 | 311 | return this.send('event', params, clientID); 312 | } 313 | 314 | /** 315 | * 316 | * @param {*} hostname 317 | * @param {*} url 318 | * @param {*} title 319 | * @param {*} param3 320 | * @param {*} clientID 321 | */ 322 | promoImp(hostname, url, title, { 323 | promoID, promoName, promoCrt, promoPos 324 | } = {}, clientID) { 325 | const params = { 326 | dh: hostname, 327 | dp: url, 328 | dt: title 329 | }; 330 | 331 | if (promoID) params.promo1id = promoID; 332 | if (promoName) params.promo1nm = promoName; 333 | if (promoCrt) params.promo1cr = promoCrt; 334 | if (promoPos) params.promo1ps = promoPos; 335 | 336 | return this.send('pageview', params, clientID); 337 | } 338 | 339 | /** 340 | * 341 | * @param {*} evCategory 342 | * @param {*} evAction 343 | * @param {*} param2 344 | * @param {*} clientID 345 | */ 346 | promoCk(evCategory, evAction, { 347 | evLabel, promoID, promoName, promoCrt, promoPos 348 | } = {}, clientID) { 349 | const params = { 350 | ec: evCategory, 351 | ea: evAction, 352 | promos: 'click' 353 | }; 354 | 355 | if (evLabel) params.el = evLabel; 356 | if (promoID) params.promo1id = promoID; 357 | if (promoName) params.promo1nm = promoName; 358 | if (promoCrt) params.promo1cr = promoCrt; 359 | if (promoPos) params.promo1ps = promoPos; 360 | 361 | return this.send('event', params, clientID); 362 | } 363 | 364 | /** 365 | * Send a "item" request 366 | * @param {string} trnID Transaction ID 367 | * @param {string} itemName Item name 368 | * @param {Number} itemPrice Item price 369 | * @param {string} itemQty Item quantity 370 | * @param {string} itemSku Item SKU 371 | * @param {string} itemVariation Item variation / category 372 | * @param {string} currCode Currency code 373 | * @param {string} clientID uuidV4 374 | * @return {Promise} 375 | */ 376 | item(trnID, itemName, { 377 | itemPrice, itemQty, itemSku, itemVariation, currCode 378 | } = {}, clientID) { 379 | const params = { ti: trnID, in: itemName }; 380 | 381 | if (itemPrice) params.ip = itemPrice; 382 | if (itemQty) params.iq = itemQty; 383 | if (itemSku) params.ic = itemSku; 384 | if (itemVariation) params.iv = itemVariation; 385 | if (currCode) params.cu = currCode; 386 | 387 | return this.send('item', params, clientID); 388 | } 389 | 390 | /** 391 | * Send a "timing tracking" request 392 | * @param {string} timingCtg Timing category 393 | * @param {string} timingVar Timing variable 394 | * @param {Number} timingTime Timing time 395 | * @param {string} timingLbl Timing label 396 | * @param {Number} dns DNS load time 397 | * @param {Number} pageDownTime Page download time 398 | * @param {Number} redirTime Redirect time 399 | * @param {Number} tcpConnTime TCP connect time 400 | * @param {Number} serverResTime Server response time 401 | * @param {string} clientID uuidV4 402 | * @return {Promise} 403 | */ 404 | timingTrk(timingCtg, timingVar, timingTime, { 405 | timingLbl, dns, pageDownTime, redirTime, tcpConnTime, serverResTime 406 | } = {}, clientID) { 407 | const params = { utc: timingCtg, utv: timingVar, utt: timingTime }; 408 | 409 | if (timingLbl) params.utl = timingLbl; 410 | if (dns) params.dns = dns; 411 | if (pageDownTime) params.pdt = pageDownTime; 412 | if (redirTime) params.rrt = redirTime; 413 | if (tcpConnTime) params.tcp = tcpConnTime; 414 | if (serverResTime) params.srt = serverResTime; 415 | 416 | return this.send('timing', params, clientID); 417 | } 418 | 419 | /** 420 | * Send a request to google-analytics 421 | * 422 | * @param {string} hitType Hit type 423 | * @param {string} clientID Unique identifier (uuidV4) 424 | * @param {Object} params Options 425 | * 426 | * @return {Promise} 427 | */ 428 | send(hitType, params, clientID) { 429 | const formObj = { 430 | v: this.globalVersion, 431 | tid: this.globalTrackingID, 432 | cid: clientID || uuidv4(), 433 | t: hitType 434 | }; 435 | if (params) Object.assign(formObj, params); 436 | 437 | if (Object.keys(this.customParams).length > 0) { 438 | Object.assign(formObj, this.customParams); 439 | } 440 | 441 | let url = `${this.globalBaseURL}${this.globalCollectURL}`; 442 | if (this.globalDebug) { 443 | url = `${this.globalBaseURL}${this.globalDebugURL}${this.globalCollectURL}`; 444 | } 445 | 446 | const reqObj = { 447 | method: 'post', 448 | body: Object.keys(formObj).map((key) => `${encodeURI(key)}=${encodeURI(formObj[key])}`).join('&') 449 | }; 450 | 451 | if (this.globalUserAgent !== '') { 452 | reqObj.headers = { 'User-Agent': this.globalUserAgent }; 453 | } 454 | 455 | return fetch(url, reqObj) 456 | .then((res) => { 457 | let response = {}; 458 | 459 | if (res.headers.get('content-type') !== 'image/gif') { 460 | response = res.json(); 461 | } else { 462 | response = res.text(); 463 | } 464 | 465 | if (res.status === 200) { 466 | return response; 467 | } 468 | 469 | return Promise.reject(new Error(response)); 470 | }).then((json) => { 471 | if (this.globalDebug) { 472 | if (json.hitParsingResult[0].valid) { 473 | return { clientID: formObj.cid }; 474 | } 475 | } 476 | 477 | return { clientID: formObj.cid }; 478 | }).catch((err) => new Error(err)); 479 | } 480 | } 481 | 482 | export default Analytics; 483 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports["default"] = void 0; 7 | 8 | var _electronFetch = _interopRequireDefault(require("electron-fetch")); 9 | 10 | var _uuid = require("uuid"); 11 | 12 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 13 | 14 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 15 | 16 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 17 | 18 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 19 | 20 | var Analytics = /*#__PURE__*/function () { 21 | /** 22 | * Constructor 23 | * 24 | * @param {string} trackingID 25 | * @param {Object} param1 26 | */ 27 | function Analytics(trackingID) { 28 | var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, 29 | _ref$userAgent = _ref.userAgent, 30 | userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent, 31 | _ref$debug = _ref.debug, 32 | debug = _ref$debug === void 0 ? false : _ref$debug, 33 | _ref$version = _ref.version, 34 | version = _ref$version === void 0 ? 1 : _ref$version; 35 | 36 | _classCallCheck(this, Analytics); 37 | 38 | // Debug 39 | this.globalDebug = debug; // User-agent 40 | 41 | this.globalUserAgent = userAgent; // Links 42 | 43 | this.globalBaseURL = 'https://www.google-analytics.com'; 44 | this.globalDebugURL = '/debug'; 45 | this.globalCollectURL = '/collect'; 46 | this.globalBatchURL = '/batch'; // Google generated ID 47 | 48 | this.globalTrackingID = trackingID; // Google API version 49 | 50 | this.globalVersion = version; // Custom parameters 51 | 52 | this.customParams = {}; 53 | } 54 | /** 55 | * Adds custom parameters to requests 56 | * if value is null, then parameter will be removed 57 | * 58 | * @param {string} key Parameter name 59 | * @param {string} value Parameter value 60 | */ 61 | 62 | 63 | _createClass(Analytics, [{ 64 | key: "set", 65 | value: function set(key, value) { 66 | if (value !== null) { 67 | this.customParams[key] = value; 68 | } else { 69 | delete this.customParams[key]; 70 | } 71 | } 72 | /** 73 | * Send a "pageview" request 74 | * 75 | * @param {string} url Url of the page 76 | * @param {string} title Title of the page 77 | * @param {string} hostname Document hostname 78 | * @param {string} clientID uuidV4 79 | * @param {string} sessDuration A string to force start or end a session 80 | * 81 | * @return {Promise} 82 | */ 83 | 84 | }, { 85 | key: "pageview", 86 | value: function pageview(hostname, url, title, clientID, sessDuration) { 87 | var params = { 88 | dh: hostname, 89 | dp: url, 90 | dt: title 91 | }; 92 | 93 | if (typeof sessDuration !== 'undefined') { 94 | params.sc = sessDuration; 95 | } 96 | 97 | return this.send('pageview', params, clientID); 98 | } 99 | /** 100 | * Send a "event" request 101 | * 102 | * @param {string} evCategory Event category 103 | * @param {string} evAction Event action 104 | * @param {string} clientID uuidV4 105 | * @param {string} evLabel Event label 106 | * @param {string} evValue Event description 107 | * 108 | * @return {Promise} 109 | */ 110 | 111 | }, { 112 | key: "event", 113 | value: function event(evCategory, evAction) { 114 | var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, 115 | evLabel = _ref2.evLabel, 116 | evValue = _ref2.evValue, 117 | clientID = _ref2.clientID; 118 | 119 | var params = { 120 | ec: evCategory, 121 | ea: evAction 122 | }; 123 | if (evLabel) params.el = evLabel; 124 | if (evValue) params.ev = evValue; 125 | return this.send('event', params, clientID); 126 | } 127 | /** 128 | * Send a "screenview" request 129 | * 130 | * @param {string} appName App name 131 | * @param {string} appVer App version 132 | * @param {string} appID App Id 133 | * @param {string} appInstallerID App Installer Id 134 | * @param {string} screenName Screen name / Content description 135 | * @param {string} clientID uuidV4 136 | * 137 | * @return {Promise} 138 | */ 139 | 140 | }, { 141 | key: "screen", 142 | value: function screen(appName, appVer, appID, appInstallerID, screenName, clientID) { 143 | var params = { 144 | an: appName, 145 | av: appVer, 146 | aid: appID, 147 | aiid: appInstallerID, 148 | cd: screenName 149 | }; 150 | return this.send('screenview', params, clientID); 151 | } 152 | /** 153 | * Send a "transaction" request 154 | * 155 | * @param {string} trnID Transaction ID 156 | * @param {string} trnAffil Transaction affiliation 157 | * @param {string} trnRev Transaction Revenue 158 | * @param {Number} trnShip Transaction shipping 159 | * @param {Number} trnTax Transaction tax 160 | * @param {string} currCode Currency code 161 | * @param {string} clientID uuidV4 162 | * 163 | * @return {Promise} 164 | */ 165 | 166 | }, { 167 | key: "transaction", 168 | value: function transaction(trnID) { 169 | var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, 170 | trnAffil = _ref3.trnAffil, 171 | trnRev = _ref3.trnRev, 172 | trnShip = _ref3.trnShip, 173 | trnTax = _ref3.trnTax, 174 | currCode = _ref3.currCode; 175 | 176 | var clientID = arguments.length > 2 ? arguments[2] : undefined; 177 | var params = { 178 | ti: trnID 179 | }; 180 | if (trnAffil) params.ta = trnAffil; 181 | if (trnRev) params.tr = trnRev; 182 | if (trnShip) params.ts = trnShip; 183 | if (trnTax) params.tt = trnTax; 184 | if (currCode) params.cu = currCode; 185 | return this.send('transaction', params, clientID); 186 | } 187 | /** 188 | * Send a "social" request 189 | * 190 | * @param {string} socialAction Social Action 191 | * @param {string} socialNetwork Social Network 192 | * @param {string} socialTarget Social Target 193 | * @param {string} clientID uuidV4 194 | * 195 | * @return {Promise} 196 | */ 197 | 198 | }, { 199 | key: "social", 200 | value: function social(socialAction, socialNetwork, socialTarget, clientID) { 201 | var params = { 202 | sa: socialAction, 203 | sn: socialNetwork, 204 | st: socialTarget 205 | }; 206 | return this.send('social', params, clientID); 207 | } 208 | /** 209 | * Send a "exception" request 210 | * 211 | * @param {string} exDesc Exception description 212 | * @param {Number} exFatal Exception is fatal? 213 | * @param {string} clientID uuidV4 214 | * 215 | * @return {Promise} 216 | */ 217 | 218 | }, { 219 | key: "exception", 220 | value: function exception(exDesc, exFatal, clientID) { 221 | var params = { 222 | exd: exDesc, 223 | exf: exFatal 224 | }; 225 | return this.send('exception', params, clientID); 226 | } 227 | /** 228 | * Send a "refund" request 229 | * 230 | * @param {string} trnID Transaction ID 231 | * @param {string} evCategory Event category 232 | * @param {string} evAction Event action 233 | * @param {Number} nonInteraction Non-interaction parameter 234 | * @param {string} prdID Product ID 235 | * @param {Number} prdQty Product quantity 236 | * @param {string} clientID uuidV4 237 | * 238 | * @returns {Promise} 239 | */ 240 | 241 | }, { 242 | key: "refund", 243 | value: function refund(trnID) { 244 | var evCategory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Ecommerce'; 245 | var evAction = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'Refund'; 246 | var nonInteraction = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1; 247 | 248 | var _ref4 = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}, 249 | prdID = _ref4.prdID, 250 | prdQty = _ref4.prdQty; 251 | 252 | var clientID = arguments.length > 5 ? arguments[5] : undefined; 253 | var params = { 254 | ec: evCategory, 255 | ea: evAction, 256 | ni: nonInteraction, 257 | ti: trnID, 258 | pa: 'refund' 259 | }; 260 | if (prdID) params.pr1id = prdID; 261 | if (prdQty) params.pr1qt = prdQty; 262 | return this.send('event', params, clientID); 263 | } 264 | /** 265 | * Send a "purchase" request 266 | * @param {string} hostname Document hostname 267 | * @param {string} url Url of the page 268 | * @param {string} title Title of the page 269 | * @param {string} transactionID Transaction ID 270 | * @param {string} trnAffil Transaction affiliation 271 | * @param {string} trnRev Transaction Revenue 272 | * @param {Number} trnTax Transaction tax 273 | * @param {Number} trnShip Transaction shipping 274 | * @param {string} trnCoupon Transaction coupon 275 | * @param {string} prdID Product ID 276 | * @param {string} prdName Product name 277 | * @param {string} prdCtg Product category 278 | * @param {string} prdBrand Product brand 279 | * @param {string} prdVar Product variant 280 | * @param {string} prdPos Product position 281 | * @param {string} clientID uuidV4 282 | * @return {Promise} 283 | */ 284 | 285 | }, { 286 | key: "purchase", 287 | value: function purchase(hostname, url, title, transactionID) { 288 | var _ref5 = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}, 289 | trnAffil = _ref5.trnAffil, 290 | trnRev = _ref5.trnRev, 291 | trnTax = _ref5.trnTax, 292 | trnShip = _ref5.trnShip, 293 | trnCoupon = _ref5.trnCoupon, 294 | prdID = _ref5.prdID, 295 | prdName = _ref5.prdName, 296 | prdCtg = _ref5.prdCtg, 297 | prdBrand = _ref5.prdBrand, 298 | prdVar = _ref5.prdVar, 299 | prdPos = _ref5.prdPos; 300 | 301 | var clientID = arguments.length > 5 ? arguments[5] : undefined; 302 | var params = { 303 | dh: hostname, 304 | dp: url, 305 | dt: title, 306 | ti: transactionID, 307 | pa: 'purchase' 308 | }; // Transaction params 309 | 310 | if (trnAffil) params.ta = trnAffil; 311 | if (trnRev) params.tr = trnRev; 312 | if (trnTax) params.tt = trnTax; 313 | if (trnShip) params.ts = trnShip; 314 | if (trnCoupon) params.tcc = trnCoupon; // Product params 315 | 316 | if (prdID) params.pr1id = prdID; 317 | if (prdName) params.pr1nm = prdName; 318 | if (prdCtg) params.pr1ca = prdCtg; 319 | if (prdBrand) params.pr1br = prdBrand; 320 | if (prdVar) params.pr1va = prdVar; 321 | if (prdPos) params.pr1p = prdPos; 322 | return this.send('pageview', params, clientID); 323 | } 324 | /** 325 | * Send a "checkout" request 326 | * @param {string} hostname Document hostname 327 | * @param {string} url Url of the page 328 | * @param {string} title Title of the page 329 | * @param {string} checkoutStep Checkout step 330 | * @param {string} checkoutOpt Checkout step option 331 | * @param {string} prdID Product ID 332 | * @param {string} prdName Product name 333 | * @param {string} prdCtg Product category 334 | * @param {string} prdBrand Product brand 335 | * @param {string} prdVar Product variant 336 | * @param {Number} prdPrice Product price 337 | * @param {Number} prdQty Product category 338 | * @param {string} clientID uuidV4 339 | * @return {Promise} 340 | */ 341 | 342 | }, { 343 | key: "checkout", 344 | value: function checkout(hostname, url, title, checkoutStep, checkoutOpt) { 345 | var _ref6 = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {}, 346 | prdID = _ref6.prdID, 347 | prdName = _ref6.prdName, 348 | prdCtg = _ref6.prdCtg, 349 | prdBrand = _ref6.prdBrand, 350 | prdVar = _ref6.prdVar, 351 | prdPrice = _ref6.prdPrice, 352 | prdQty = _ref6.prdQty; 353 | 354 | var clientID = arguments.length > 6 ? arguments[6] : undefined; 355 | var params = { 356 | dh: hostname, 357 | dp: url, 358 | dt: title, 359 | pa: 'checkout', 360 | cos: checkoutStep, 361 | col: checkoutOpt 362 | }; 363 | if (prdID) params.pr1id = prdID; 364 | if (prdName) params.pr1nm = prdName; 365 | if (prdCtg) params.pr1ca = prdCtg; 366 | if (prdBrand) params.pr1br = prdBrand; 367 | if (prdVar) params.pr1va = prdVar; 368 | if (prdPrice) params.pr1pr = prdPrice; 369 | if (prdQty) params.pr1qt = prdQty; 370 | return this.send('pageview', params, clientID); 371 | } 372 | /** 373 | * Send a "checkout_option" request 374 | * @param {string} evCategory Event category 375 | * @param {string} evAction Event action 376 | * @param {string} checkoutStep Checkout step 377 | * @param {string} checkoutOpt Checkout step option 378 | * @param {string} clientID uuidV4 379 | * @return {Promise} 380 | */ 381 | 382 | }, { 383 | key: "checkoutOpt", 384 | value: function checkoutOpt(evCategory, evAction, checkoutStep, _checkoutOpt, clientID) { 385 | var params = { 386 | ec: evCategory, 387 | ea: evAction, 388 | pa: 'checkout_option' 389 | }; 390 | if (checkoutStep) params.cos = checkoutStep; 391 | if (_checkoutOpt) params.col = _checkoutOpt; 392 | return this.send('event', params, clientID); 393 | } 394 | /** 395 | * 396 | * @param {*} hostname 397 | * @param {*} url 398 | * @param {*} title 399 | * @param {*} param3 400 | * @param {*} clientID 401 | */ 402 | 403 | }, { 404 | key: "promoImp", 405 | value: function promoImp(hostname, url, title) { 406 | var _ref7 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}, 407 | promoID = _ref7.promoID, 408 | promoName = _ref7.promoName, 409 | promoCrt = _ref7.promoCrt, 410 | promoPos = _ref7.promoPos; 411 | 412 | var clientID = arguments.length > 4 ? arguments[4] : undefined; 413 | var params = { 414 | dh: hostname, 415 | dp: url, 416 | dt: title 417 | }; 418 | if (promoID) params.promo1id = promoID; 419 | if (promoName) params.promo1nm = promoName; 420 | if (promoCrt) params.promo1cr = promoCrt; 421 | if (promoPos) params.promo1ps = promoPos; 422 | return this.send('pageview', params, clientID); 423 | } 424 | /** 425 | * 426 | * @param {*} evCategory 427 | * @param {*} evAction 428 | * @param {*} param2 429 | * @param {*} clientID 430 | */ 431 | 432 | }, { 433 | key: "promoCk", 434 | value: function promoCk(evCategory, evAction) { 435 | var _ref8 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, 436 | evLabel = _ref8.evLabel, 437 | promoID = _ref8.promoID, 438 | promoName = _ref8.promoName, 439 | promoCrt = _ref8.promoCrt, 440 | promoPos = _ref8.promoPos; 441 | 442 | var clientID = arguments.length > 3 ? arguments[3] : undefined; 443 | var params = { 444 | ec: evCategory, 445 | ea: evAction, 446 | promos: 'click' 447 | }; 448 | if (evLabel) params.el = evLabel; 449 | if (promoID) params.promo1id = promoID; 450 | if (promoName) params.promo1nm = promoName; 451 | if (promoCrt) params.promo1cr = promoCrt; 452 | if (promoPos) params.promo1ps = promoPos; 453 | return this.send('event', params, clientID); 454 | } 455 | /** 456 | * Send a "item" request 457 | * @param {string} trnID Transaction ID 458 | * @param {string} itemName Item name 459 | * @param {Number} itemPrice Item price 460 | * @param {string} itemQty Item quantity 461 | * @param {string} itemSku Item SKU 462 | * @param {string} itemVariation Item variation / category 463 | * @param {string} currCode Currency code 464 | * @param {string} clientID uuidV4 465 | * @return {Promise} 466 | */ 467 | 468 | }, { 469 | key: "item", 470 | value: function item(trnID, itemName) { 471 | var _ref9 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, 472 | itemPrice = _ref9.itemPrice, 473 | itemQty = _ref9.itemQty, 474 | itemSku = _ref9.itemSku, 475 | itemVariation = _ref9.itemVariation, 476 | currCode = _ref9.currCode; 477 | 478 | var clientID = arguments.length > 3 ? arguments[3] : undefined; 479 | var params = { 480 | ti: trnID, 481 | "in": itemName 482 | }; 483 | if (itemPrice) params.ip = itemPrice; 484 | if (itemQty) params.iq = itemQty; 485 | if (itemSku) params.ic = itemSku; 486 | if (itemVariation) params.iv = itemVariation; 487 | if (currCode) params.cu = currCode; 488 | return this.send('item', params, clientID); 489 | } 490 | /** 491 | * Send a "timing tracking" request 492 | * @param {string} timingCtg Timing category 493 | * @param {string} timingVar Timing variable 494 | * @param {Number} timingTime Timing time 495 | * @param {string} timingLbl Timing label 496 | * @param {Number} dns DNS load time 497 | * @param {Number} pageDownTime Page download time 498 | * @param {Number} redirTime Redirect time 499 | * @param {Number} tcpConnTime TCP connect time 500 | * @param {Number} serverResTime Server response time 501 | * @param {string} clientID uuidV4 502 | * @return {Promise} 503 | */ 504 | 505 | }, { 506 | key: "timingTrk", 507 | value: function timingTrk(timingCtg, timingVar, timingTime) { 508 | var _ref10 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}, 509 | timingLbl = _ref10.timingLbl, 510 | dns = _ref10.dns, 511 | pageDownTime = _ref10.pageDownTime, 512 | redirTime = _ref10.redirTime, 513 | tcpConnTime = _ref10.tcpConnTime, 514 | serverResTime = _ref10.serverResTime; 515 | 516 | var clientID = arguments.length > 4 ? arguments[4] : undefined; 517 | var params = { 518 | utc: timingCtg, 519 | utv: timingVar, 520 | utt: timingTime 521 | }; 522 | if (timingLbl) params.utl = timingLbl; 523 | if (dns) params.dns = dns; 524 | if (pageDownTime) params.pdt = pageDownTime; 525 | if (redirTime) params.rrt = redirTime; 526 | if (tcpConnTime) params.tcp = tcpConnTime; 527 | if (serverResTime) params.srt = serverResTime; 528 | return this.send('timing', params, clientID); 529 | } 530 | /** 531 | * Send a request to google-analytics 532 | * 533 | * @param {string} hitType Hit type 534 | * @param {string} clientID Unique identifier (uuidV4) 535 | * @param {Object} params Options 536 | * 537 | * @return {Promise} 538 | */ 539 | 540 | }, { 541 | key: "send", 542 | value: function send(hitType, params, clientID) { 543 | var _this = this; 544 | 545 | var formObj = { 546 | v: this.globalVersion, 547 | tid: this.globalTrackingID, 548 | cid: clientID || (0, _uuid.v4)(), 549 | t: hitType 550 | }; 551 | if (params) Object.assign(formObj, params); 552 | 553 | if (Object.keys(this.customParams).length > 0) { 554 | Object.assign(formObj, this.customParams); 555 | } 556 | 557 | var url = "".concat(this.globalBaseURL).concat(this.globalCollectURL); 558 | 559 | if (this.globalDebug) { 560 | url = "".concat(this.globalBaseURL).concat(this.globalDebugURL).concat(this.globalCollectURL); 561 | } 562 | 563 | var reqObj = { 564 | method: 'post', 565 | body: Object.keys(formObj).map(function (key) { 566 | return "".concat(encodeURI(key), "=").concat(encodeURI(formObj[key])); 567 | }).join('&') 568 | }; 569 | 570 | if (this.globalUserAgent !== '') { 571 | reqObj.headers = { 572 | 'User-Agent': this.globalUserAgent 573 | }; 574 | } 575 | 576 | return (0, _electronFetch["default"])(url, reqObj).then(function (res) { 577 | var response = {}; 578 | 579 | if (res.headers.get('content-type') !== 'image/gif') { 580 | response = res.json(); 581 | } else { 582 | response = res.text(); 583 | } 584 | 585 | if (res.status === 200) { 586 | return response; 587 | } 588 | 589 | return Promise.reject(new Error(response)); 590 | }).then(function (json) { 591 | if (_this.globalDebug) { 592 | if (json.hitParsingResult[0].valid) { 593 | return { 594 | clientID: formObj.cid 595 | }; 596 | } 597 | } 598 | 599 | return { 600 | clientID: formObj.cid 601 | }; 602 | })["catch"](function (err) { 603 | return new Error(err); 604 | }); 605 | } 606 | }]); 607 | 608 | return Analytics; 609 | }(); 610 | 611 | var _default = Analytics; 612 | exports["default"] = _default; --------------------------------------------------------------------------------