Skip to content

feat(bot): add Vercel JS webhook gateway with Televerse forwarding skeleton#53

Merged
SEVAAIGNATYEV merged 6 commits intoHyperlinksSpace:mainfrom
Dhereal1:fix/ai-intent-history-leak
Feb 26, 2026
Merged

feat(bot): add Vercel JS webhook gateway with Televerse forwarding skeleton#53
SEVAAIGNATYEV merged 6 commits intoHyperlinksSpace:mainfrom
Dhereal1:fix/ai-intent-history-leak

Conversation

@Dhereal1
Copy link
Contributor

@Dhereal1 Dhereal1 commented Feb 26, 2026

PR Title

feat(bot): add Vercel JS webhook gateway with Televerse forwarding skeleton

Summary

This PR adds a production-safe Telegram webhook gateway in front/api/bot.js and isolates bot logic into front/bot-service/*.
The gateway handles core commands locally (/start, /help, /ping), applies strict webhook safety checks, and can optionally forward sanitized updates to a Televerse (Dart) downstream service.

Confirmed Direction

  • JS webhook receiver on Vercel (thin entrypoint)
  • Televerse service handles richer logic downstream
  • Gateway remains reliable even when AI/downstream are unavailable

Gateway Contract

  • GET /api/bot
    • Health/status for gateway wiring.
  • POST /api/bot
    • Verifies X-Telegram-Bot-Api-Secret-Token (when configured).
    • Rejects oversized payloads.
    • Validates parsed JSON update.
    • Responds 200 { ok: true } immediately after validation (antifragile ACK behavior).
    • Processes update best-effort asynchronously.

Core Behavior

  • /start
    • Uses bounded AI health probe:
      • AI_HEALTH_TIMEOUT_MS default 1200
      • clamped to 200..1500
      • cached for short TTL (AI_HEALTH_CACHE_TTL_MS, default 30000)
    • AI up => welcome suggests prompts
    • AI down => safe welcome without prompt suggestion
  • /help and /ping handled locally in gateway
  • Non-core text messages optionally forwarded to Televerse via internal endpoint

Security and Reliability

  • Secret-token verification (401 on mismatch)
  • Payload size limit (TELEGRAM_BODY_LIMIT_BYTES, default 262144)
  • Structured sanitized logs (telegram_webhook_error, update_id, chat_id, update_kind)
  • No raw payload logging in error path

Televerse Forwarding Contract (Skeleton)

Gateway forwards a reduced envelope to:

  • POST {TELEVERSE_BASE_URL}/internal/process-update
  • Header: X-Internal-Key: {TELEVERSE_INTERNAL_KEY}

Envelope shape:

{
  "update_id": 123,
  "chat_id": 1,
  "user_id": 2,
  "text": "hi",
  "message_id": 10,
  "is_command": false,
  "command": null,
  "timestamp": 1700000000
}

Files Added

  • front/api/bot.js
  • front/bot-service/config.js
  • front/bot-service/logger.js
  • front/bot-service/text.js
  • front/bot-service/ai-health.js
  • front/bot-service/telegram.js
  • front/bot-service/downstream.js
  • front/bot-service/router.js
  • front/scripts/set-telegram-webhook.mjs
  • front/scripts/delete-telegram-webhook.mjs

Files Updated

  • front/vercel.json
  • front/README.md

Manual Smoke Checklist

  1. Set env vars (BOT_TOKEN, TELEGRAM_WEBHOOK_SECRET, optional AI/Televerse vars).
  2. Deploy front to Vercel.
  3. Run node front/scripts/set-telegram-webhook.mjs with TELEGRAM_WEBHOOK_URL=https://<domain>/api/bot.
  4. Send /start with healthy AI endpoint => prompt suggestion appears.
  5. Break AI_HEALTH_URL => /start safe fallback without prompt suggestion.
  6. Send wrong secret header => 401.
  7. Send malformed/oversized request => rejection path works.

Notes

  • This PR intentionally follows the existing front/api/*.js Vercel style for fast merge and single-root deployment.
  • apps/bot prototype is not part of this PR scope.

@SEVAAIGNATYEV
Copy link
Member

Review: chore(unified) scaffold modular unified service

Verdict: Approve — worth merging. One optional robustness fix below.


What's good

  • Config: Settings + _mode() validation; URLs only from env → no SSRF from user input.
  • Forwarding: Upstream URLs fixed from settings; only content-type and x-api-key forwarded (plus optional inner_calls_key).
  • Routers: Thin auth/ai/rag routers; local mode returns 501.
  • Health: /health and /ready expose only mode/route info; no secrets.
  • Tests: Health and forwarding tests in CI; forwarding tests use monkeypatch, no real HTTP.
  • Secrets: inner_calls_key from env only, not logged or exposed.
  • Placeholders: modules/* and observability are stubs; wallet/crypto.py states client-side-only.

Security / vulnerabilities

Area Status
SSRF No risk: URLs from config only.
Header forwarding Limited set; no sensitive headers beyond x-api-key.
Secrets No exposure of inner_calls_key.
Config / mode Validated; invalid mode falls back to "forward".
Dependencies FastAPI, uvicorn, httpx, pytest — nothing concerning.

No vulnerabilities identified.


Optional fix (non-blocking)

In app/forwarding/client.py, if upstream sends Content-Type: application/json but invalid JSON, upstream.json() can raise and cause a 500. Wrapping in try/except ValueError and falling back to returning the raw body (as in the old gateway) would avoid that:

if "application/json" in content_type:
    try:
        return JSONResponse(status_code=upstream.status_code, content=upstream.json())
    except ValueError:
        pass
return Response(content=upstream.content, status_code=upstream.status_code, media_type=content_type or None)

Minor

  • CI: pytest is in both requirements.txt and the workflow; redundant but fine.
  • Diff: Includes front/ and global_logo_bar.dart; if those are from a merge, consider keeping the PR scope to the unified service only.

Conclusion: Safe to merge. No security issues; optional to add the JSON robustness fix in this PR or a follow-up.

@SEVAAIGNATYEV SEVAAIGNATYEV merged commit ef2e3e3 into HyperlinksSpace:main Feb 26, 2026
1 check passed
@Dhereal1 Dhereal1 changed the title chore(unified): scaffold modular unified service with forward-only defaults and test wiring feat(bot): add Vercel JS webhook gateway with Televerse forwarding skeleton Feb 26, 2026
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.

2 participants