@adwait12345/telemetry-express 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,142 @@
1
+ # `@adwait12345/telemetry-express`
2
+
3
+ Express middleware adapter for the Telemetry SDK. Detects bots and crawlers on every incoming request and sends tracking payloads to the Telemetry API.
4
+
5
+ ---
6
+
7
+ ## Requirements
8
+
9
+ - Express **4.x or later**
10
+ - Node.js **18+** (uses native `fetch`)
11
+ - A Telemetry account with a **Project ID** and **Server Secret**
12
+
13
+ ---
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @adwait12345/telemetry-express @adwait12345/telemetry-core
19
+ # or
20
+ pnpm add @adwait12345/telemetry-express @adwait12345/telemetry-core
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Setup
26
+
27
+ ```typescript
28
+ import express from "express";
29
+ import { telemetryMiddleware } from "@adwait12345/telemetry-express";
30
+
31
+ const app = express();
32
+
33
+ app.use(
34
+ telemetryMiddleware({
35
+ projectId: process.env.TELEMETRY_PROJECT_ID!,
36
+ apiUrl: process.env.TELEMETRY_API_URL,
37
+ serverSecret: process.env.TELEMETRY_SERVER_SECRET!,
38
+ debug: false,
39
+ })
40
+ );
41
+
42
+ app.get("/", (req, res) => {
43
+ res.send("Hello world");
44
+ });
45
+
46
+ app.listen(3000);
47
+ ```
48
+
49
+ ```bash
50
+ # .env
51
+ TELEMETRY_PROJECT_ID=your-project-id
52
+ TELEMETRY_API_URL=https://telemetry-uqd3.onrender.com
53
+ TELEMETRY_SERVER_SECRET=sk_...
54
+ ```
55
+
56
+ ---
57
+
58
+ ## How it works
59
+
60
+ 1. The middleware runs synchronously on every request
61
+ 2. The request is normalized (UA, IP, headers, HTTP version) and passed to `detectBot()`
62
+ 3. Express exposes the real `httpVersion` from the raw request — this improves detection accuracy (HTTP/1.0 is flagged as a bot signal)
63
+ 4. If a bot is detected (or `trackAll: true`), a fire-and-forget send is triggered
64
+ 5. `next()` is called immediately — the send **does not block** the response
65
+
66
+ ---
67
+
68
+ ## Configuration options
69
+
70
+ | Option | Type | Default | Description |
71
+ |--------|------|---------|-------------|
72
+ | `projectId` | `string` | **required** | Your Telemetry project ID |
73
+ | `serverSecret` | `string` | **required** | Your server secret key for API auth |
74
+ | `apiUrl` | `string` | hosted service | Override the API endpoint |
75
+ | `trackAll` | `boolean` | `false` | Track all requests, not just bots |
76
+ | `trackSearchBots` | `boolean` | `true` | Include Googlebot, Bingbot etc. |
77
+ | `ignorePaths` | `(string \| RegExp)[]` | — | Paths to skip entirely |
78
+ | `customBots` | `Array<{name, pattern, category?}>` | — | Add custom bot definitions |
79
+ | `debug` | `boolean` | `false` | Log detection results to the console |
80
+ | `authorizationHeader` | `string` | — | Fully custom `Authorization` header value |
81
+ | `headers` | `Record<string, string>` | — | Extra headers on every telemetry request |
82
+
83
+ ---
84
+
85
+ ## Examples
86
+
87
+ ### Skip health check and static routes
88
+
89
+ ```typescript
90
+ app.use(
91
+ telemetryMiddleware({
92
+ projectId: "...",
93
+ serverSecret: "sk_...",
94
+ ignorePaths: ["/health", "/ping", /^\/static\//],
95
+ })
96
+ );
97
+ ```
98
+
99
+ ### Track all visitors
100
+
101
+ ```typescript
102
+ app.use(
103
+ telemetryMiddleware({
104
+ projectId: "...",
105
+ serverSecret: "sk_...",
106
+ trackAll: true,
107
+ })
108
+ );
109
+ ```
110
+
111
+ ### Add custom bot definitions
112
+
113
+ ```typescript
114
+ app.use(
115
+ telemetryMiddleware({
116
+ projectId: "...",
117
+ serverSecret: "sk_...",
118
+ customBots: [
119
+ { name: "MyInternalCrawler", pattern: /my-crawler\/\d+/i, category: "scraper" },
120
+ ],
121
+ })
122
+ );
123
+ ```
124
+
125
+ ---
126
+
127
+ ## What gets tracked
128
+
129
+ | Field | Description |
130
+ |-------|-------------|
131
+ | `projectId` | Your project ID |
132
+ | `path` | Request path (from `req.originalUrl`) |
133
+ | `method` | HTTP method |
134
+ | `userAgent` | Full user-agent string |
135
+ | `ip` | Client IP (from `req.ip` or `x-forwarded-for`) |
136
+ | `isBot` | `true` / `false` |
137
+ | `botName` | Named bot e.g. `"GPTBot"`, or `null` |
138
+ | `botCategory` | e.g. `"ai-crawler"`, `"search"`, `"scraper"` |
139
+ | `confidence` | `"certain"` / `"high"` / `"medium"` / `"low"` |
140
+ | `detectionMethod` | `"ua-match"` / `"header-anomaly"` / `"http10"` / `"automation-header"` |
141
+ | `referrer` | Referrer header |
142
+ | `timestamp` | ISO 8601 UTC |
package/dist/index.js CHANGED
@@ -70,7 +70,10 @@ function telemetryMiddleware(config) {
70
70
  };
71
71
  (0, import_telemetry_core.sendToTelemetry)(payload, config).catch((err) => {
72
72
  if (config.debug) {
73
- console.error("[Telemetry Middleware] Failed to send to telemetry:", err);
73
+ console.error(
74
+ "[Telemetry Middleware] Failed to send to telemetry:",
75
+ err
76
+ );
74
77
  }
75
78
  });
76
79
  }
package/dist/index.mjs CHANGED
@@ -50,7 +50,10 @@ function telemetryMiddleware(config) {
50
50
  };
51
51
  sendToTelemetry(payload, config).catch((err) => {
52
52
  if (config.debug) {
53
- console.error("[Telemetry Middleware] Failed to send to telemetry:", err);
53
+ console.error(
54
+ "[Telemetry Middleware] Failed to send to telemetry:",
55
+ err
56
+ );
54
57
  }
55
58
  });
56
59
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adwait12345/telemetry-express",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Express middleware for Telemetry SDK - track AI bots and crawlers",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -12,8 +12,12 @@
12
12
  "types": "./dist/index.d.ts"
13
13
  }
14
14
  },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
15
19
  "dependencies": {
16
- "@adwait12345/telemetry-core": "0.1.0"
20
+ "@adwait12345/telemetry-core": ">=0.1.0"
17
21
  },
18
22
  "devDependencies": {
19
23
  "@types/express": "^4.17.21",
package/src/index.ts DELETED
@@ -1,83 +0,0 @@
1
- import { ServerTrackPayload } from "@adwait12345/telemetry-core";
2
-
3
- // Mocking some request structures here just so we can write the package
4
- import type { Request, Response, NextFunction } from "express";
5
- import {
6
- detectBot,
7
- extractAutomationHeaders,
8
- sendToTelemetry,
9
- type TelemetryConfig,
10
- type NormalizedRequest,
11
- } from "@adwait12345/telemetry-core";
12
-
13
- export function telemetryMiddleware(config: TelemetryConfig) {
14
- return function (req: Request, res: Response, next: NextFunction) {
15
- // 1. Normalize the request
16
- const userAgent = req.get("user-agent") || "";
17
- const ip = req.ip || (req.headers["x-forwarded-for"] as string) || "";
18
- const path = req.originalUrl || req.url;
19
-
20
- // Check ignore paths first
21
- if (config.ignorePaths) {
22
- for (const ignorePath of config.ignorePaths) {
23
- if (typeof ignorePath === "string" && path === ignorePath) {
24
- return next();
25
- } else if (ignorePath instanceof RegExp && ignorePath.test(path)) {
26
- return next();
27
- }
28
- }
29
- }
30
-
31
- const normalizedReq: NormalizedRequest = {
32
- userAgent,
33
- ip: Array.isArray(ip) ? ip[0] : ip.split(",")[0],
34
- path,
35
- method: req.method,
36
- referrer: req.get("referrer") || null,
37
- acceptLanguage: req.get("accept-language") || null,
38
- acceptEncoding: req.get("accept-encoding") || null,
39
- secFetchSite: req.get("sec-fetch-site") || null,
40
- httpVersion: req.httpVersion || null,
41
- automationHeaders: extractAutomationHeaders(req.headers as any),
42
- };
43
-
44
- // 2. Detect bots
45
- const result = detectBot(normalizedReq, config.customBots);
46
-
47
- // 3. Check if we should track
48
- const shouldTrackBot =
49
- result.isBot &&
50
- (config.trackSearchBots !== false || result.botCategory !== "search");
51
-
52
- if (config.trackAll || shouldTrackBot) {
53
- const payload: ServerTrackPayload = {
54
- projectId: config.projectId,
55
- path: normalizedReq.path,
56
- method: normalizedReq.method,
57
- referrer: normalizedReq.referrer,
58
- userAgent: normalizedReq.userAgent,
59
- ip: normalizedReq.ip,
60
- isBot: result.isBot,
61
- botName: result.botName,
62
- botCategory: result.botCategory,
63
- confidence: result.confidence,
64
- detectionMethod: result.method,
65
- source: "server-middleware",
66
- timestamp: new Date().toISOString(),
67
- };
68
-
69
- // Fire and forget
70
- sendToTelemetry(payload, config).catch((err: any) => {
71
- if (config.debug) {
72
- console.error(
73
- "[Telemetry Middleware] Failed to send to telemetry:",
74
- err,
75
- );
76
- }
77
- });
78
- }
79
-
80
- // Always continue the request
81
- next();
82
- };
83
- }
package/tsconfig.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "../../packages/core/tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "./dist",
5
- "rootDir": "./src"
6
- },
7
- "include": ["src/**/*"],
8
- "exclude": ["node_modules", "dist"]
9
- }