@overpod/mcp-telegram 1.34.0 → 1.35.0
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/CHANGELOG.md +39 -0
- package/dist/rate-limiter.d.ts +4 -0
- package/dist/rate-limiter.js +30 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,45 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.35.0] — 2026-04-25
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
**Rate limiter — structured stderr events for retries.**
|
|
13
|
+
|
|
14
|
+
The internal `RateLimiter` previously logged `FLOOD_WAIT` and network retries as
|
|
15
|
+
human-readable strings via `console.error`, and the temporary-server-error
|
|
16
|
+
branch (5xx, etc.) was silent. All three retry branches now emit a single
|
|
17
|
+
structured stderr line per event:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
[rate-limiter] event {"event":"flood_wait","context":"list-chats","seconds":30,"attempt":1,"maxRetries":3}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Event types: `flood_wait`, `network_retry`, `temporary_retry`. Each event
|
|
24
|
+
carries:
|
|
25
|
+
|
|
26
|
+
- `event` — event class (string literal)
|
|
27
|
+
- `context` — caller-supplied operation name (never user input / PII)
|
|
28
|
+
- `attempt` / `maxRetries` — retry counters
|
|
29
|
+
- `seconds` (flood_wait only) or `delayMs` (network/temporary)
|
|
30
|
+
- `error` (network/temporary only) — the upstream Telegram error message
|
|
31
|
+
|
|
32
|
+
This is a logging contract change, not a behaviour change: retry timing,
|
|
33
|
+
backoff, and error-throwing semantics are identical to 1.34.0.
|
|
34
|
+
|
|
35
|
+
### Why this matters
|
|
36
|
+
|
|
37
|
+
Downstream log collectors can now aggregate retry rates by event class and
|
|
38
|
+
caller without parsing free-form English. `mcp-telegram-cloud` v1.12.0+ wires
|
|
39
|
+
this into SigNoz directly. Self-hosters can `grep '\[rate-limiter\] event'` or
|
|
40
|
+
pipe into any structured log pipeline.
|
|
41
|
+
|
|
42
|
+
### Compatibility
|
|
43
|
+
|
|
44
|
+
No breaking changes. No new dependencies. No new environment variables.
|
|
45
|
+
Tests: 490/490 pass.
|
|
46
|
+
|
|
8
47
|
## [1.34.0] — 2026-04-24
|
|
9
48
|
|
|
10
49
|
### Added
|
package/dist/rate-limiter.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Rate limiter and retry logic for Telegram API calls.
|
|
3
3
|
* Handles FLOOD_WAIT errors and implements exponential backoff.
|
|
4
|
+
*
|
|
5
|
+
* Emits structured events on stderr so downstream log collectors (e.g. cloud
|
|
6
|
+
* SigNoz) can aggregate by `event` and `context`. Format:
|
|
7
|
+
* [rate-limiter] event {"event":"flood_wait","context":"X","seconds":N,...}
|
|
4
8
|
*/
|
|
5
9
|
export interface RateLimiterOptions {
|
|
6
10
|
/** Maximum number of requests per second (default: 20) */
|
package/dist/rate-limiter.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Rate limiter and retry logic for Telegram API calls.
|
|
3
3
|
* Handles FLOOD_WAIT errors and implements exponential backoff.
|
|
4
|
+
*
|
|
5
|
+
* Emits structured events on stderr so downstream log collectors (e.g. cloud
|
|
6
|
+
* SigNoz) can aggregate by `event` and `context`. Format:
|
|
7
|
+
* [rate-limiter] event {"event":"flood_wait","context":"X","seconds":N,...}
|
|
4
8
|
*/
|
|
5
9
|
export class RateLimiter {
|
|
6
10
|
minInterval;
|
|
@@ -41,7 +45,13 @@ export class RateLimiter {
|
|
|
41
45
|
if (attempt >= this.maxRetries) {
|
|
42
46
|
throw new Error(`Rate limit exceeded after ${this.maxRetries} retries. Telegram requires ${waitSeconds}s wait. Try again later.`);
|
|
43
47
|
}
|
|
44
|
-
|
|
48
|
+
logEvent({
|
|
49
|
+
event: "flood_wait",
|
|
50
|
+
context,
|
|
51
|
+
seconds: waitSeconds,
|
|
52
|
+
attempt: attempt + 1,
|
|
53
|
+
maxRetries: this.maxRetries,
|
|
54
|
+
});
|
|
45
55
|
await sleep(waitSeconds * 1000);
|
|
46
56
|
return this.executeWithRetry(fn, context, attempt + 1, options);
|
|
47
57
|
}
|
|
@@ -51,7 +61,14 @@ export class RateLimiter {
|
|
|
51
61
|
throw new Error(`Network error after ${this.maxRetries} retries: ${errorMessage}. Check your connection.`);
|
|
52
62
|
}
|
|
53
63
|
const delay = Math.min(this.initialRetryDelay * 2 ** attempt, this.maxRetryDelay);
|
|
54
|
-
|
|
64
|
+
logEvent({
|
|
65
|
+
event: "network_retry",
|
|
66
|
+
context,
|
|
67
|
+
delayMs: delay,
|
|
68
|
+
attempt: attempt + 1,
|
|
69
|
+
maxRetries: this.maxRetries,
|
|
70
|
+
error: errorMessage,
|
|
71
|
+
});
|
|
55
72
|
await sleep(delay);
|
|
56
73
|
return this.executeWithRetry(fn, context, attempt + 1, options);
|
|
57
74
|
}
|
|
@@ -61,6 +78,14 @@ export class RateLimiter {
|
|
|
61
78
|
throw new Error(`Temporary error after ${this.maxRetries} retries: ${errorMessage}`);
|
|
62
79
|
}
|
|
63
80
|
const delay = Math.min(this.initialRetryDelay * 2 ** attempt, this.maxRetryDelay);
|
|
81
|
+
logEvent({
|
|
82
|
+
event: "temporary_retry",
|
|
83
|
+
context,
|
|
84
|
+
delayMs: delay,
|
|
85
|
+
attempt: attempt + 1,
|
|
86
|
+
maxRetries: this.maxRetries,
|
|
87
|
+
error: errorMessage,
|
|
88
|
+
});
|
|
64
89
|
await sleep(delay);
|
|
65
90
|
return this.executeWithRetry(fn, context, attempt + 1, options);
|
|
66
91
|
}
|
|
@@ -85,3 +110,6 @@ function isTemporaryError(msg) {
|
|
|
85
110
|
function sleep(ms) {
|
|
86
111
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
87
112
|
}
|
|
113
|
+
function logEvent(payload) {
|
|
114
|
+
console.error(`[rate-limiter] event ${JSON.stringify(payload)}`);
|
|
115
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@overpod/mcp-telegram",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.35.0",
|
|
4
4
|
"description": "MCP server for Telegram userbot — messages, media, reactions, polls & more. Built on GramJS/MTProto.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"zod": "^4.3.6"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@biomejs/biome": "^2.4.
|
|
66
|
+
"@biomejs/biome": "^2.4.13",
|
|
67
67
|
"@types/node": "^25.6.0",
|
|
68
68
|
"@types/qrcode": "^1.5.6",
|
|
69
69
|
"c8": "^11.0.0",
|