weavefox/tracker
GitHub: weavefox/tracker
一款轻量级 Web 分析 SDK,支持用户访问追踪、事件埋点、设备指纹和离线队列,专为 AI 生成应用提供零配置接入体验。
Stars: 0 | Forks: 0
# Tracker SDK
[](https://github.com/weavefox/tracker/actions/workflows/build.yml)
[](https://www.npmjs.com/package/@weavefox/tracker)
[](https://bundlejs.com/?bundle=&name=weavefox-tracker)
[](LICENSE)
[](https://www.typescriptlang.org/)
[](https://www.npmjs.com/package/@weavefox/tracker)
一个轻量级的 Web 分析 SDK,用于跟踪用户访问和事件。
## ✨ 功能
- **Vibe Coding 友好** - 零配置,AI 生成的应用只需一行代码即可添加跟踪
- **设备指纹** - 基于 Canvas 的指纹用于访客识别
- **离线队列** - 将失败的请求存入本地存储并重试
- **自动 Pageview** - 自动跟踪页面访问
- **自定义事件** - 跟踪点击、错误和自定义操作
- **Session 跟踪** - 自动 Session 管理(30 分钟超时)
## 📦 安装
### CDN
```
```
### NPM
```
npm install @weavefox/tracker
```
```
import { init, track, setUserId } from '@weavefox/tracker';
init({
endpoint: 'https://your-api.com/api/v1/collect/event'
});
```
## 📖 API
| Method | 描述 |
|--------|-------------|
| `init(config)` | 初始化 tracker |
| `track(eventName, data)` | 跟踪自定义事件 |
| `trackPageview(data)` | 跟踪页面浏览 |
| `trackClick(selector, data)` | 自动跟踪元素上的点击 |
| `trackError(data)` | 跟踪 JavaScript 错误 |
| `setUserId(userId)` | 登录后设置用户 ID |
| `getFingerprint()` | 获取设备指纹 |
| `flush()` | 强制发送队列中的事件 |
## ⚙️ 配置
```
WFTK.init({
endpoint: 'required', // Full API URL (required)
appId: 'optional', // Your app identifier
autoPageview: true, // Auto track page views
debug: false, // Enable debug logs
enableQueue: true, // Enable offline queue
sessionTimeout: 1800000, // Session timeout in ms
maxEventsPerSession: 1000 // Max events per session
});
```
## 📄 请求格式
```
{
"appId": "abc123", // optional
"events": [{
"event": "pageview",
"timestamp": 1699999999999,
"nonce": "a1b2c3d4e5f6",
"fingerprint": "fp_xxx",
"data": {
"url": "https://example.com/page",
"title": "Page Title",
"referer": "https://google.com",
"sessionId": "sess_xxx",
"sessionStart": 1699999000000,
"visitCount": 1,
"deviceType": "desktop",
"browser": { "name": "Chrome", "version": "120" },
"os": "macOS",
"screen": "1920x1080",
"viewport": "1920x1080",
"language": "en-US"
}
}]
}
```
## 🖥️ 服务端实现
### Endpoint
```
POST /api/v1/collect/event
Content-Type: application/json
```
### App 识别
主要方法:使用请求体中的 `appId`。可选替代方案:通过请求来源(Referer/Host)进行识别。
```
// Method 1: From request body (recommended)
const appId = req.body.appId;
// Method 2: By Referer
const domain = new URL(req.headers.referer || '').hostname;
const appId = await getAppIdByDomain(domain);
```
### 必需功能
1. **时间戳验证**
- 拒绝超过 5 分钟的请求
- `if (now - event.timestamp > 5 * 60 * 1000) return 403;`
2. **Nonce 去重**
- 存储已使用的 nonce(Redis key:`nonce:{appId}:{nonce}`)
- TTL:24 小时
- `if (redis.exists(key)) return 409;`
3. **速率限制**
- 单个 IP:60 次请求/分钟
- 单个指纹:10000 个事件/天
4. **请求验证**
- 验证是否提供了 appId 或从请求来源识别
- 验证必填字段:`event`、`timestamp`、`nonce`、`fingerprint`
### 示例(Node.js + Express)
```
const express = require('express');
const app = express();
app.post('/api/v1/collect/event', async (req, res) => {
const { appId, events } = req.body;
if (!appId) {
return res.status(400).json({ error: 'appId required' });
}
for (const event of events) {
// Check timestamp
if (Date.now() - event.timestamp > 5 * 60 * 1000) {
continue; // Skip expired
}
// Check nonce (deduplication)
const nonceKey = `nonce:${appId}:${event.nonce}`;
if (await redis.setnx(nonceKey, 1)) {
await redis.expire(nonceKey, 86400);
} else {
continue; // Skip duplicate
}
// Store event
await saveEvent(appId, event);
}
res.json({ success: true });
});
```
## 📝 License
MIT
标签:TypeScript, Web分析, 安全插件, 数据可视化, 数据埋点, 暗色界面, 自动化攻击