Created
February 17, 2019 08:15
-
-
Save dustinrecko/e8e05c431a6c7c2a2b6e96f2602f4877 to your computer and use it in GitHub Desktop.
Deduping Google Analytics Transaction Hits - Cloudflare Worker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
addEventListener('fetch', event => { | |
if(event.request.url.indexOf('/collect') > -1) | |
event.waitUntil(process(event.request)) | |
event.respondWith(new Response('',{status:200})) | |
}) | |
/** | |
* CONFIG SECTION | |
*/ | |
const ANALYTICS_URL = 'https://www.google-analytics.com' | |
const FB_URL = 'https://<your-database-id>.firebaseio.com/transactions/'; | |
const FB_KEY = '<your-database-secret>'; | |
/** | |
* Process the hit, but only for transactions that haven't been seen before | |
* param {Request} Original Request | |
*/ | |
const process = async (request) => { | |
const url = new URL(request.url) | |
const transactionId = url.searchParams.get('ti') | |
const hitType = url.searchParams.get('t') | |
let entry = await lookup(transactionId) | |
let entryData = await entry.json() | |
if(entryData) | |
return (hitType != 'item') ? logDuplicateHit(transactionId,++entryData.hits) : Promise.resolve(1) | |
else { | |
return Promise.all([ | |
(hitType != 'item') ? logTransaction(transactionId) : Promise.resolve(1), | |
analyticsHit(decorateHitPayload(url,request.headers.get('CF-Connecting-IP'),encodeURIComponent(request.headers.get('user-agent')))) | |
]) | |
} | |
} | |
/** | |
* Check for transaction in Firebase database | |
* @param {string} Transaction ID | |
*/ | |
const lookup = async (id) => (fetch(FB_URL+id+'.json?auth='+FB_KEY)) | |
/** | |
* Log new transactions in Firebase database | |
* @param {string} Transaction ID | |
*/ | |
const logTransaction = async (id) => (fetch(new Request(FB_URL+id+'.json?auth='+FB_KEY, { | |
method: 'PUT', | |
headers: { | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify({ | |
createdAt: new Date().getTime(), | |
hits: 1 | |
}) | |
}))) | |
/** | |
* Increase hit count for duplicate transactions in Firebase database | |
* @param {string} Transaction ID | |
* @param {number} Hit Count | |
*/ | |
const logDuplicateHit = async (id,count) => (fetch(new Request(FB_URL+id+'.json?auth='+FB_KEY, { | |
method: 'PATCH', | |
headers: { | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify({ | |
hits: count | |
}) | |
}))) | |
/** | |
* Decorate the Analytics hit with client's IP and client's User Agent | |
* @param {URL} request url | |
* @param {string} User's IP | |
* @param {string} User's User Agent | |
*/ | |
const decorateHitPayload = (url,userIP,userAgent) => (url.pathname+url.search+'&ua='+userAgent+'&uip='+userIP) | |
/** | |
* Forward hit to Google Analytics | |
* @param {string} Hit Payload | |
*/ | |
const analyticsHit = async (hitPayload) => (fetch(ANALYTICS_URL+hitPayload)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment