集成 Google Analytics
在 <script>
即可为 Angela 启用 Google Analytics。
此外,通过
以下是一个示例实现,将全部代码复制到 extension.html
即可启用进阶 Google Analytics 集成:
<script type="module">
/** @import { Observable } from "rxjs" */
/** @import { User } from "../../../../../angela/src/app/core/user/user.model" */
/** @import { Plan } from "../../../../../angela/src/app/core/plan/plan.model" */
/**
* @typedef AngelaAccessPoints
* @property {() => Observable} watchCommands
* @property {(command) => object} readCommandMetadata
* @property {() => Observable} watchEvents
* @property {(event) => object} readEventMetadata
* @property {() => Observable<string>} queryAuthToken
* @property {() => Observable<User>} queryUser
* @property {() => Observable<Plan | null>} queryUserPlan
*/
/**
* @typedef {((...args: unknown[]) => void) & { adapted?: boolean }} GtagSdk
*/
/**
* @typedef {AngelaAccessPoints & { gtag?: GtagSdk; }} Global
*/
import * as mRxJS from 'https://cdn.skypack.dev/rxjs@7.8.1';
/**@returns {asserts v is Global} */
function typeAssertGlobal(v) {}
/**@returns {asserts m is typeof import("rxjs")} */
function typeAssertModuleRxJS(m) {}
typeAssertGlobal(window);
const global = window;
const { watchCommands, watchEvents, readCommandMetadata } = global;
typeAssertModuleRxJS(mRxJS);
const { timer, first, map, filter } = mRxJS;
timer(1000, 1000)
.pipe(
map(() => global.gtag),
first(Boolean),
)
.subscribe((gtag) => {
adaptGA(gtag);
gtag.adapted = true;
});
/**
*
* @param {GtagSdk} gtag
*/
function adaptGA(gtag) {
const commands$ = watchCommands();
const events$ = watchEvents();
commands$
.pipe(
filter((command) => {
const name = command.constructor.name;
const metadata = readCommandMetadata(command);
const isProcess = !!metadata.process;
return isProcess || name === 'Logout';
}),
)
.subscribe((command) => {
gtag('event', command.constructor.name, { ...command });
});
events$
.pipe(
filter((event) => {
const name = event.constructor.name;
return name === 'ProcessFailed' || name === 'QueryErrored';
}),
)
.subscribe((event) => {
gtag('event', 'exception', {
description: `[${event.constructor.name}] ${String(event.error)}`,
stack: event.error instanceof Error ? event.error.stack : null,
fatal: false,
});
});
}
</script>