Skip to content

Harden Telegram proxy cloud fallback handling#1

Open
dankarization wants to merge 3 commits into
mainfrom
codex/getfile-400-cloud-fallback
Open

Harden Telegram proxy cloud fallback handling#1
dankarization wants to merge 3 commits into
mainfrom
codex/getfile-400-cloud-fallback

Conversation

@dankarization

Copy link
Copy Markdown
Owner

Summary

  • fallback getFile to cloud when local Bot API returns 400, so cloud-origin file_id values can still resolve
  • harden cloud getUpdates fallback with bridge/virtualization for local update_id values after cloud fallback
  • defer cloud pending fallback for 60 seconds when local polling is healthy but temporarily empty
  • add diagnostics for pendingAgeMs, translatedLocal, and bridgedLocal
  • document the fallback behavior and new env knobs in README.md and CHANGELOG.md

Verification

  • node --check src/telegram-bot-api-proxy.mjs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9f7053f336

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const translated = translateLocalUpdatesWithBridge(token, payload);
if (translated) {
return {
upstream: translated.translated ? jsonCloudResponse(upstream, { ...payload, result: translated.result }) : upstream,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return an empty body when bridged updates are dropped

When a local bridge is active and the local API returns only updates with update_id <= state.localFloor, translateLocalUpdatesWithBridge() returns result: [], dropped > 0, and translated: false; this ternary then sends the original upstream body back to OpenClaw instead of the empty filtered result. In that retry/ack-lag scenario the proxy logs and acknowledges dropped stale local updates but still exposes those stale low-ID updates to the caller, defeating the bridge/filtering that this path is meant to enforce.

Useful? React with 👍 / 👎.

// В этом случае local getFile отвечает 400, но cloud API всё ещё может его разрешить.
function shouldRetryCloudAfterLocalStatus(method, statusCode) {
if (statusCode === 401 || statusCode === 404) return true;
if (method === "getFile" && statusCode === 400) return true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Route cloud getFile paths to cloud downloads

When this new getFile 400 fallback returns a cloud file_path for a file ID unknown to the local Bot API, the following /file/bot.../<file_path> request still goes to localRoot whenever checkLocalHealth() passes, and the streaming path only retries on socket errors rather than local 404/400 responses. Healthy local deployments therefore hand OpenClaw a cloud-only path and then fail the media download for exactly the fallback updates this branch is meant to support; the proxy needs to remember cloud-origin paths or prefer cloud for those cached /file downloads.

Useful? React with 👍 / 👎.

});
const dropped = payload.result.length - result.length;
const bridged = result.length === 0 && shouldBridgeLocalUpdateIds(floor, maxDroppedUpdateId, payload.result)
? bridgeLocalUpdateIds(botId, maxDroppedUpdateId, floor)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Virtualize the first local batch before acking it

When the first local poll after cloud/OpenClaw divergence returns only fresh local-space updates below the OpenClaw floor, this seeds the bridge at maxDroppedUpdateId after those updates have already been filtered out; the same response then acknowledges maxDroppedUpdateId + 1, so that initial batch is never returned and will not be fetched again. In this divergence case the bridge should virtualize the current batch or base the bridge before the first dropped local ID rather than confirming the batch as skipped.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant