Skip to content

Instantly share code, notes, and snippets.

@dustinrecko
Created February 17, 2019 08:15
Show Gist options
  • Save dustinrecko/e8e05c431a6c7c2a2b6e96f2602f4877 to your computer and use it in GitHub Desktop.
Save dustinrecko/e8e05c431a6c7c2a2b6e96f2602f4877 to your computer and use it in GitHub Desktop.
Deduping Google Analytics Transaction Hits - Cloudflare Worker
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