fix(telegram): add exponential backoff for sendChatAction 401 to prevent bot deletion#27415
Conversation
|
@greptile-apps please review |
Greptile SummaryThis PR successfully implements a two-layer defense against Telegram bot deletion caused by infinite Key Changes:
Testing:
The implementation correctly uses existing backoff infrastructure ( Confidence Score: 4/5
Last reviewed commit: d88da64 |
|
@greptile-apps please review — addressed feedback: now uses existing |
Address Greptile review feedback: - Handler is now created once in createTelegramBot() and shared across all message contexts for the account. This means consecutive 401s from ANY chat are tracked together, triggering the circuit breaker faster. - Reuse existing src/infra/backoff.ts (computeBackoff, sleepWithAbort) instead of custom sleep utility. - New test verifies cross-chatId failure counting (global behavior). - Interface now accepts chatId/action/threadParams per-call instead of per-handler, matching the global usage pattern.
31b857b to
6e343e0
Compare
|
Refactored based on Greptile feedback:
@greptile-apps please review |
src/telegram/bot-message-context.ts
Outdated
| baseRequireMention, | ||
| ); | ||
|
|
||
| const { sendChatActionHandler } = params; |
There was a problem hiding this comment.
params is not defined - this will cause ReferenceError at runtime. The function uses destructuring in its signature, so there's no params variable.
| const { sendChatActionHandler } = params; | |
| // sendChatActionHandler is already available from function parameters (needs to be added to destructuring above) |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/telegram/bot-message-context.ts
Line: 245
Comment:
`params` is not defined - this will cause `ReferenceError` at runtime. The function uses destructuring in its signature, so there's no `params` variable.
```suggestion
// sendChatActionHandler is already available from function parameters (needs to be added to destructuring above)
```
How can I resolve this? If you propose a fix, please make it concise.
Additional Comments (3)
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/telegram/bot-message-context.ts
Line: 143-161
Comment:
`sendChatActionHandler` is missing from the destructured parameters. It's defined in the type but not extracted here.
```suggestion
export const buildTelegramMessageContext = async ({
primaryCtx,
allMedia,
storeAllowFrom,
options,
bot,
cfg,
account,
historyLimit,
groupHistories,
dmPolicy,
allowFrom,
groupAllowFrom,
ackReactionScope,
logger,
resolveGroupActivation,
resolveGroupRequireMention,
resolveTelegramGroupConfig,
sendChatActionHandler,
}: BuildTelegramMessageContextParams) => {
```
How can I resolve this? If you propose a fix, please make it concise.
The handler needs to be created before Prompt To Fix With AIThis is a comment left during a code review.
Path: src/telegram/bot.ts
Line: 352-372
Comment:
The `sendChatActionHandler` is created later (line 414) but never passed to the message processor. This means the handler is never used, and the 401 backoff fix won't work.
The handler needs to be created before `createTelegramMessageProcessor` is called, then passed as a parameter. Alternatively, access it via `bot.sendChatActionHandler` after creating it.
How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/telegram/bot-message.ts
Line: 55-73
Comment:
`sendChatActionHandler` is not passed to `buildTelegramMessageContext`. Even if it's available in `deps`, it needs to be explicitly passed here.
```suggestion
const context = await buildTelegramMessageContext({
primaryCtx,
allMedia,
storeAllowFrom,
options,
bot,
cfg,
account,
historyLimit,
groupHistories,
dmPolicy,
allowFrom,
groupAllowFrom,
ackReactionScope,
logger,
resolveGroupActivation,
resolveGroupRequireMention,
resolveTelegramGroupConfig,
sendChatActionHandler: deps.sendChatActionHandler,
});
```
How can I resolve this? If you propose a fix, please make it concise. |
Address Greptile 1/5 review — handler was created but never reached the actual sendChatAction call sites. Call chain: createTelegramBot() → creates global handler → createTelegramMessageProcessor(deps) → receives handler → buildTelegramMessageContext(params) → receives handler → sendTyping() / sendRecordVoice() → uses handler Changes: - Handler created before message processor in bot.ts - Passed through bot-message.ts deps destructuring - Required (not optional) in BuildTelegramMessageContextParams - Removed fallback to raw bot.api.sendChatAction - All 7 backoff tests pass
|
Fixed all integration issues from Greptile 1/5 review: The handler is now properly threaded through the entire call chain: Specific fixes:
@greptile-apps please review |
The handler was in BuildTelegramMessageContextParams but missing from the actual destructured arguments of buildTelegramMessageContext(). This caused a ReferenceError at runtime since 'params' is not a variable (the function uses destructuring, not a params object). Also removed the redundant re-destructuring lower in the function.
|
Fixed the ReferenceError:
Now properly destructured alongside the other parameters. @greptile-apps please review |
…nks @widingmarcus-cyber) Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
|
Landed on What was landed from this PR:
Original PR commits:
Landing integration note:
Validation run before landing (
Thanks @widingmarcus-cyber for the incident-grade fix. |
, thanks @widingmarcus-cyber) Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
, thanks @widingmarcus-cyber) Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
, thanks @widingmarcus-cyber) Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
, thanks @widingmarcus-cyber) Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
, thanks @widingmarcus-cyber) Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
, thanks @widingmarcus-cyber) Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
, thanks @widingmarcus-cyber) Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
, thanks @widingmarcus-cyber) Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
, thanks @widingmarcus-cyber) Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
, thanks @widingmarcus-cyber) Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
, thanks @widingmarcus-cyber) Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
Problem
When a Telegram bot token becomes invalid (401 Unauthorized), the gateway enters an infinite loop of sendChatAction API calls with no backoff. This results in thousands of rapid-fire 401 errors (~1/sec), causing Telegram to flag the bot as abusive and permanently delete it.
Impact
CRITICAL - This bug destroys Telegram bots permanently:
Root Cause
The typing keepalive loop calls
sendChatActionevery 6 seconds with no error handling for 401 responses. When the token is invalid, each call fails with 401, but the loop continues indefinitely. Telegram interprets the rapid-fire requests as abuse and deletes the bot.Fix
Two-layer defense:
Testing
sendchataction-401-backoff.test.tswith comprehensive coverageFixes #27092