replace splitbee and panelbear with fathom

This commit is contained in:
m5r 2022-07-02 01:49:12 +02:00
parent 06f0078dfd
commit a8491e28a5
13 changed files with 76 additions and 87 deletions

View File

@ -32,11 +32,7 @@ invariant(
typeof process.env.WEB_PUSH_VAPID_PUBLIC_KEY === "string", typeof process.env.WEB_PUSH_VAPID_PUBLIC_KEY === "string",
`Please define the "WEB_PUSH_VAPID_PUBLIC_KEY" environment variable`, `Please define the "WEB_PUSH_VAPID_PUBLIC_KEY" environment variable`,
); );
invariant(typeof process.env.SENTRY_DSN === "string", `Please define the "SENTRY_DSN" environment variable`); invariant(typeof process.env.FATHOM_SITE_ID === "string", `Please define the "FATHOM_SITE_ID" environment variable`);
invariant(
typeof process.env.PANELBEAR_SITE_ID === "string",
`Please define the "PANELBEAR_SITE_ID" environment variable`,
);
export default { export default {
app: { app: {
@ -51,8 +47,9 @@ export default {
secretAccessKey: process.env.AWS_SES_ACCESS_KEY_SECRET, secretAccessKey: process.env.AWS_SES_ACCESS_KEY_SECRET,
fromEmail: process.env.AWS_SES_FROM_EMAIL, fromEmail: process.env.AWS_SES_FROM_EMAIL,
}, },
panelBear: { fathom: {
siteId: process.env.PANELBEAR_SITE_ID, siteId: process.env.FATHOM_SITE_ID,
domain: process.env.FATHOM_CUSTOM_DOMAIN,
}, },
redis: { redis: {
url: process.env.REDIS_URL, url: process.env.REDIS_URL,

View File

@ -3,19 +3,13 @@ import { RemixBrowser } from "@remix-run/react";
import * as Sentry from "@sentry/browser"; import * as Sentry from "@sentry/browser";
import { Integrations } from "@sentry/tracing"; import { Integrations } from "@sentry/tracing";
declare global { if (window.shellphoneConfig.sentry.dsn) {
interface Window { Sentry.init({
shellphoneConfig: {
sentry: { dsn: string };
};
}
}
Sentry.init({
dsn: window.shellphoneConfig.sentry.dsn, dsn: window.shellphoneConfig.sentry.dsn,
tracesSampleRate: 1.0, tracesSampleRate: 1.0,
integrations: [new Integrations.BrowserTracing()], integrations: [new Integrations.BrowserTracing()],
}); });
}
hydrate(<RemixBrowser />, document); hydrate(<RemixBrowser />, document);

View File

@ -33,8 +33,8 @@ self.addEventListener("fetch", (event) => {
const url = new URL(event.request.url); const url = new URL(event.request.url);
const isSSERequest = event.request.headers.get("Accept") === "text/event-stream"; const isSSERequest = event.request.headers.get("Accept") === "text/event-stream";
const isOutsideRequest = !["localhost", "dev.shellphone.app", "www.shellphone.app"].includes(url.hostname); const isOutsideRequest = !["localhost", "dev.shellphone.app", "www.shellphone.app"].includes(url.hostname);
const isSplitbeeProxiedRequest = url.pathname.startsWith("/_hive") || url.pathname === "/bee.js";
if (isSSERequest || isOutsideRequest || isSplitbeeProxiedRequest) { if (isSSERequest || isOutsideRequest) {
return; return;
} }

View File

@ -0,0 +1,21 @@
import { useEffect } from "react";
import { useLocation } from "@remix-run/react";
import * as Fathom from "fathom-client";
export default function useFathom() {
const location = useLocation();
useEffect(() => {
const { fathom, app } = window.shellphoneConfig;
Fathom.load(fathom.siteId, {
spa: "history",
url: fathom.domain ? `https://${fathom.domain}/script.js` : undefined,
includedDomains: [app.baseUrl.replace("https://", "")],
});
}, []);
useEffect(() => {
console.log(`tracking ${location.pathname}`);
Fathom.trackPageview();
}, [location]);
}

View File

@ -1,21 +0,0 @@
import { useEffect } from "react";
import { useLocation } from "@remix-run/react";
import * as Panelbear from "@panelbear/panelbear-js";
import type { PanelbearConfig } from "@panelbear/panelbear-js";
export default function usePanelbear(siteId: string, config: PanelbearConfig = {}) {
const location = useLocation();
useEffect(() => {
Panelbear.load(siteId, {
scriptSrc: "/bear.js",
spaMode: "off",
autoTrack: false,
...config,
});
}, []);
useEffect(() => {
Panelbear.trackPageview();
}, [location]);
}

View File

@ -145,6 +145,7 @@ async function setTwilioCredentials(request: Request, formData: unknown) {
await Promise.all( await Promise.all(
phoneNumbers.map(async (phoneNumber) => { phoneNumbers.map(async (phoneNumber) => {
const phoneNumberId = phoneNumber.sid; const phoneNumberId = phoneNumber.sid;
logger.info(`Importing phone number with id=${phoneNumberId}`);
try { try {
await db.phoneNumber.create({ await db.phoneNumber.create({
data: { data: {
@ -166,6 +167,8 @@ async function setTwilioCredentials(request: Request, formData: unknown) {
}), }),
]); ]);
} catch (error: any) { } catch (error: any) {
logger.error(error);
if (error.code !== "P2002") { if (error.code !== "P2002") {
// if it's not a duplicate, it's a real error we need to handle // if it's not a duplicate, it's a real error we need to handle
throw error; throw error;

View File

@ -13,20 +13,30 @@ import {
} from "@remix-run/react"; } from "@remix-run/react";
import config from "~/config/config.server"; import config from "~/config/config.server";
import usePanelbear from "~/features/core/hooks/use-panelbear"; import useFathom from "~/features/core/hooks/use-fathom";
import Logo from "~/features/core/components/logo"; import Logo from "~/features/core/components/logo";
import styles from "./styles/tailwind.css"; import styles from "./styles/tailwind.css";
export const links: LinksFunction = () => [{ rel: "stylesheet", href: styles }]; export const links: LinksFunction = () => [{ rel: "stylesheet", href: styles }];
declare global {
interface Window {
shellphoneConfig: LoaderData["shellphoneConfig"];
}
}
type LoaderData = { type LoaderData = {
shellphoneConfig: { shellphoneConfig: {
sentry: { sentry: {
dsn: string; dsn?: string;
}; };
panelbear: { fathom: {
siteId: string; siteId: string;
domain?: string;
};
app: {
baseUrl: string;
}; };
}; };
}; };
@ -36,8 +46,12 @@ export const loader: LoaderFunction = () => {
sentry: { sentry: {
dsn: config.sentry.dsn, dsn: config.sentry.dsn,
}, },
panelbear: { fathom: {
siteId: config.panelBear.siteId, siteId: config.fathom.siteId,
domain: config.fathom.domain,
},
app: {
baseUrl: config.app.baseUrl,
}, },
}, },
}); });
@ -45,7 +59,7 @@ export const loader: LoaderFunction = () => {
export default function App() { export default function App() {
const { shellphoneConfig } = useLoaderData<LoaderData>(); const { shellphoneConfig } = useLoaderData<LoaderData>();
usePanelbear(shellphoneConfig.panelbear.siteId); useFathom();
return ( return (
<Document> <Document>
<Outlet /> <Outlet />
@ -136,7 +150,6 @@ const Document: FunctionComponent<PropsWithChildren<{}>> = ({ children }) => (
<body className="h-full"> <body className="h-full">
{children} {children}
<ScrollRestoration /> <ScrollRestoration />
<script async data-api="/_hive" src="/bee.js" />
<Scripts /> <Scripts />
<LiveReload /> <LiveReload />
</body> </body>

View File

@ -1,14 +0,0 @@
import type { ActionFunction } from "remix";
async function proxyHive(request: Request) {
const url = new URL(request.url);
const req = new Request("https://hive.splitbee.io" + url.pathname.replace("/_hive", ""), {
...request,
signal: null,
});
req.headers.set("x-country", request.headers.get("cf-ipcountry")!);
req.headers.set("x-real-ip", request.headers.get("x-real-ip")!);
return fetch(req);
}
export const action: ActionFunction = ({ request }) => proxyHive(request);

View File

@ -1,3 +0,0 @@
import type { LoaderFunction } from "remix";
export const loader: LoaderFunction = () => fetch("https://cdn.panelbear.com/analytics.js");

View File

@ -1,3 +0,0 @@
import type { LoaderFunction } from "remix";
export const loader: LoaderFunction = () => fetch("https://cdn.splitbee.io/sb.js");

22
package-lock.json generated
View File

@ -9,7 +9,6 @@
"@bull-board/express": "3.11.0", "@bull-board/express": "3.11.0",
"@headlessui/react": "1.6.4", "@headlessui/react": "1.6.4",
"@maizzle/framework": "3.7.3", "@maizzle/framework": "3.7.3",
"@panelbear/panelbear-js": "1.3.3",
"@prisma/client": "3.14.0", "@prisma/client": "3.14.0",
"@react-aria/interactions": "3.9.0", "@react-aria/interactions": "3.9.0",
"@remix-run/express": "1.5.1", "@remix-run/express": "1.5.1",
@ -28,6 +27,7 @@
"clsx": "1.1.1", "clsx": "1.1.1",
"compression": "1.7.4", "compression": "1.7.4",
"express": "4.18.1", "express": "4.18.1",
"fathom-client": "3.5.0",
"ioredis": "5.0.6", "ioredis": "5.0.6",
"isbot": "3.5.0", "isbot": "3.5.0",
"jotai": "1.7.0", "jotai": "1.7.0",
@ -3027,11 +3027,6 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0" "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
} }
}, },
"node_modules/@panelbear/panelbear-js": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@panelbear/panelbear-js/-/panelbear-js-1.3.3.tgz",
"integrity": "sha512-LsAxdlvdvyoQy04no/VsSMQd1i1qGFNMy328VG/BI5N5hQXIa8CZjCWNXuOjIMbJcltt7QjESMr6BgHuEeo5AA=="
},
"node_modules/@prisma/client": { "node_modules/@prisma/client": {
"version": "3.14.0", "version": "3.14.0",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.14.0.tgz", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.14.0.tgz",
@ -10270,6 +10265,11 @@
"reusify": "^1.0.4" "reusify": "^1.0.4"
} }
}, },
"node_modules/fathom-client": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/fathom-client/-/fathom-client-3.5.0.tgz",
"integrity": "sha512-BiRDS9Q9a8Zma0H717FWC5cvf545K/CsxBpxKT22TcSl1EbRhhlHWIJgrdeiQUfdorBK2ppy09TwMOhRsbos/A=="
},
"node_modules/fault": { "node_modules/fault": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz",
@ -24904,11 +24904,6 @@
"json-parse-even-better-errors": "^2.3.1" "json-parse-even-better-errors": "^2.3.1"
} }
}, },
"@panelbear/panelbear-js": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@panelbear/panelbear-js/-/panelbear-js-1.3.3.tgz",
"integrity": "sha512-LsAxdlvdvyoQy04no/VsSMQd1i1qGFNMy328VG/BI5N5hQXIa8CZjCWNXuOjIMbJcltt7QjESMr6BgHuEeo5AA=="
},
"@prisma/client": { "@prisma/client": {
"version": "3.14.0", "version": "3.14.0",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.14.0.tgz", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.14.0.tgz",
@ -30300,6 +30295,11 @@
"reusify": "^1.0.4" "reusify": "^1.0.4"
} }
}, },
"fathom-client": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/fathom-client/-/fathom-client-3.5.0.tgz",
"integrity": "sha512-BiRDS9Q9a8Zma0H717FWC5cvf545K/CsxBpxKT22TcSl1EbRhhlHWIJgrdeiQUfdorBK2ppy09TwMOhRsbos/A=="
},
"fault": { "fault": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz",

View File

@ -52,7 +52,6 @@
"@bull-board/express": "3.11.0", "@bull-board/express": "3.11.0",
"@headlessui/react": "1.6.4", "@headlessui/react": "1.6.4",
"@maizzle/framework": "3.7.3", "@maizzle/framework": "3.7.3",
"@panelbear/panelbear-js": "1.3.3",
"@prisma/client": "3.14.0", "@prisma/client": "3.14.0",
"@react-aria/interactions": "3.9.0", "@react-aria/interactions": "3.9.0",
"@remix-run/express": "1.5.1", "@remix-run/express": "1.5.1",
@ -71,6 +70,7 @@
"clsx": "1.1.1", "clsx": "1.1.1",
"compression": "1.7.4", "compression": "1.7.4",
"express": "4.18.1", "express": "4.18.1",
"fathom-client": "3.5.0",
"ioredis": "5.0.6", "ioredis": "5.0.6",
"isbot": "3.5.0", "isbot": "3.5.0",
"jotai": "1.7.0", "jotai": "1.7.0",

View File

@ -9,12 +9,14 @@ import logger from "~/utils/logger.server";
import { adminMiddleware, setupBullBoard } from "./queues"; import { adminMiddleware, setupBullBoard } from "./queues";
import { registerSentry, sentryLoadContext } from "./sentry-remix"; import { registerSentry, sentryLoadContext } from "./sentry-remix";
Sentry.init({ if (config.sentry.dsn) {
Sentry.init({
dsn: config.sentry.dsn, dsn: config.sentry.dsn,
integrations: [new Sentry.Integrations.Http({ tracing: true })], integrations: [new Sentry.Integrations.Http({ tracing: true })],
tracesSampleRate: 1.0, tracesSampleRate: 1.0,
environment: process.env.NODE_ENV, environment: process.env.NODE_ENV,
}); });
}
const app = express(); const app = express();
app.use((req, res, next) => { app.use((req, res, next) => {