web-collect-events
Version:
An sdk for collecting events from web pages
246 lines (218 loc) • 7.04 kB
text/typescript
import getBrowserProfile from "./helpers/browserProfile";
import getDateTimeIndex from "./helpers/dateTimeIndex";
import getDomNodeProfile from "./helpers/domNodeProfile";
import { isNodeValid } from "./helpers/validNode";
import { postData } from "./helpers/api";
import getUserDetails from "./helpers/userId";
const BASE_URL = "http://localhost:8080";
interface IContext {
userId: string;
name: string;
email: string;
phone: string;
}
class GTETWebSDK {
// variables for scope
private isPushNotificationScope: boolean = false;
private isCustomEventScope: boolean = false;
// data storage
private _data: Record<string, any>[] = [];
constructor() {
this.checkScope();
this.initStorage();
console.log("GTETWebSDK started");
}
// initialize storage
initStorage() {
this._data = [];
}
// helper functions for data storage
private setData(value: any) {
this._data.push(value);
}
private getData() {
return this._data;
}
private removeData() {
this._data = [];
}
// function to check scope of functions allowed to user
private checkScope() {
this.isPushNotificationScope =
typeof window !== "undefined" && typeof navigator !== "undefined";
this.isCustomEventScope = typeof window !== "undefined";
}
handleDocumentClick(e: MouseEvent) {
const targetNode = e.target as HTMLElement;
console.log(targetNode);
if (isNodeValid(targetNode)) {
const data = {
event_name: "click",
event_data: {
browserProfile: getBrowserProfile(),
dateTimeIndex: getDateTimeIndex(),
userDetails: getUserDetails(),
domNodeProfile: getDomNodeProfile(e),
},
};
this.setData(data);
}
}
// function to register the user for services
registerUser(key: string) {
const url = `${BASE_URL || process.env.BASE_URL}/api/v1/register`;
if (!url) {
console.log("BASE_URL environment variable is not defined.");
return;
}
const headers = {
type: "application/json",
Authorization: `Bearer ${key}`,
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify({
user_id: localStorage.getItem("userId"),
}),
});
}
// function to send the event data to the server using sendBeacon method
sendEventData() {
const url = `${BASE_URL || process.env.BASE_URL}/api/v1/event`;
if (!url) {
console.log("BASE_URL environment variable is not defined.");
return;
}
const jwtToken = localStorage.getItem("jwtToken") || "";
const headers = {
type: "application/json",
Authorization: `Bearer ${jwtToken}`,
};
const formdata = new FormData();
const bData = this.getData();
formdata.append("headers", JSON.stringify(headers));
formdata.append("data", JSON.stringify(bData));
if (bData.length > 0) {
navigator.sendBeacon(`${url}`, formdata);
}
this.removeData();
}
// function to self analyze the page and send data to the server
selfAnalyze() {
if (this.isCustomEventScope) {
document.addEventListener("click", this.handleDocumentClick.bind(this)); // Bind the event handler
document.addEventListener(
"visibilitychange",
this.sendEventData.bind(this)
); // Bind the event handler
setInterval(this.sendEventData.bind(this), 60000); // Bind the method
console.log("Self analyze started");
} else {
console.log(
"This code is not running in a browser environment for selfAnalyze."
);
}
}
// function to custom event send data to the server
customEvent(eventName: string, data: any) {
if (this.isCustomEventScope) {
const dataObject = {
event_name: eventName,
event_data: data,
};
this.sendCustomEvent(dataObject);
} else {
console.log(
"This code is not running in a browser environment for customEvent."
);
}
}
sendCustomEvent(data: any) {
const url = `${BASE_URL || process.env.BASE_URL}/api/v1/event`;
if (!url) {
console.log("BASE_URL environment variable is not defined.");
return;
}
const jwtToken = localStorage.getItem("jwtToken") || "";
const headers = {
type: "application/json",
Authorization: `Bearer ${jwtToken}`,
};
const formdata = new FormData();
const bData = data
formdata.append("headers", JSON.stringify(headers));
formdata.append("data", JSON.stringify(bData));
navigator.sendBeacon(`${url}`, formdata);
}
// setContext function to set the context of the user
setContext(userContext: IContext) {
const url = `${BASE_URL || process.env.BASE_URL}/api/v1/user`;
if (!url) {
console.log("BASE_URL environment variable is not defined.");
return;
}
postData(url, userContext);
}
pushNotification(publicVapidKey: string, api: string, swfile: string) {
if (this.isPushNotificationScope) {
if ("serviceWorker" in navigator && "PushManager" in window) {
this.registerServiceWorker(swfile)
.then(() => this.sendSubscriptionToServer(publicVapidKey, api))
.catch((error) => console.error("Error:", error));
} else {
console.log(
"Service Worker or PushManager is not supported in this browser."
);
}
} else {
console.log(
"This code is not running in a browser environment for pushNotification."
);
}
}
async registerServiceWorker(swfile: string) {
try {
const register = await navigator.serviceWorker.register(`/${swfile}.js`, {
scope: "/",
});
console.log("Service Worker registered:", register);
} catch (error) {
console.error("Failed to register Service Worker:", error);
throw error;
}
}
async sendSubscriptionToServer(publicVapidKey: string, api: string) {
try {
const registration = await navigator.serviceWorker.ready;
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: this.urlBase64ToUint8Array(publicVapidKey),
});
await fetch(api, {
method: "POST",
body: JSON.stringify(subscription),
headers: {
"content-type": "application/json",
},
});
console.log("Push Sent...", JSON.stringify(subscription));
} catch (error) {
console.error("Failed to send subscription to the server:", error);
throw error;
}
}
urlBase64ToUint8Array(base64String: string) {
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, "+")
.replace(/_/g, "/");
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
}
export default GTETWebSDK;