Implement analytics

This commit is contained in:
MassiveBox 2025-04-16 23:56:24 +02:00
parent fc4ce8e69e
commit fe32505873
Signed by: massivebox
GPG key ID: 9B74D3A59181947D
3 changed files with 91 additions and 8 deletions

46
src/analytics.ts Normal file
View file

@ -0,0 +1,46 @@
import {getBackend, getFrontend} from "siyuan";
import {JSON_MIME} from "@/const";
import packageJson from '../package.json' assert { type: 'json' };
export class Analytics {
private readonly enabled: boolean;
private static readonly ENDPOINT = 'https://stats.massive.box/api/send_noua';
private static readonly WEBSITE_ID = '0a1ebbc1-d702-4f64-86ed-f62dcde9b522';
constructor(enabled: boolean) {
this.enabled = enabled;
}
async sendEvent(name: string) {
if(!this.enabled) return;
const sendData = (name == 'load' || name == 'install') ?
{
'appVersion': window.navigator.userAgent.split(' ')[0],
'pluginVersion': packageJson.version,
'frontend': getFrontend(),
'backend': getBackend(),
'language': navigator.language,
} : {};
await fetch(Analytics.ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': JSON_MIME,
},
body: JSON.stringify({
type: 'event',
payload: {
website: Analytics.WEBSITE_ID,
name: name,
data: sendData,
},
})
})
}
}

View file

@ -5,7 +5,7 @@ import {SettingUtils} from "@/libs/setting-utils";
import {validateColor} from "@/helper";
type Options = {
autoResize: boolean,
autoResize: boolean
background: string
analytics: boolean
};
@ -15,12 +15,16 @@ export class PluginConfig {
private file: PluginFile;
options: Options;
private firstRun: boolean;
getFirstRun() { return this.firstRun }
constructor() {
this.file = new PluginFile(STORAGE_PATH, CONFIG_FILENAME, JSON_MIME);
}
async load() {
this.firstRun = false;
await this.file.loadFromSiYuanFS();
this.options = JSON.parse(this.file.getContent());
if(this.options == null) {
@ -32,8 +36,9 @@ export class PluginConfig {
this.options = {
autoResize: true,
background: "#000000",
analytics: true
analytics: true,
};
this.firstRun = true;
}
async save() {
@ -69,7 +74,11 @@ export class PluginConfigViewer {
this.settingUtils = new SettingUtils({
plugin: this.plugin,
callback: async (data) => {
this.config.setConfig(data);
this.config.setConfig({
analytics: data.analytics,
autoResize: data.autoResize,
background: data.background,
});
await this.config.save();
}
});
@ -95,7 +104,7 @@ export class PluginConfigViewer {
title: "Analytics",
description: `
Enable to send anonymous usage data to the developer.
<a href='https://massive.box'>Privacy</a>
<a href='https://s.massive.box/jsdraw-plugin-privacy'>Privacy</a>
`,
value: this.config.options.analytics,
type: 'checkbox'

View file

@ -9,10 +9,12 @@ import {
import {migrate} from "@/migration";
import {EditorManager, PluginEditor} from "@/editor";
import {PluginConfig, PluginConfigViewer} from "@/config";
import {Analytics} from "@/analytics";
export default class DrawJSPlugin extends Plugin {
config: PluginConfig;
analytics: Analytics;
async onload() {
@ -20,16 +22,15 @@ export default class DrawJSPlugin extends Plugin {
EditorManager.registerTab(this);
migrate()
this.config = new PluginConfig();
await this.config.load();
let configViewer = new PluginConfigViewer(this.config, this);
await configViewer.load();
await this.startConfig();
await this.startAnalytics();
this.protyleSlash = [{
id: "insert-drawing",
filter: ["Insert Drawing", "Add drawing", "whiteboard", "freehand", "graphics", "jsdraw"],
html: getMenuHTML("iconDraw", this.i18n.insertDrawing),
callback: (protyle: Protyle) => {
void this.analytics.sendEvent('create');
const fileID = generateRandomString();
const syncID = generateTimeString() + '-' + generateRandomString();
protyle.insert(getMarkdownBlock(fileID, syncID), true, false);
@ -44,6 +45,7 @@ export default class DrawJSPlugin extends Plugin {
icon: "iconDraw",
label: "Edit with js-draw",
click: () => {
void this.analytics.sendEvent('edit');
new EditorManager(new PluginEditor(ids.fileID, ids.syncID)).open(this)
}
})
@ -51,4 +53,30 @@ export default class DrawJSPlugin extends Plugin {
}
onunload() {
void this.analytics.sendEvent("unload");
}
uninstall() {
void this.analytics.sendEvent("uninstall");
}
private async startConfig() {
this.config = new PluginConfig();
await this.config.load();
let configViewer = new PluginConfigViewer(this.config, this);
await configViewer.load();
}
private async startAnalytics() {
this.analytics = new Analytics(this.config.options.analytics);
if(this.config.getFirstRun()) {
await this.config.save();
void this.analytics.sendEvent('install');
}else{
void this.analytics.sendEvent('load');
}
}
}