数据埋点

This commit is contained in:
xu_yanfeng 2025-01-10 15:22:32 +08:00
parent 1907e59ba1
commit 7ff2613309
14 changed files with 201 additions and 8 deletions

View File

@ -38,6 +38,9 @@ const manifest: CocosPluginManifest = {
icon: {
"48": "./icons/48.png",
},
analysis: {
// googleAnalytics: "G-0S2X4Z1FE7",
},
chrome: {
version: 3,
pem: "./crx-key.pem",

View File

@ -2,7 +2,7 @@
"author": "cc-plugin",
"description": "cocos creator plugin",
"devDependencies": {
"@types/chrome": "0.0.133",
"@types/chrome": "0.0.293",
"@types/fs-extra": "9.0.1",
"@types/kind-of": "^6.0.0",
"@types/lodash": "^4.14.176",

View File

@ -0,0 +1,63 @@
import { GA_Button, GA_EventName, MeasurementBody } from "./type";
const API_SECRET = "_yU7eNTgT4Khe2Jo22Ki_g";
const MEASUREMENT_ID = "G-RW7J0JZ6T5";
const GA_ENDPOINT = "https://www.google-analytics.com/mp/collect";
export class GoogleAnalytics {
async getOrCreateSessionId() {
const result = await chrome.storage.local.get("clientId");
let clientId = result.clientId;
if (!clientId) {
clientId = self.crypto.randomUUID();
await chrome.storage.local.set({ clientId });
}
return clientId;
}
public async fireEventWithParam(name: GA_EventName, param: string) {
const time = Date.now();
const id = await this.getOrCreateSessionId();
fetch(`${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`, {
method: "POST",
body: JSON.stringify({
client_id: id,
events: [
{
name: name,
params: {
id: param,
session_id: time.toString(),
engagement_time_msec: time.toString(),
},
},
],
} as MeasurementBody),
});
}
public async fireEvent(name: string) {
const time = Date.now();
const id = await this.getOrCreateSessionId();
fetch(`${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`, {
method: "POST",
body: JSON.stringify({
client_id: id,
events: [
{
name: name,
params: {
session_id: time.toString(),
engagement_time_msec: time.toString(),
},
},
],
} as MeasurementBody),
});
}
async clickButton(btn: GA_Button) {
await this.fireEventWithParam(GA_EventName.ButtonClicked, btn);
}
async openView(view: string) {
await this.fireEventWithParam(GA_EventName.PageView, view);
}
}
export const ga = new GoogleAnalytics();

View File

@ -0,0 +1,89 @@
/**
*
*
* @doc https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?hl=zh-cn&client_type=gtag#payload_post_body
* @github https://github.dev/GoogleChrome/chrome-extensions-samples/blob/main/functional-samples/tutorial.google-analytics/scripts/google-analytics.js#L69
*/
export interface MeasurementBody {
/**
* ID
*/
client_id: string;
/**
* utf-8
*/
user_id?: string;
/**
* UNIX
*/
timestamp_micros?: number;
/**
*
*
* @doc https://developers.google.com/analytics/devguides/collection/protocol/ga4/user-properties?hl=zh-cn&client_type=gtag
*/
user_properties?: Object;
/**
*
*
*@doc https://developers.google.com/analytics/devguides/collection/ga4/uid-data?hl=zh-cn
*/
user_data?: Object;
/**
*
* @doc https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?hl=zh-cn&client_type=gtag#payload_consent
*/
consent?: Object;
/**
* 25
*/
events?: MeasurementEvent[];
}
export interface MeasurementEvent {
/**
*
*
* Google提供的事件 https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference/events?hl=zh-cn#add_payment_info
* https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?hl=zh-cn&client_type=gtag#reserved_event_names
*/
name: string;
/**
* https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?hl=zh-cn&client_type=gtag#reserved_parameter_names
*/
params?: {
[key: string]: any;
/**
*
*/
session_id?: string;
/**
*
*/
engagement_time_msec?: string;
};
}
export interface GA_Event_PageView extends MeasurementEvent {
name: "page_view";
params: {
page_title: string;
page_location: string;
};
}
export enum GA_EventName {
ButtonClicked = "button_clicked",
PageView = "page_view",
SpaceVisible = "space_visible",
MouseMenu = "mouse_menu",
Hierarchy = "hierarchy",
Inspector = "Inspector",
}
export enum GA_Button {
Github = "github",
Issues = "issues",
QQ = "qq",
/**
* cocos时
*/
FreshManual = "fresh-manual",
}

View File

@ -10,6 +10,8 @@
<script lang="ts">
import { defineComponent, ref } from "vue";
import { Msg, PluginEvent, ResponseSupportData } from "../../core/types";
import { ga } from "../../ga";
import { GA_Button } from "../../ga/type";
import { bridge } from "./bridge";
import { checkSupport } from "./util";
export default defineComponent({
@ -28,6 +30,7 @@ export default defineComponent({
return {
msg,
onBtnClickUpdatePage() {
ga.clickButton(GA_Button.FreshManual);
checkSupport();
},
};

View File

@ -17,6 +17,8 @@ import Mousetrap, { MousetrapInstance } from "mousetrap";
import { storeToRefs } from "pinia";
import { defineComponent, nextTick, onMounted, onUnmounted, ref, toRaw, watch } from "vue";
import { Msg, PluginEvent, RequestTreeInfoData, RequestUseFrameData, ResponseSetPropertyData } from "../../core/types";
import { ga } from "../../ga";
import { GA_EventName } from "../../ga/type";
import { bridge } from "./bridge";
import { Bus, BusMsg } from "./bus";
import { EngineData, TreeData } from "./data";
@ -43,6 +45,7 @@ export default defineComponent({
});
let ins: MousetrapInstance | null = null;
function onQuickVisible() {
ga.fireEvent(GA_EventName.SpaceVisible);
console.log("onQuickVisible");
if (selectedUUID) {
bridge.send(Msg.RequestVisible, selectedUUID);
@ -160,10 +163,12 @@ export default defineComponent({
onNodeExpand(data: TreeData) {
if (data.id) {
expandedKeys.value.push(data.id);
ga.fireEventWithParam(GA_EventName.Hierarchy, "node expand");
}
},
onNodeCollapse(data: TreeData) {
if (data.id) {
ga.fireEventWithParam(GA_EventName.Hierarchy, "node collapse");
const keys = toRaw(expandedKeys.value);
const index = keys.findIndex((el) => el === data.id);
if (index !== -1) {
@ -191,6 +196,7 @@ export default defineComponent({
name: "update hierarchy",
enabled: true,
callback: () => {
ga.fireEventWithParam(GA_EventName.MouseMenu, "update hierarchy");
updateTree();
},
});
@ -199,6 +205,7 @@ export default defineComponent({
name: "visible (sapce)",
enabled: true,
callback: () => {
ga.fireEventWithParam(GA_EventName.MouseMenu, "visible");
onQuickVisible();
},
});
@ -206,6 +213,7 @@ export default defineComponent({
name: "destroy",
enabled: true,
callback: () => {
ga.fireEventWithParam(GA_EventName.MouseMenu, "destroy");
bridge.send(Msg.RequestDestroy, selectedUUID);
},
});

View File

@ -29,7 +29,9 @@ import { Option } from "@xuyanfeng/cc-ui/types/cc-select/const";
import { storeToRefs } from "pinia";
import { defineComponent, onMounted, onUnmounted, ref, toRaw } from "vue";
import PluginConfig from "../../../cc-plugin.config";
import { Msg, PluginEvent, RequestUseFrameData, ResponseSupportData, ResponseUseFrameData } from "../../core/types";
import { Msg, Page, PluginEvent, RequestUseFrameData, ResponseSupportData, ResponseUseFrameData } from "../../core/types";
import { ga } from "../../ga";
import { GA_Button } from "../../ga/type";
import { bridge } from "./bridge";
import { Bus, BusMsg } from "./bus";
import { FrameDetails, NodeInfoData, TreeData } from "./data";
@ -53,6 +55,7 @@ export default defineComponent({
name: "devtools",
props: {},
setup(props, ctx) {
ga.openView(Page.Devtools);
appStore().init();
const isShowDebug = ref<boolean>(false);
const iframes = ref<Array<FrameInfo>>([]);
@ -71,18 +74,21 @@ export default defineComponent({
icon: "github",
cb: () => {
window.open("https://github.com/tidys/cc-inspector-chrome");
ga.clickButton(GA_Button.Github);
},
});
ccui.footbar.registerCmd({
icon: "qq",
cb: () => {
window.open("https://jq.qq.com/?_wv=1027&k=5SdPdy2");
ga.clickButton(GA_Button.QQ);
},
});
ccui.footbar.registerCmd({
icon: "support",
cb: () => {
window.open("https://github.com/tidys/cc-inspector-chrome/issues");
ga.clickButton(GA_Button.Issues);
},
});
Bus.on(BusMsg.EnableSchedule, funcEnableSchedule);

View File

@ -17,6 +17,8 @@ import { Bus, BusMsg } from "./bus";
import { NodeInfoData } from "./data";
import { Timer } from "./timer";
import Properties from "./ui/propertys.vue";
import { ga } from "../../ga";
import { GA_EventName } from "../../ga/type";
const { CCDock } = ccui.components;
export default defineComponent({
components: { Properties, CCDock },
@ -89,12 +91,14 @@ export default defineComponent({
name: "update node info",
callback: () => {
updateNodeInfo();
ga.fireEventWithParam(GA_EventName.MouseMenu, "update node info");
},
});
menus.push({
name: simpleProperties ? "show more properties" : "show simple properties",
callback: () => {
simpleProperties = !simpleProperties;
ga.fireEventWithParam(GA_EventName.MouseMenu, "simple/more properties");
},
});
ccui.menu.showMenuByMouseEvent(evnet, menus);

View File

@ -8,6 +8,8 @@
<script lang="ts">
import { defineComponent, PropType, toRaw } from "vue";
import { ga } from "../../../ga";
import { GA_EventName } from "../../../ga/type";
import { Bus, BusMsg } from "../bus";
import { CompType } from "../comp";
import { EngineData } from "../data";
@ -23,6 +25,7 @@ export default defineComponent({
setup(props, context) {
return {
onPlaceInTree() {
ga.fireEventWithParam(GA_EventName.Inspector, BusMsg.ShowPlace);
Bus.emit(BusMsg.ShowPlace, toRaw(props.data));
},
getEngineTypeIcon() {

View File

@ -26,6 +26,8 @@ import { Bus, BusMsg } from "../bus";
import { BoolData, Group, Info, Property } from "../data";
import UiProp from "./ui-prop.vue";
import { VisibleProp } from "../comp";
import { ga } from "../../../ga";
import { GA_EventName } from "../../../ga/type";
const { CCInput, CCSection, CCButton, CCInputNumber, CCSelect, CCCheckBox, CCColor } = ccui.components;
export default defineComponent({
name: "property-group",
@ -72,11 +74,13 @@ export default defineComponent({
fold,
visible,
onChangeVisible(b: boolean) {
ga.fireEventWithParam(GA_EventName.Inspector, "group-visible");
const raw: BoolData = toRaw<Info>(visibleTarget.value) as BoolData;
raw.data = b;
bridge.send(Msg.RequestSetProperty, raw as RequestSetPropertyData);
},
onLog() {
ga.fireEventWithParam(GA_EventName.Inspector, "group-log");
const raw = toRaw(props);
const data = [raw.group.id];
bridge.send(Msg.RequestLogData, data as RequestLogData);

View File

@ -34,6 +34,8 @@ import ccui from "@xuyanfeng/cc-ui";
import { Option } from "@xuyanfeng/cc-ui/types/cc-select/const";
import { defineComponent, onMounted, PropType, ref, toRaw, watch } from "vue";
import { Msg, RequestLogData, RequestSetPropertyData } from "../../../core/types";
import { ga } from "../../../ga";
import { GA_EventName } from "../../../ga/type";
import { bridge } from "../bridge";
import { ArrayData, EngineData, EnumData, ImageData, Info, NumberData, ObjectData, Property, StringData, TextData, Vec2Data, Vec3Data } from "../data";
import Engine from "./property-engine.vue";
@ -123,6 +125,7 @@ export default defineComponent({
}
},
onClickFold(v: boolean) {
ga.fireEventWithParam(GA_EventName.Inspector, "expand/fold prop");
freshSubData(props.value);
},
onChangeValue() {
@ -132,6 +135,7 @@ export default defineComponent({
}
},
onLogToConsole() {
ga.fireEventWithParam(GA_EventName.Inspector, "log-circle-object");
const data = toRaw(props.value.path);
bridge.send(Msg.RequestLogData, data as RequestLogData);
},

View File

@ -15,10 +15,13 @@
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { Page } from "../../core/types";
import { ga } from "../../ga";
export default defineComponent({
name: "options",
components: {},
setup(props, ctx) {
ga.openView(Page.Options);
return {};
},
});

View File

@ -16,6 +16,8 @@ import ccui from "@xuyanfeng/cc-ui";
import CCP from "cc-plugin/src/ccp/entry-render";
import { ChromeConst } from "cc-plugin/src/chrome/const";
import { defineComponent, onMounted, ref } from "vue";
import { Page } from "../../core/types";
import { ga } from "../../ga";
const { CCInput, CCButton, CCInputNumber, CCSelect, CCCheckBox, CCColor } = ccui.components;
export default defineComponent({
name: "popup",
@ -28,6 +30,7 @@ export default defineComponent({
CCColor,
},
setup(props, ctx) {
ga.openView(Page.Popup);
const title = ref(CCP.manifest.name);
const version = ref(CCP.manifest.version);
let longConn: chrome.runtime.Port | null = null;

View File

@ -396,10 +396,10 @@
dependencies:
"@types/node" "*"
"@types/chrome@0.0.133":
version "0.0.133"
resolved "https://mirrors.cloud.tencent.com/npm/@types/chrome/-/chrome-0.0.133.tgz#9e1d55441584ba2d5274ca84db36427da9c5dc6e"
integrity sha512-G8uIUdaCTBILprQvQXBWGXZxjAWbkCkFQit17cdH3zYQEwU8f/etNl8+M7e8MRz9Xj8daHaVpysneMZMx8/ldQ==
"@types/chrome@0.0.293":
version "0.0.293"
resolved "https://mirrors.cloud.tencent.com/npm/@types/chrome/-/chrome-0.0.293.tgz#1494b081b91521d749d2a5e3602eae202729991a"
integrity sha512-pghCOLVHsnePWcMEHCxkAfMRx8qJWmj4lUoyF3ZpANniKz8AucIGLSld7smsrTdLUkk/p5JjOCGVDRdUDHx+uA==
dependencies:
"@types/filesystem" "*"
"@types/har-format" "*"
@ -1229,7 +1229,7 @@
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
"@xuyanfeng/cc-ui@file:.yalc/@xuyanfeng/cc-ui":
version "0.2.34"
version "0.2.36"
dependencies:
axios "^1.7.2"
chalk "^5.3.0"
@ -1943,7 +1943,7 @@ case-sensitive-paths-webpack-plugin@^2.3.0:
integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==
"cc-plugin@file:.yalc/cc-plugin":
version "2.1.68"
version "2.1.69"
dependencies:
"@babel/generator" "^7.16.8"
"@popperjs/core" "^2.11.6"