Skip to content

Commit e057f44

Browse files
authored
Draft to extend metrics with daily/monthly/yearly stats (#3)
* First draft to extend metrics with daily/monthly/yearly stats * Use TypeScript * Update `series` and `ranking` functions * Add types * Remove unused tests * Update README.md * Update dashboard * Update README.md * Use sls-analytics name again
1 parent 1e8f9f4 commit e057f44

File tree

17 files changed

+1505
-171
lines changed

17 files changed

+1505
-171
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ jspm_packages
44

55
# Serverless directories
66
.serverless
7+
build
78
dist
9+
10+
*.log

README.md

Lines changed: 73 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,33 @@
55

66
Example project for a personal [serverless](https://serverless.com) *Google Analytics* clone to track website visitors.
77

8-
After deploying the service you will have a HTTP endpoint using API Gateway that accepts requests and puts them into a Kinesis Stream. A Lambda function processes the stream and writes a basic metric about how many visitors you have per absolute URL to DynamoDB.
8+
After deploying the service you will have an HTTP endpoint using Amazon API Gateway that accepts requests and puts them into a Kinesis Stream. A Lambda function processes the stream and writes basic metrics about how many visitors you have per absolute URL to DynamoDB.
9+
10+
To access the tracked data, a basic dashboard with a JSON API is included as well. This should be a perfect starting point for you to create your own analytics service.
911

1012
## Components
1113

1214
#### Tracking Service
1315

1416
- Amazon Kinesis to stream visitor events
15-
- Amazon API Gateway as HTTP proxy for Kinesis
17+
- Amazon API Gateway for Kinesis HTTP proxy
1618
- Amazon DynamoDB for data storage
1719
- AWS Lambda to process visitor events
1820

19-
#### Examples
21+
#### Dashboard
22+
23+
- Amazon API Gateway for JSON API
24+
- [Dashboard w/ API to show metrics](http://sls-analytics-website-dashboard.s3-website-us-east-1.amazonaws.com/)
25+
26+
#### Example
2027

2128
- [Static website to track visitors](http://sls-analytics-website-example.s3-website-us-east-1.amazonaws.com)
22-
- [API & Dashboard to show metrics](http://sls-analytics-website-dashboard.s3-website-us-east-1.amazonaws.com/)
29+
30+
*The use of two API Gateways (data tracking and reading) is intended. You might have different settings for tracking and data access when you build something meaningful out of this example.*
2331

2432
## Configuration
2533

26-
All settings can be changes in the `serverless.yml` configuration file. You can easily change the DynamoDB Table, Kinesis Stream and API Gateway Resource names:
34+
All settings can be customized in the `serverless.yml` configuration file. You can easily change the DynamoDB Table, Kinesis Stream and API Gateway tracking resource name:
2735

2836
```yaml
2937
service: sls-analytics
@@ -38,13 +46,13 @@ custom:
3846
kinesis: ${self:service}-stream
3947
```
4048
41-
The S3 Bucket configuration is only needed for the included example website. If you don't need the example sites, have a look at the `scripts/deploy.sh` file and disable the deployment and remove the CloudFormation resources from the `serverless.yml` file.
49+
The S3 Bucket configuration is only needed for the included example website and dashboard. If you don't need the examples, have a look at the `scripts/deploy.sh` file and disable the deployment and remove the CloudFormation resources from the `serverless.yml` file.
4250

4351
*Amazon requires unique names for S3 buckets and other resources. Please rename at least the service before you try to deploy the example!*
4452

4553
## Deployment
4654

47-
Running `yarn deploy` will trigger a default [serverless](https://serverless.com) deployment. After the output of the CloudFormation Stack is available, the included static websites will be generated *(Using the hostname from the stack output)* and uploaded to the configured S3 buckets. As the final step, the deploy process will display the URL of the example website and data dashboard:
55+
Running `yarn deploy` will trigger a [serverless](https://serverless.com) deployment. After the output of your CloudFormation Stack is available, the included static websites will be generated *(using the hostname from the stack output)* and uploaded to the configured S3 buckets. As the last step, the deploy process will display the URLs of the example website and dashboard:
4856

4957
```bash
5058
# Install dependencies
@@ -58,46 +66,93 @@ Dashboard: http://sls-analytics-website-dashboard.s3-website-us-east-1.amazonaw
5866
Website: http://sls-analytics-website-example.s3-website-us-east-1.amazonaws.com/
5967
```
6068

61-
The **website** includes a simple HTML file, some stylings, and a few JavaScript lines that send a request to your API on every page load. Visit your URL, hit a few times the refresh button and take a look at the DynamoDB table or the **dashboard** URL.
69+
The **website** includes a simple HTML file, some stylings, and a few JavaScript lines that send a request to the tracking API on every page load. Open the URL in a web browser, hit a few times the refresh button and take a look at the DynamoDB table or the **dashboard** URL.
6270

6371
## Tracking
6472

65-
Basically tracking is nothing more than a HTTP request to the API Gateway with a set of payload information *(currently just `url` and `name`)*. Normally you would have a non-JS fallback, like an image e.g., but a simple `fetch` call does the job for now:
73+
Basically, tracking is nothing more than sending a HTTP request to the API with a set of payload information *(currently `url`, `date`, `name`, and a `websiteId`)*. Normally you would have an additional non-JS fallback, like an image e.g., but a simple `fetch` call does the job for now:
6674

6775
```js
6876
fetch(
6977
'https://n6q0egpreh.execute-api.us-east-1.amazonaws.com/v1/track',
7078
{
7179
method: "POST",
72-
body: JSON.stringify( { url: location.href, name: document.title } ),
73-
headers: new Headers(
80+
body: JSON.stringify(
7481
{
75-
"Content-Type": "application/json"
82+
date: new Date().getTime(),
83+
name: document.title,
84+
url: location.href,
85+
website: 'yfFbTv1GslRcIkUsWpa7'
7686
}
77-
)
87+
),
88+
headers: new Headers({ "Content-Type": "application/json" })
7889
}
7990
)
8091
```
8192

8293
## Data Access
8394

84-
You can get a list of all tracked data by invoking the `list` function, or just have a look into your DynamoDB or use the included dashboard.
95+
An example [dashboard to access tracked data](http://sls-analytics-website-dashboard.s3-website-us-east-1.amazonaws.com/) is included and deployed to S3. The URL will be displayed after the `deploy` task. You can access the metrics using basic `curl` requests as well. Just provide the `website` and `date` parameters:
96+
97+
### Top Content
98+
99+
The `ranking` resource scans the DynamoDB for pages with the most hits on a specific `date` value:
85100

86101
```bash
87-
$ > sls invoke -f list
102+
$ > curl https://p026537a2j.execute-api.us-east-1.amazonaws.com/dev/ranking?website=yfFbTv1GslRcIkUsWpa7&date=MONTH:2017-08
88103
89104
[
90105
{
91-
"name": "http://sls-analytics-website-example.s3-website-us-east-1.amazonaws.com/",
106+
"name": "Example Website - Serverless Analytics",
107+
"url": "http://sls-analytics-website.s3-website-us-east-1.amazonaws.com/baz",
108+
"value": 19
109+
},
110+
{
111+
"name": "Example Website - Serverless Analytics",
112+
"url": "http://sls-analytics-website.s3-website-us-east-1.amazonaws.com/",
92113
"value": 10
93114
},
94115
{
95-
"name": "http://sls-analytics-website-example.s3-website-us-east-1.amazonaws.com/?foo=bar",
96-
"value": 2
116+
"name": "Example Website - Serverless Analytics",
117+
"url": "http://sls-analytics-website.s3-website-us-east-1.amazonaws.com/bar",
118+
"value": 4
97119
}
98120
]
99121
```
100122

123+
### Requests per URL
124+
125+
The `series` resource scans the DynamoDB for data about a specific `url` in a given `date` period.
126+
127+
```bash
128+
$ > curl https://p026537a2j.execute-api.us-east-1.amazonaws.com/dev/series?website=yfFbTv1GslRcIkUsWpa7&date=HOUR:2017-08-25T13&url=http://sls-analytics-website.s3-website-us-east-1.amazonaws.com/baz
129+
130+
[
131+
{
132+
"date": "MINUTE:2017-08-25T13:33",
133+
"value": 1
134+
},
135+
{
136+
"date": "MINUTE:2017-08-25T13:37",
137+
"value": 1
138+
},
139+
{
140+
"date": "MINUTE:2017-08-25T13:46",
141+
"value": 14
142+
},
143+
{
144+
"date": "MINUTE:2017-08-25T13:52",
145+
"value": 1
146+
}
147+
]
148+
```
149+
150+
### Date Parameter
151+
152+
The DynamoDB stores the absolute hits number for the dimensions `YEAR`, `MONTH`, `DATE`, `HOUR`, and `MINUTE` per default. This may cause lots of write capacities when processing events, but with the [serverless-dynamodb-autoscaling](https://github.com/sbstjn/serverless-dynamodb-autoscaling) plugin DynamoDB will scale the capacities when needed.
153+
154+
All dates are UTC values!
155+
101156
## Infrastructure
102157

103158
![Infrastructure](infra.png)

package.json

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,33 @@
22
"license": "MIT",
33
"scripts": {
44
"build": "./scripts/build.sh",
5-
"deploy": "./scripts/deploy.sh"
5+
"deploy": "./scripts/deploy.sh",
6+
"lint": "tslint src/**/*.ts",
7+
"test": "jest test",
8+
"test:watch": "jest test --watch"
9+
},
10+
"jest": {
11+
"transform": {
12+
".*": "<rootDir>/node_modules/ts-jest/preprocessor.js"
13+
},
14+
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts)$",
15+
"moduleFileExtensions": [
16+
"ts",
17+
"js"
18+
]
619
},
720
"devDependencies": {
21+
"@types/node": "^8.0.25",
22+
"aws-sdk": "^2.104.0",
823
"ejs-cli": "^2.0.0",
24+
"jasmine-data-provider": "^2.2.0",
925
"node-sass": "^4.5.3",
1026
"s3sync-cli": "^2.0.0",
11-
"serverless": "^1.17.0",
27+
"serverless": "^1.20.2",
1228
"serverless-dynamodb-autoscaling": "^0.6.1",
13-
"serverless-stack-output": "0.2"
29+
"serverless-plugin-typescript": "^1.1.1",
30+
"serverless-stack-output": "^0.2.0",
31+
"ts-jest": "^20.0.10",
32+
"typescript": "^2.4.2"
1433
}
15-
}
34+
}

serverless.yml

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
service: sls-analytics
22

33
plugins:
4-
- serverless-stack-output
54
- serverless-dynamodb-autoscaling
5+
- serverless-plugin-typescript
6+
- serverless-stack-output
67

78
provider:
89
name: aws
@@ -19,10 +20,11 @@ provider:
1920

2021
custom:
2122
stage: ${opt:stage, self:provider.stage}
23+
website: yfFbTv1GslRcIkUsWpa7 # Random ID
2224
names:
2325
bucket:
24-
website: ${self:service}-website-example
25-
dashboard: ${self:service}-website-dashboard
26+
website: ${self:service}-website
27+
dashboard: ${self:service}-dashboard
2628
resource: track
2729
dynamodb: ${self:service}-data
2830
kinesis: ${self:service}-stream
@@ -31,11 +33,11 @@ custom:
3133
capacities:
3234
- table: DynamoDBTable
3335
read:
34-
minimum: 5
35-
maximum: 100
36+
minimum: 10
37+
maximum: 120
3638
write:
37-
minimum: 5
38-
maximum: 100
39+
minimum: 10
40+
maximum: 120
3941

4042
package:
4143
exclude:
@@ -52,14 +54,18 @@ package:
5254
- yarn.lock
5355

5456
functions:
55-
list:
56-
handler: src/list.get
57-
58-
route-list:
59-
handler: src/route/list.get
57+
series:
58+
handler: src/api/series.get
59+
events:
60+
- http:
61+
path: /series
62+
method: GET
63+
64+
ranking:
65+
handler: src/api/ranking.get
6066
events:
6167
- http:
62-
path: /list
68+
path: /ranking
6369
method: GET
6470

6571
process:
@@ -97,6 +103,9 @@ resources:
97103
Region:
98104
Description: AWS Region
99105
Value: { Ref: 'AWS::Region' }
106+
WebsiteID:
107+
Description: Website ID
108+
Value: ${self:custom.website}
100109

101110
Resources:
102111
KinesisStream:
@@ -110,11 +119,15 @@ resources:
110119
Properties:
111120
TableName: ${self:custom.names.dynamodb}
112121
AttributeDefinitions:
113-
- AttributeName: url
122+
- AttributeName: id
123+
AttributeType: S
124+
- AttributeName: date
114125
AttributeType: S
115126
KeySchema:
116-
- AttributeName: url
127+
- AttributeName: id
117128
KeyType: HASH
129+
- AttributeName: date
130+
KeyType: RANGE
118131
ProvisionedThroughput:
119132
ReadCapacityUnits: 5
120133
WriteCapacityUnits: 5
@@ -144,7 +157,7 @@ resources:
144157
BucketName: ${self:custom.names.bucket.website}
145158
WebsiteConfiguration:
146159
IndexDocument: index.html
147-
ErrorDocument: error.html
160+
ErrorDocument: index.html
148161

149162
BucketWebsitePolicy:
150163
Type: AWS::S3::BucketPolicy

sites/dashboard/index.ejs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<link href="/style.css" media="all" rel="stylesheet" />
88
</head>
99
<body>
10+
<div class="loader">Loading...</div>
1011
<div id="container">
1112
<table>
1213
<thead>
@@ -38,12 +39,13 @@
3839
item => '<tr><td><strong>' + item.name + '</strong><br />' + item.url + '</td><td>' + item.value + '</td></tr>'
3940
)
4041
42+
document.querySelector('.loader').style.display = 'none'
4143
document.querySelector('#data').innerHTML = rows.join('')
4244
document.querySelector('#container').classList.add('show')
4345
}
4446
4547
fetch(
46-
'<%=APIRootURL%>/<%=APIStageName%>/list'
48+
'<%=APIRootURL%>/<%=APIStageName%>/ranking?website=<%=WebsiteID%>&date=YEAR:2017'
4749
).then(
4850
res => res.json()
4951
).then(

sites/dashboard/style.scss

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,41 @@ footer {
104104
}
105105
}
106106
}
107+
108+
.loader {
109+
margin: 100px auto;
110+
font-size: 8px;
111+
width: 1em;
112+
height: 1em;
113+
border-radius: 50%;
114+
position: relative;
115+
text-indent: -9999em;
116+
-webkit-animation: load5 1.1s infinite ease;
117+
animation: load5 1.1s infinite ease;
118+
-webkit-transform: translateZ(0);
119+
-ms-transform: translateZ(0);
120+
transform: translateZ(0);
121+
}
122+
123+
@-webkit-keyframes load5 {
124+
0%,
125+
100% { box-shadow: 0em -2.6em 0em 0em #cccccc, 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2), 2.5em 0em 0 0em rgba(200, 200, 200, 0.2), 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.2), 0em 2.5em 0 0em rgba(200, 200, 200, 0.2), -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.2), -2.6em 0em 0 0em rgba(200, 200, 200, 0.5), -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.7); }
126+
12.5% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.7), 1.8em -1.8em 0 0em #cccccc, 2.5em 0em 0 0em rgba(200, 200, 200, 0.2), 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.2), 0em 2.5em 0 0em rgba(200, 200, 200, 0.2), -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.2), -2.6em 0em 0 0em rgba(200, 200, 200, 0.2), -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.5); }
127+
25% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.5), 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.7), 2.5em 0em 0 0em #cccccc, 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.2), 0em 2.5em 0 0em rgba(200, 200, 200, 0.2), -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.2), -2.6em 0em 0 0em rgba(200, 200, 200, 0.2), -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2); }
128+
37.5% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.2), 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.5), 2.5em 0em 0 0em rgba(200, 200, 200, 0.7), 1.75em 1.75em 0 0em #cccccc, 0em 2.5em 0 0em rgba(200, 200, 200, 0.2), -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.2), -2.6em 0em 0 0em rgba(200, 200, 200, 0.2), -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2); }
129+
50% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.2), 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2), 2.5em 0em 0 0em rgba(200, 200, 200, 0.5), 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.7), 0em 2.5em 0 0em #cccccc, -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.2), -2.6em 0em 0 0em rgba(200, 200, 200, 0.2), -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2); }
130+
62.5% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.2), 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2), 2.5em 0em 0 0em rgba(200, 200, 200, 0.2), 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.5), 0em 2.5em 0 0em rgba(200, 200, 200, 0.7), -1.8em 1.8em 0 0em #cccccc, -2.6em 0em 0 0em rgba(200, 200, 200, 0.2), -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2); }
131+
75% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.2), 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2), 2.5em 0em 0 0em rgba(200, 200, 200, 0.2), 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.2), 0em 2.5em 0 0em rgba(200, 200, 200, 0.5), -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.7), -2.6em 0em 0 0em #cccccc, -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2); }
132+
87.5% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.2), 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2), 2.5em 0em 0 0em rgba(200, 200, 200, 0.2), 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.2), 0em 2.5em 0 0em rgba(200, 200, 200, 0.2), -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.5), -2.6em 0em 0 0em rgba(200, 200, 200, 0.7), -1.8em -1.8em 0 0em #cccccc; }
133+
}
134+
@keyframes load5 {
135+
0%,
136+
100% { box-shadow: 0em -2.6em 0em 0em #cccccc, 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2), 2.5em 0em 0 0em rgba(200, 200, 200, 0.2), 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.2), 0em 2.5em 0 0em rgba(200, 200, 200, 0.2), -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.2), -2.6em 0em 0 0em rgba(200, 200, 200, 0.5), -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.7); }
137+
12.5% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.7), 1.8em -1.8em 0 0em #cccccc, 2.5em 0em 0 0em rgba(200, 200, 200, 0.2), 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.2), 0em 2.5em 0 0em rgba(200, 200, 200, 0.2), -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.2), -2.6em 0em 0 0em rgba(200, 200, 200, 0.2), -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.5); }
138+
25% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.5), 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.7), 2.5em 0em 0 0em #cccccc, 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.2), 0em 2.5em 0 0em rgba(200, 200, 200, 0.2), -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.2), -2.6em 0em 0 0em rgba(200, 200, 200, 0.2), -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2); }
139+
37.5% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.2), 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.5), 2.5em 0em 0 0em rgba(200, 200, 200, 0.7), 1.75em 1.75em 0 0em #cccccc, 0em 2.5em 0 0em rgba(200, 200, 200, 0.2), -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.2), -2.6em 0em 0 0em rgba(200, 200, 200, 0.2), -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2); }
140+
50% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.2), 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2), 2.5em 0em 0 0em rgba(200, 200, 200, 0.5), 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.7), 0em 2.5em 0 0em #cccccc, -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.2), -2.6em 0em 0 0em rgba(200, 200, 200, 0.2), -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2); }
141+
62.5% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.2), 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2), 2.5em 0em 0 0em rgba(200, 200, 200, 0.2), 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.5), 0em 2.5em 0 0em rgba(200, 200, 200, 0.7), -1.8em 1.8em 0 0em #cccccc, -2.6em 0em 0 0em rgba(200, 200, 200, 0.2), -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2); }
142+
75% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.2), 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2), 2.5em 0em 0 0em rgba(200, 200, 200, 0.2), 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.2), 0em 2.5em 0 0em rgba(200, 200, 200, 0.5), -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.7), -2.6em 0em 0 0em #cccccc, -1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2); }
143+
87.5% { box-shadow: 0em -2.6em 0em 0em rgba(200, 200, 200, 0.2), 1.8em -1.8em 0 0em rgba(200, 200, 200, 0.2), 2.5em 0em 0 0em rgba(200, 200, 200, 0.2), 1.75em 1.75em 0 0em rgba(200, 200, 200, 0.2), 0em 2.5em 0 0em rgba(200, 200, 200, 0.2), -1.8em 1.8em 0 0em rgba(200, 200, 200, 0.5), -2.6em 0em 0 0em rgba(200, 200, 200, 0.7), -1.8em -1.8em 0 0em #cccccc; }
144+
}

sites/website/index.ejs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,14 @@
3131
'<%=TrackingRootURL%>/<%=TrackingStageName%>/<%=TrackingResource%>',
3232
{
3333
method: "POST",
34-
body: JSON.stringify( { url: location.href, name: document.title } ),
34+
body: JSON.stringify(
35+
{
36+
date: new Date().getTime(),
37+
name: document.title,
38+
url: location.href,
39+
website: '<%=WebsiteID%>'
40+
}
41+
),
3542
headers: new Headers(
3643
{
3744
"Content-Type": "application/json"

0 commit comments

Comments
 (0)