Skip to content

Commit

Permalink
use measurement protocol to get at least some statistics of usage.
Browse files Browse the repository at this point in the history
  • Loading branch information
MayGo committed Jul 20, 2023
1 parent 7e316f0 commit 84b6da0
Show file tree
Hide file tree
Showing 15 changed files with 218 additions and 49 deletions.
3 changes: 2 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"match-sorter": "^6.3.1",
"moment": "^2.29.4",
"moment-duration-format": "2.3.2",
"querystring": "^0.2.1",
"randomcolor": "^0.6.2",
"react": "^18.2.0",
"react-color-palette": "^6.2.0",
Expand Down Expand Up @@ -55,7 +56,7 @@
"@testing-library/user-event": "^14.4.3",
"@types/jest": "^29.2.2",
"@types/lodash.throttle": "^4.1.7",
"@types/node": "^18.11.9",
"@types/node": "^20.4.2",
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.8",
"@types/webpack-env": "1.18.0",
Expand Down
6 changes: 0 additions & 6 deletions client/src/components/AuthButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import React, { useState } from 'react';
import * as yup from 'yup';
import { Input, Button, Center, Text, Box } from '@chakra-ui/react';
import { FormControl, FormErrorMessage } from '@chakra-ui/form-control';
import ReactGA from 'react-ga4';
import { FormProvider, useForm, useFormContext } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { setEmailToLocalStorage } from './Paywall/Paywall.utils';
Expand Down Expand Up @@ -136,11 +135,6 @@ export const AuthButton = ({ isRestore }) => {
const { handleSubmit } = methods;

const onSubmitFn = async (values: LoginFormInputs) => {
ReactGA.event({
category: 'Paywall',
action: `User pressed Login`,
});

try {
await sendEmail(values.email);
setEmailToLocalStorage(values.email);
Expand Down
14 changes: 1 addition & 13 deletions client/src/components/Paywall/Paywall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Loader } from '../Loader';
import { UserContext } from './UserProvider';
import { auth, firestore } from '../../utils/firebase.utils';
import { APP_RETURN_URL } from './Paywall.utils';
import ReactGA from 'react-ga4';

import { useCollectionData } from 'react-firebase-hooks/firestore';
import { addDoc, collection, getDocs, onSnapshot, query, where } from 'firebase/firestore';

Expand Down Expand Up @@ -83,11 +83,6 @@ const AddSubsciptionButton: React.FC<any> = () => {
}

try {
ReactGA.event({
category: 'Paywall',
action: `User pressed Subscribe`,
});

setIsLoading(true);

const product = products?.find((item) => item.active);
Expand Down Expand Up @@ -183,13 +178,6 @@ export const Paywall: React.FC<any> = ({ children, ...rest }) => {
}
}, [firebaseUser]);

React.useEffect(() => {
ReactGA.event({
category: 'Paywall',
action: `User went to ${StepTexts[step]} step`,
});
}, [step]);

return (
<Box
borderRadius="lg"
Expand Down
8 changes: 0 additions & 8 deletions client/src/components/Paywall/PaywallOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,11 @@ import * as React from 'react';
import { Box, useMultiStyleConfig, Center } from '@chakra-ui/react';
import { Paywall } from './Paywall';
import { UserContext } from './UserProvider';
import ReactGA from 'react-ga4';

export const PaywallOverlay: React.FC<any> = ({ children, ...rest }) => {
const styles = useMultiStyleConfig('Paywall', {});
const { hasTrial, hasSubscription } = React.useContext(UserContext);

React.useEffect(() => {
ReactGA.event({
category: 'Paywall',
action: `Paywall overlay displayed!`,
});
}, []);

if (hasTrial || hasSubscription) {
return null;
}
Expand Down
87 changes: 87 additions & 0 deletions client/src/ga-measurement-protocol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { stringify } from 'querystring';
import { getMachineId } from './services/settings.api';

const trackingId: string = process.env.REACT_APP_TRACKING_ID || '';
const secretKey: string = process.env.REACT_APP_SECRET_KEY || '';

const config = {
measurementId: trackingId,
measurementSecret: secretKey,

measurementUrl: 'https://www.google-analytics.com/mp/collect',
measurementUrlDebug: 'https://www.google-analytics.com/debug/mp/collect',
clientId: null,
};

const getUrl = () =>
new URL(
`${config.measurementUrl}?${stringify({
measurement_id: config.measurementId,
api_secret: config.measurementSecret,
})}`,
);

/**
* Tracks an analytics event via measurement protocol,
* i.e. via API.
*
* @param name the event name.
*
* @param params the event parameters.
*
* @param clientId the clientId for this event. Generated if not supplied.
*/
export const sendEvent = async ({ name, params }: { name: string; params }) => {
const url = getUrl();

if (!config.clientId) {
const machineId = await getMachineId();
config.clientId = machineId;
}

return fetch(url, {
method: 'POST',
body: JSON.stringify({
client_id: config.clientId,
non_personalized_ads: true,

events: [
{
name,
params,
},
],
}),
});
};

export const setUserProperty = async (name, value) => {
const url = getUrl();

if (!config.clientId) {
const machineId = await getMachineId();
config.clientId = machineId;
}

return fetch(url, {
method: 'POST',
body: JSON.stringify({
client_id: config.clientId,
user_properties: {
[name]: {
value,
},
},
}),
});
};

export const pageView = ({ location, title }) => {
return sendEvent({
name: 'page_view',
params: {
page_title: title,
page_location: location,
},
});
};
14 changes: 2 additions & 12 deletions client/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,11 @@ import { ChakraProvider, ColorModeScript } from '@chakra-ui/react';
import { mainStore } from './store/mainStore';
import '@fontsource/inter';
import { theme } from './theme/theme';
import ReactGA from 'react-ga4';
import { setAppParams } from './useGoogleAnalytics.utils';

const isDev = process.env.NODE_ENV !== 'production';

const trackingId: string = process.env.REACT_APP_TRACKING_ID || '';

ReactGA.initialize(trackingId);

ReactGA.set({
appVersion: process.env.REACT_APP_VERSION,
anonymizeIp: true,
checkProtocolTask: null,
checkStorageTask: null,
historyImportTask: null,
});
setAppParams();

(window as any).CSPSettings = {
nonce: 'nonce',
Expand Down
7 changes: 2 additions & 5 deletions client/src/routes/TrayAppPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { OnlineChart } from '../components/TrayLayout/OnlineChart';
import { useStoreActions, useStoreState } from '../store/easyPeasy';
import { useInterval } from '../hooks/intervalHook';
import { TrayItemEdit } from './tray/TrayItemEdit';
import ReactGA from 'react-ga4';
import { sendOpenTrayEvent } from '../useGoogleAnalytics.utils';

const EMPTY_ARRAY = [];
const BG_SYNC_DELAY_MS = 10000;
Expand Down Expand Up @@ -62,10 +62,7 @@ const TrayAppPageTemp = () => {
Logger.debug('Window active:', windowIsActive);
// loadLastLogItemsThrottled();

ReactGA.event({
category: 'Tray',
action: `Opened Tray`,
});
sendOpenTrayEvent();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [windowIsActive]);
Expand Down
4 changes: 4 additions & 0 deletions client/src/services/settings.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ export function getRunningLogItem() {
return EventEmitter.emit('getRunningLogItemAsJson');
}

export function getMachineId() {
return EventEmitter.emit('getMachineId');
}

export async function fetchWorkSettings() {
const jsonStr = await EventEmitter.emit('fetchWorkSettingsJsonString');
try {
Expand Down
7 changes: 4 additions & 3 deletions client/src/useGoogleAnalytics.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import ReactGA from 'react-ga4';

import { sendPageEvent } from './useGoogleAnalytics.utils';

export function useGoogleAnalytics() {
const location = useLocation();

useEffect(() => {
console.info('Setting page', location.pathname);
ReactGA.set({ path: location.pathname, search: location.search }); // Update the user's current page
ReactGA.send({ hitType: 'pageview', page: location.pathname });

sendPageEvent(location.pathname, location.search);
}, [location]);
}
14 changes: 14 additions & 0 deletions client/src/useGoogleAnalytics.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { pageView, sendEvent, setUserProperty } from './ga-measurement-protocol';

export function setAppParams() {
setUserProperty('app_version', process.env.REACT_APP_VERSION || '1.0.0');
}

export function sendPageEvent(path, search) {
setAppParams();
pageView({ location: path, title: path });
}

export function sendOpenTrayEvent() {
sendEvent({ name: 'open_tray', params: {} });
}
12 changes: 11 additions & 1 deletion client/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3581,11 +3581,16 @@
resolved "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz"
integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==

"@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0", "@types/node@^18.11.9":
"@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0":
version "18.11.9"
resolved "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz"
integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==

"@types/node@^20.4.2":
version "20.4.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9"
integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==

"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz"
Expand Down Expand Up @@ -9346,6 +9351,11 @@ qs@6.11.0:
dependencies:
side-channel "^1.0.4"

querystring@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd"
integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==

querystringify@^2.1.1:
version "2.2.0"
resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz"
Expand Down
1 change: 1 addition & 0 deletions electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"lodash": "^4.17.21",
"menubar": "9.2.3",
"moment": "2.29.4",
"node-machine-id": "^1.1.12",
"objection": "3.0.1",
"randomcolor": "0.6.2",
"sqlite3": "5.1.2",
Expand Down
4 changes: 4 additions & 0 deletions electron/src/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { State } from './enums/state';
import AppManager from './app-manager';
import { sendToTrayWindow, sendToNotificationWindow } from './window-manager';
import { initBackgroundJob } from './initBackgroundJob';
import { machineId } from 'node-machine-id';

const settingsActions = {
fetchAnalyserSettingsJsonString: async () => {
Expand Down Expand Up @@ -44,6 +45,9 @@ const settingsActions = {
notifyUser: async (payload) => {
sendToNotificationWindow('notifyUser', payload.message);
},
getMachineId: async () => {
return machineId(true);
},
};

const appSettingsActions = {
Expand Down
5 changes: 5 additions & 0 deletions electron/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5479,6 +5479,11 @@ node-int64@^0.4.0:
resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz"
integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==

node-machine-id@^1.1.12:
version "1.1.12"
resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267"
integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==

node-releases@^2.0.6:
version "2.0.6"
resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz"
Expand Down
Loading

0 comments on commit 84b6da0

Please sign in to comment.