Skip to content

Instantly share code, notes, and snippets.

@mountainash
Last active October 24, 2023 19:00
Show Gist options
  • Save mountainash/94cc7bb56d6702e6d127c340e75c1419 to your computer and use it in GitHub Desktop.
Save mountainash/94cc7bb56d6702e6d127c340e75c1419 to your computer and use it in GitHub Desktop.
Aptabase website tracking using Cloudflare Zaraz
/**
*
> This Cloudfare Workers script takes a request from Zaraz
Use the Zaraz **HTTP Request Tool** with an endpoint set to the Worker URL running this script, with a trigger of **Pageview**, using the **POST JSON** method, with **Send all System and Client data** checked for each **pageView** and sends it to Aptabase's **HTTP API**.
Notes:
- Create an Environment Variable called `APATABASE_KEY` and set it to your API Key
- The endpoint is set to Europe, change to USA or self-hosted as needed
- toggle `isDebug` to `false` when you're ready to go live
**/
export default {
async fetch(request, env) {
// Get JSON sent to the body of this request
const readRequestBody = async (request) => await request.json();
// Extra the HREF, userAgent, bot score, and ip, city, region and country from the JSON payload
const getSelectedData = (reqBody) => {
const {
page,
device
} = reqBody;
return {
domain: page.url?.hostname,
path: page.url?.pathname,
userAgent: device.userAgent?.ua,
language: device.language,
ip: device.ip,
botScore: String(device.bot?.score),
location: `${device.location?.city}, ${device.location?.region}, ${device.location?.country}`,
};
};
const aptabaseDataFormat = (data) => {
const now = new Date();
const isoString = now.toISOString(); // eg 2023-10-23T15:16:47.366Z,
return {
timestamp: isoString,
sessionId: data.ip,
eventName: 'page_view',
systemProps: {
locale: data.language,
isDebug: true,
appVersion: '1.0.0',
sdkVersion: 'aptabase-web@fake'
},
props: JSON.stringify(data),
}
};
// Send the data to Aptabase's HTTP API
const sendData = async (data, env) => {
const url = 'https://eu.aptabase.com/api/v0/event';
const headers = {
'Content-Type': 'application/json',
'App-Key': env.APATABASE_KEY,
};
return await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(data),
});
}
if (request.method === 'POST') {
const reqBody = await readRequestBody(request);
// console.info(reqBody);
const selectData = getSelectedData(reqBody);
// console.info(selectData);
const aptabaseData = aptabaseDataFormat(selectData);
// console.info(aptabaseData);
const response = await sendData(aptabaseData, env);
if (!response.ok)
console.error(response);
return new Response('✅');
} else if (request.method === 'GET') {
return new Response('The request was a GET. Needs to be a POST.');
}
},
};
@mountainash
Copy link
Author

Linked from aptabase/aptabase#13

@mountainash
Copy link
Author

NOTE: this script, as-is is using IP address for session IP - which is not ideal (long-lived, may not be unique per user/session) and could have PII implications. Please change #L42 to sessionId: Math.floor(Math.random() * 100000000) [or similar] but it's likely all your sessions will be unique and unlinked for each hit. It depends on your expected use-case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment