From 3b86d3c6324f9ae9a131e479ec5fc1ef34f83c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Sun, 29 Dec 2024 14:39:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20umami=20=E7=BB=9F=E8=AE=A1=E8=BF=BD?= =?UTF-8?q?=E8=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/umami.ts | 41 +++++++++++++++++++++++++++++++++++++++++ src/core/index.ts | 7 +++++++ src/framework/napcat.ts | 4 +++- src/shell/base.ts | 8 +++++--- 4 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 src/common/umami.ts diff --git a/src/common/umami.ts b/src/common/umami.ts new file mode 100644 index 00000000..cde1ff67 --- /dev/null +++ b/src/common/umami.ts @@ -0,0 +1,41 @@ +import https from 'node:https'; +import { napCatVersion } from './version'; + +export class umamiTrace { + static trackEvent(eventName: string, info?: string) { + const StatesData = { + type: 'event', + payload: { + 'website': '596cbbb2-1740-4373-a807-cf3d0637bfa7', + 'hostname': 'trace.napneko.icu', + 'language': process.env.LANG || 'en-US', + 'title': 'NapCat ' + napCatVersion, + 'url': '/' + napCatVersion + '/' + eventName, + 'referrer': 'https://trace.napneko.icu/' + napCatVersion, + 'info': info + } + }; + + let request = https.request({ + hostname: '104.19.42.72',// 固定 IP + port: 443, + path: '/api/send', + method: 'POST', + headers: { + "Host": "umami.napneko.icu", + "Content-Type": "application/json", + "User-Agent": `Mozilla/5.0 Umami/${process.version}` + } + }, (res) => { + res.on('error', (error) => { + + }); + res.on('data', (data) => { + + }); + }); + + request.write(JSON.stringify(StatesData)); + request.end(); + } +} \ No newline at end of file diff --git a/src/core/index.ts b/src/core/index.ts index 3cdf6158..cebc8550 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -30,6 +30,7 @@ import os from 'node:os'; import { NodeIKernelMsgListener, NodeIKernelProfileListener } from '@/core/listeners'; import { proxiedListenerOf } from '@/common/proxy-handler'; import { NTQQPacketApi } from './apis/packet'; +import { umamiTrace } from '@/common/umami'; export * from './wrapper'; export * from './types'; export * from './services'; @@ -152,7 +153,13 @@ export class NapCatCore { // Renamed from 'InitDataListener' async initNapCatCoreListeners() { const msgListener = new NodeIKernelMsgListener(); + msgListener.onKickedOffLine = (Info: KickedOffLineInfo) => { + if (this.context.workingEnv === NapCatCoreWorkingEnv.Framework) { + umamiTrace.trackEvent('framework/kickoff'); + } else { + umamiTrace.trackEvent('shell/kickoff'); + } // 下线通知 this.context.logger.logError('[KickedOffLine] [' + Info.tipsTitle + '] ' + Info.tipsDesc); this.selfInfo.online = false; diff --git a/src/framework/napcat.ts b/src/framework/napcat.ts index 1dfb92b5..78e27d0d 100644 --- a/src/framework/napcat.ts +++ b/src/framework/napcat.ts @@ -9,6 +9,7 @@ import { NodeIKernelLoginService } from '@/core/services'; import { NodeIQQNTWrapperSession, WrapperNodeApi } from '@/core/wrapper'; import { InitWebUi, WebUiConfig } from '@/webui'; import { NapCatOneBot11Adapter } from '@/onebot'; +import { umamiTrace } from '@/common/umami'; //Framework ES入口文件 export async function getWebUiUrl() { @@ -23,8 +24,9 @@ export async function NCoreInitFramework( ) { //在进入本层前是否登录未进行判断 console.log('NapCat Framework App Loading...'); - + umamiTrace.trackEvent('framework/login'); process.on('uncaughtException', (err) => { + umamiTrace.trackEvent('framework/error', err.message); console.log('[NapCat] [Error] Unhandled Exception:', err.message); }); process.on('unhandledRejection', (reason, promise) => { diff --git a/src/shell/base.ts b/src/shell/base.ts index 7c1d03c3..68963afd 100644 --- a/src/shell/base.ts +++ b/src/shell/base.ts @@ -29,9 +29,11 @@ import { InitWebUi } from '@/webui'; import { WebUiDataRuntime } from '@/webui/src/helper/Data'; import { napCatVersion } from '@/common/version'; import { NodeIO3MiscListener } from '@/core/listeners/NodeIO3MiscListener'; +import { umamiTrace } from '@/common/umami'; // NapCat Shell App ES 入口文件 async function handleUncaughtExceptions(logger: LogWrapper) { process.on('uncaughtException', (err) => { + umamiTrace.trackEvent('framework/error', err.message); logger.logError('[NapCat] [Error] Unhandled Exception:', err.message); }); process.on('unhandledRejection', (reason, promise) => { @@ -222,7 +224,7 @@ async function handleLogin( logger.log(`可用于快速登录的 QQ:\n${historyLoginList .map((u, index) => `${index + 1}. ${u.uin} ${u.nickName}`) .join('\n') - }`); + }`); } loginService.getQRCodePicture(); } @@ -266,7 +268,7 @@ export async function NCoreInitShell() { const pathWrapper = new NapCatPathWrapper(); const logger = new LogWrapper(pathWrapper.logsPath); handleUncaughtExceptions(logger); - + umamiTrace.trackEvent('shell/boot'); const basicInfoWrapper = new QQBasicInfoWrapper({ logger }); const wrapper = loadQQWrapper(basicInfoWrapper.getFullQQVesion()); @@ -297,7 +299,7 @@ export async function NCoreInitShell() { o3Service.reportAmgomWeather('login', 'a1', [dataTimestape, '0', '0']); const selfInfo = await handleLogin(loginService, logger, pathWrapper, quickLoginUin, historyLoginList); - + umamiTrace.trackEvent('shell/login'); const amgomDataPiece = 'eb1fd6ac257461580dc7438eb099f23aae04ca679f4d88f53072dc56e3bb1129'; o3Service.setAmgomDataPiece(basicInfoWrapper.QQVersionAppid, new Uint8Array(Buffer.from(amgomDataPiece, 'hex')));