Skip to content
This repository was archived by the owner on Sep 12, 2019. It is now read-only.

Commit 30ba0c6

Browse files
author
sw-yx
committed
add GA, email, stripe, url shortener templates
1 parent 05ca7a5 commit 30ba0c6

18 files changed

+1325
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = {
2+
name: "google-analytics",
3+
description: "Google Analytics: proxy for GA on your domain to avoid adblock",
4+
async onComplete() {
5+
// your message here
6+
}
7+
};
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// with thanks to https://github.com/codeniko/simple-tracker/blob/master/examples/server-examples/aws-lambda/google-analytics.js
2+
const request = require("request");
3+
const querystring = require("querystring");
4+
const uuidv4 = require("uuid/v4");
5+
6+
const GA_ENDPOINT = `https://www.google-analytics.com/collect`;
7+
8+
// Domains to whitelist. Replace with your own!
9+
const originWhitelist = []; // keep this empty and append domains to whitelist using whiteListDomain()
10+
whitelistDomain("test.com");
11+
whitelistDomain("nfeld.com");
12+
13+
function whitelistDomain(domain, addWww = true) {
14+
const prefixes = ["https://", "http://"];
15+
if (addWww) {
16+
prefixes.push("https://www.");
17+
prefixes.push("http://www.");
18+
}
19+
prefixes.forEach(prefix => originWhitelist.push(prefix + domain));
20+
}
21+
22+
function proxyToGoogleAnalytics(event, done) {
23+
// get GA params whether GET or POST request
24+
const params =
25+
event.httpMethod.toUpperCase() === "GET"
26+
? event.queryStringParameters
27+
: JSON.parse(event.body);
28+
const headers = event.headers || {};
29+
30+
// attach other GA params, required for IP address since client doesn't have access to it. UA and CID can be sent from client
31+
params.uip = headers["x-forwarded-for"] || headers["x-bb-ip"] || ""; // ip override. Look into headers for clients IP address, as opposed to IP address of host running lambda function
32+
params.ua = params.ua || headers["user-agent"] || ""; // user agent override
33+
params.cid = params.cid || uuidv4(); // REQUIRED: use given cid, or generate a new one as last resort. Generating should be avoided because one user can show up in GA multiple times. If user refresh page `n` times, you'll get `n` pageviews logged into GA from "different" users. Client should generate a uuid and store in cookies, local storage, or generate a fingerprint. Check simple-tracker client example
34+
35+
console.info("proxying params:", params);
36+
const qs = querystring.stringify(params);
37+
38+
const reqOptions = {
39+
method: "POST",
40+
headers: {
41+
"Content-Type": "image/gif"
42+
},
43+
url: GA_ENDPOINT,
44+
body: qs
45+
};
46+
47+
request(reqOptions, (error, result) => {
48+
if (error) {
49+
console.info("googleanalytics error!", error);
50+
} else {
51+
console.info(
52+
"googleanalytics status code",
53+
result.statusCode,
54+
result.statusMessage
55+
);
56+
}
57+
});
58+
59+
done();
60+
}
61+
62+
exports.handler = function(event, context, callback) {
63+
const origin = event.headers["origin"] || event.headers["Origin"] || "";
64+
console.log(`Received ${event.httpMethod} request from, origin: ${origin}`);
65+
66+
const isOriginWhitelisted = originWhitelist.indexOf(origin) >= 0;
67+
console.info("is whitelisted?", isOriginWhitelisted);
68+
69+
const headers = {
70+
//'Access-Control-Allow-Origin': '*', // allow all domains to POST. Use for localhost development only
71+
"Access-Control-Allow-Origin": isOriginWhitelisted
72+
? origin
73+
: originWhitelist[0],
74+
"Access-Control-Allow-Methods": "GET,POST,OPTIONS",
75+
"Access-Control-Allow-Headers": "Content-Type,Accept"
76+
};
77+
78+
const done = () => {
79+
callback(null, {
80+
statusCode: 200,
81+
headers,
82+
body: ""
83+
});
84+
};
85+
86+
const httpMethod = event.httpMethod.toUpperCase();
87+
88+
if (event.httpMethod === "OPTIONS") {
89+
// CORS (required if you use a different subdomain to host this function, or a different domain entirely)
90+
done();
91+
} else if (
92+
(httpMethod === "GET" || httpMethod === "POST") &&
93+
isOriginWhitelisted
94+
) {
95+
// allow GET or POST, but only for whitelisted domains
96+
proxyToGoogleAnalytics(event, done);
97+
} else {
98+
callback("Not found");
99+
}
100+
};
101+
102+
/*
103+
Docs on GA endpoint and example params
104+
105+
https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide
106+
107+
v: 1
108+
_v: j67
109+
a: 751874410
110+
t: pageview
111+
_s: 1
112+
dl: https://nfeld.com/contact.html
113+
dr: https://google.com
114+
ul: en-us
115+
de: UTF-8
116+
dt: Nikolay Feldman - Software Engineer
117+
sd: 24-bit
118+
sr: 1440x900
119+
vp: 945x777
120+
je: 0
121+
_u: blabla~
122+
jid:
123+
gjid:
124+
cid: 1837873423.1522911810
125+
tid: UA-116530991-1
126+
_gid: 1828045325.1524815793
127+
gtm: u4d
128+
z: 1379041260
129+
*/

0 commit comments

Comments
 (0)