From 7bfca6df07bad97d4519110ca03e0ba2f146e01a Mon Sep 17 00:00:00 2001 From: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sun, 9 Feb 2025 16:10:18 +0900 Subject: [PATCH] introduce analytics wrapper --- packages/frontend/src/analytics.ts | 103 +++++++++++++++++++++++++++ packages/frontend/src/boot/common.ts | 9 +++ 2 files changed, 112 insertions(+) create mode 100644 packages/frontend/src/analytics.ts diff --git a/packages/frontend/src/analytics.ts b/packages/frontend/src/analytics.ts new file mode 100644 index 0000000000..f19ba761ba --- /dev/null +++ b/packages/frontend/src/analytics.ts @@ -0,0 +1,103 @@ +import * as Misskey from 'misskey-js'; +import type { AnalyticsInstance, AnalyticsPlugin } from 'analytics'; + +/** + * analytics moduleを読み込まなくても動作するようにするためのラッパー + */ +class AnalyticsProxy implements AnalyticsInstance { + private analytics?: AnalyticsInstance; + + constructor(analytics?: AnalyticsInstance) { + if (analytics) { + this.analytics = analytics; + } + } + + public setAnalytics(analytics: AnalyticsInstance) { + if (this.analytics) { + throw new Error('Analytics instance already exists.'); + } + this.analytics = analytics; + } + + public identify(...args: Parameters) { + return this.analytics?.identify(...args) ?? Promise.resolve(); + } + + public track(...args: Parameters) { + return this.analytics?.track(...args) ?? Promise.resolve(); + } + + public page(...args: Parameters) { + return this.analytics?.page(...args) ?? Promise.resolve(); + } + + public user(...args: Parameters) { + return this.analytics?.user(...args) ?? Promise.resolve(); + } + + public reset(...args: Parameters) { + return this.analytics?.reset(...args) ?? Promise.resolve(); + } + + public ready(...args: Parameters) { + return this.analytics?.ready(...args) ?? function () { void 0; }; + } + + public on(...args: Parameters) { + return this.analytics?.on(...args) ?? function () { void 0; }; + } + + public once(...args: Parameters) { + return this.analytics?.once(...args) ?? function () { void 0; }; + } + + public getState(...args: Parameters) { + return this.analytics?.getState(...args) ?? Promise.resolve(); + } + + public get storage() { + return this.analytics?.storage ?? { + getItem: () => null, + setItem: () => void 0, + removeItem: () => void 0, + }; + } + + public get plugins() { + return this.analytics?.plugins ?? { + enable: (p, c) => Promise.resolve(c ? c() : void 0), + disable: (p, c) => Promise.resolve(c ? c() : void 0), + }; + } +} + +export const analytics = new AnalyticsProxy(); + +export async function initAnalytics(instance: Misskey.entities.MetaDetailed) { + + // アナリティクスプロバイダに関する設定がひとつもない場合は、アナリティクスモジュールを読み込まない + if (!instance.googleAnalyticsMeasurementId) { + return; + } + + const { default: Analytics } = await import('analytics'); + const plugins: AnalyticsPlugin[] = []; + + // Google Analytics + if (instance.googleAnalyticsMeasurementId) { + const { default: googleAnalytics } = await import('@analytics/google-analytics'); + + plugins.push(googleAnalytics({ + measurementIds: [instance.googleAnalyticsMeasurementId], + debug: _DEV_, + })); + } + + analytics.setAnalytics(Analytics({ + app: 'misskey', + version: _VERSION_, + debug: _DEV_, + plugins, + })); +} diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts index 1d8e40a12d..52be3cd81d 100644 --- a/packages/frontend/src/boot/common.ts +++ b/packages/frontend/src/boot/common.ts @@ -21,6 +21,7 @@ import { reloadChannel } from '@/scripts/unison-reload.js'; import { getUrlWithoutLoginId } from '@/scripts/login-id.js'; import { getAccountFromId } from '@/scripts/get-account-from-id.js'; import { deckStore } from '@/ui/deck/deck-store.js'; +import { analytics, initAnalytics } from '@/analytics.js'; import { miLocalStorage } from '@/local-storage.js'; import { fetchCustomEmojis } from '@/custom-emojis.js'; import { setupRouter } from '@/router/main.js'; @@ -241,6 +242,14 @@ export async function common(createVue: () => App) { await fetchCustomEmojis(); } catch (err) { /* empty */ } + await fetchInstanceMetaPromise; + + await initAnalytics(instance); + + if ($i) { + analytics.identify($i.id); + } + const app = createVue(); setupRouter(app, createMainRouter);