From 41bcd70496d8cb4361b3836b2cce70e9ba02e23e Mon Sep 17 00:00:00 2001
From: vincanger <70215737+vincanger@users.noreply.github.com>
Date: Fri, 1 Dec 2023 12:43:40 +0100
Subject: [PATCH] update analytics
---
.env.server.example | 5 +++-
main.wasp | 13 +++++----
src/server/queries.ts | 2 --
src/server/workers/googleAnalyticsUtils.ts | 27 +++++++++----------
src/server/workers/plausibleAnalyticsUtils.ts | 8 +++---
src/shared/constants.ts | 2 +-
6 files changed, 28 insertions(+), 29 deletions(-)
diff --git a/.env.server.example b/.env.server.example
index 9f46ba4..d68e58a 100644
--- a/.env.server.example
+++ b/.env.server.example
@@ -29,8 +29,11 @@ SEND_EMAILS_IN_DEVELOPMENT=true
# (OPTIONAL) get your openai api key at https://platform.openai.com/account
OPENAI_API_KEY=
-# (OPTIONAL) get your plausible api key at https://plausible.io/login
+# (OPTIONAL) get your plausible api key at https://plausible.io/login or https://your-plausible-instance.com/login
PLAUSIBLE_API_KEY=
+# You will find your site id in the Plausible dashboard. It will look like 'opensaas.sh'
+PLAUSIBLE_SITE_ID=
+PLAUSIBLE_BASE_URL=https://plausible.io/api/v1 # if you are self-hosting plausible, change this to your plausible instance's base url
# (OPTIONAL) get your google service account key at https://console.cloud.google.com/iam-admin/serviceaccounts
GOOGLE_ANALYTICS_CLIENT_EMAIL=
diff --git a/main.wasp b/main.wasp
index 01d870e..1db0085 100644
--- a/main.wasp
+++ b/main.wasp
@@ -13,10 +13,10 @@ app SaaSTemplate {
"",
"",
// you can put your analytics scripts here
- "",
- // plausible has script extension `script.local.js` for local development
- "",
- // google analytics automatically detects if you are in dev mode and
+ "",
+ // plausible has script extension `script.local.js` for local development TODO: remove before deploying
+ "",
+ // google analytics only needs one script and will automatically detect if you are in dev mode
""
],
// 🔐 Auth out of the box! https://wasp-lang.dev/docs/auth/overview
@@ -355,9 +355,8 @@ job dailyStatsJob {
fn: import { calculateDailyStats } from "@server/workers/calculateDailyStats.js"
},
schedule: {
- // every hour
- // cron: "0 * * * *"
- cron: "* * * * *"
+ // cron: "0 * * * *" // every hour. use in production
+ cron: "* * * * *" // every minute. useful for debugging
},
entities: [User, DailyStats, Logs, PageViewSource]
}
diff --git a/src/server/queries.ts b/src/server/queries.ts
index 2d6cc58..a00dbe3 100644
--- a/src/server/queries.ts
+++ b/src/server/queries.ts
@@ -41,8 +41,6 @@ export const getDailyStats: GetDailyStats = async (_args
},
});
- console.log('dailyStats: ', dailyStats)
-
const weeklyStats = await context.entities.DailyStats.findMany({
orderBy: {
date: 'desc',
diff --git a/src/server/workers/googleAnalyticsUtils.ts b/src/server/workers/googleAnalyticsUtils.ts
index 8b2c586..70c2215 100644
--- a/src/server/workers/googleAnalyticsUtils.ts
+++ b/src/server/workers/googleAnalyticsUtils.ts
@@ -1,25 +1,23 @@
import { BetaAnalyticsDataClient } from '@google-analytics/data';
-const clientEmail = process.env.GOOGLE_ANALYTICS_CLIENT_EMAIL;
-// const privateKey =
-// '-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC0pLaSKNIJ4Lio\nTunlGK0T5a228onb8zrpF/i4TMlkHoRwtJFIj19Hvj6RiGRkNCP62x1AfFwiUVzd\nV8BuagsN+BwaxvW/gZS7JeDdB7W5G5w9wTmY75gWpVy034lUoTK1Oe+mpA1m9UG7\nXv/0iUcz88vubZWXDOlnYYm2EIVboONuKwJglaVzgvlNMkpZQHzomOwmCIs/6Ujr\ntOWL3ESUKgLSmLwv/NRwAYCa3DMQ3uYwKQT73ZlHgX8R4cqmvP2AwQIeBlM4pq4S\nhUsDPpFhHEbTBww4uLXaUETW8j26tAZKYq17NjoUnMx0eRW2kkEuOz9l8D/4297D\n9ARjpWRJAgMBAAECggEAAhE4fae176MAufxdNN/5axbfzA4ugbPg4rYBhKpsS5cF\n0PxgBUKOxpVoxeWXsIXgO4iyZwCFVWc09tuAOkNAaSKDv9KzEUP8Xb/rONxTuhCU\n0ygY7qUfSnMOAovkWHGX0PcexPtvo9P+spQ9vaCsje2mUc4zPg1JxoMZPlomDIxf\n38wPtTThJCwHc7uOg0BAof3vjF+zC6Vf1YYLiqlNhAC9E6aS8Np8CVXtpxRsJifn\nb5E6jBESK9PjrtPFdUtRcm7j2vohmLqCy+6ddwjwlCSxcpIky1QVlXNxmH/qkvKA\nK8vrLJlXeGuOb3ISsRrHSfY5J8fnFtol0Rec5Bag4QKBgQDjzl0xO6PnfuGRWs/d\nVfrZuuRmQvFx7kj9D04sC4NVwWuYFauh7RWt8nJwgbRdR3lHqTQ7JlUe4627y1PW\nOzffrbMY0Q3DiwLXj+mYbt2cfrHGqPxGYjeKJCMIvbHOzQ7NBacjtw/AflxsDqKx\n2Wzu//j0QISv2uH/zNESlsd2HQKBgQDLABT7uDMoxn4JIzEwqZTdzfASaSZQ1ppU\nbdm7Tug7hNVCU+orhgAa8k6ODCjH75uwdPrkstjzmQ303Zwxfw1llt1X8CICEqNR\nPS1Ptl+5H2wBcH8K96fFeGLO5CuWOmt/e1C19n3VJULQsh9jdj5yA2rfSI7DvfsC\nCnIjvKWfHQKBgQDR2WDJoIn9D0mVD5WZ68E33szVUud9rya3TukQ884ZKiMGJzhC\n4tZstYEsGJ9gqh2ToM/HiSkyWkPJUaU6HLT8rNLlknZeYmjMz/o8fCxTI/Z57WLv\nJzzIWT+Ypr3rpcPzozhzUwgEp6JVvCmtMYACrfPUdLaGFFjJvg/+Ur0NFQKBgGQ0\nMCdo72frQv+DrZ5VtzQdmamc2dsBc8DFULrS4nOuyA4rmeXOCXNDtF8NxXub3QAn\nXklRtyHXpTn/wj/0dUp2Q+BKmp7nUFKjniBA59NbnVbAjxV81gX1vOBfZNyNDc8p\nsdeASvDRqb+WjUPtdDmXUkPRbxdUSfjh6yGU1zRJAoGBALfUrbxg8t827HMa+xLH\nMvaBHqdQ6jhdjm51sOUfRBe2EOKQWug/Dnr+XlQKWN467JCWmKS0HfQY16BLIusQ\nUUc2dD+7jFTgtkvnSHvrbj+WX1Zl4tvkawxozu04Me83Fx2eYbxf0Ds5D4HiB04j\nn6O2YEStTVYy4ViSPGxTYKEI\n-----END PRIVATE KEY-----\n';
-const privateKey = Buffer.from(process.env.GOOGLE_ANALYTICS_PRIVATE_KEY!, 'base64').toString('utf-8');
+const CLIENT_EMAIL = process.env.GOOGLE_ANALYTICS_CLIENT_EMAIL;
+const PRIVATE_KEY = Buffer.from(process.env.GOOGLE_ANALYTICS_PRIVATE_KEY!, 'base64').toString('utf-8');
-const propertyId = process.env.GOOGLE_ANALYTICS_PROPERTY_ID;
+const PROPERTY_ID = process.env.GOOGLE_ANALYTICS_PROPERTY_ID;
const analyticsDataClient = new BetaAnalyticsDataClient({
credentials: {
- client_email: clientEmail,
- private_key: privateKey,
+ client_email: CLIENT_EMAIL,
+ private_key: PRIVATE_KEY,
},
});
export async function getSources() {
const [response] = await analyticsDataClient.runReport({
- property: `properties/${propertyId}`,
+ property: `properties/${PROPERTY_ID}`,
dateRanges: [
{
- startDate: 'yesterday',
+ startDate: '2020-01-01',
endDate: 'today',
},
],
@@ -27,7 +25,7 @@ export async function getSources() {
// get total page views
dimensions: [
{
- name: 'pageReferrer',
+ name: 'source',
},
],
metrics: [
@@ -39,6 +37,7 @@ export async function getSources() {
let activeUsersPerReferrer: any[] = [];
if (response?.rows) {
+ console.log('response.rows (sources): ', response.rows)
activeUsersPerReferrer = response.rows.map((row) => {
if (row.dimensionValues && row.metricValues) {
return {
@@ -66,7 +65,7 @@ export async function getDailyPageViews() {
async function getTotalPageViews() {
const [response] = await analyticsDataClient.runReport({
- property: `properties/${propertyId}`,
+ property: `properties/${PROPERTY_ID}`,
dateRanges: [
{
startDate: '2020-01-01', // go back to earliest date of your app
@@ -91,7 +90,7 @@ async function getTotalPageViews() {
async function getPrevDayViewsChangePercent() {
const [response] = await analyticsDataClient.runReport({
- property: `properties/${propertyId}`,
+ property: `properties/${PROPERTY_ID}`,
dateRanges: [
{
@@ -120,7 +119,7 @@ async function getPrevDayViewsChangePercent() {
],
});
- console.log('response: ', JSON.stringify(response?.rows, null, 2));
+ // console.log('response: ', JSON.stringify(response?.rows, null, 2));
let viewsFromYesterday;
let viewsFromDayBeforeYesterday;
@@ -140,7 +139,7 @@ async function getPrevDayViewsChangePercent() {
console.table({ viewsFromYesterday, viewsFromDayBeforeYesterday });
const change = ((viewsFromYesterday - viewsFromDayBeforeYesterday) / viewsFromDayBeforeYesterday) * 100;
- return change.toFixed(2);
+ return change.toFixed(0);
}
} else {
return '0';
diff --git a/src/server/workers/plausibleAnalyticsUtils.ts b/src/server/workers/plausibleAnalyticsUtils.ts
index f216791..502ed57 100644
--- a/src/server/workers/plausibleAnalyticsUtils.ts
+++ b/src/server/workers/plausibleAnalyticsUtils.ts
@@ -1,6 +1,6 @@
-const PLAUSIBLE_API_KEY = process.env.PLAUSIBLE_API_KEY!; // Replace with your Plausible API key
-const PLAUSIBLE_SITE_ID = 'localhost'; // Replace with your registered site ID with Plausible
-const PLAUSIBLE_BASE_URL = 'https://plausible.apps.twoducks.dev/api'; // This is a self-hosted Plausible instance. Replace with your own, or the cloud-based Plausible base URL (e.g. https://plausible.io/api)
+const PLAUSIBLE_API_KEY = process.env.PLAUSIBLE_API_KEY!;
+const PLAUSIBLE_SITE_ID = process.env.PLAUSIBLE_SITE_ID!;
+const PLAUSIBLE_BASE_URL = process.env.PLAUSIBLE_BASE_URL;
const headers = {
'Content-Type': 'application/json',
@@ -74,7 +74,7 @@ async function getPrevDayViewsChangePercent() {
} else {
change = ((pageViewsYesterday - pageViewsDayBeforeYesterday) / pageViewsDayBeforeYesterday) * 100;
}
- return change.toFixed(2);
+ return change.toFixed(0);
}
async function getPageviewsForDate(date: string) {
diff --git a/src/shared/constants.ts b/src/shared/constants.ts
index d93bb2a..e07a87d 100644
--- a/src/shared/constants.ts
+++ b/src/shared/constants.ts
@@ -7,7 +7,7 @@ export enum TierIds {
//get this link at https://dashboard.stripe.com/test/settings/billing/portal
const isDev = process.env.NODE_ENV === 'development';
const customerPortalTestUrl = 'https://billing.stripe.com/p/login/test_8wM8x17JN7DT4zC000';
-const customerPortalProdUrl = undefined;
+const customerPortalProdUrl = undefined; // TODO: add before deploying to production
export const STRIPE_CUSTOMER_PORTAL_LINK = isDev ? customerPortalTestUrl : customerPortalProdUrl;