feat(gateway): implement global messaging gateway toggle

- Added a global switch `GATEWAY_ENABLED` to control the activation of all messaging gateway channels (Telegram, WhatsApp, Slack, Discord).
- Updated relevant routes and workers to check the `GATEWAY_ENABLED` flag, returning 404 for HTTP routes when disabled.
- Enhanced documentation in the `.env.example` file to reflect the new configuration option.
This commit is contained in:
DESKTOP-RTLN3BA\$punk 2026-06-08 13:24:29 -07:00
parent 6d1d00ebbc
commit ef7a20a5d0
7 changed files with 40 additions and 4 deletions

View file

@ -15,6 +15,13 @@ REDIS_APP_URL=redis://localhost:6379/0
# Optional: TTL in seconds for connector indexing lock key
# CONNECTOR_INDEXING_LOCK_TTL_SECONDS=28800
# Messaging Gateway (global)
# GATEWAY_ENABLED: master switch for ALL messaging gateway channels (Telegram, WhatsApp,
# Slack, Discord). When FALSE, no gateway background workers/supervisors start and all
# gateway HTTP routes (webhooks, OAuth callbacks, pairing) return 404. Set per-channel
# flags below to control individual platforms once the gateway is enabled.
GATEWAY_ENABLED=TRUE
# Telegram Gateway
# TELEGRAM_WEBHOOK_SECRET must be 1-256 chars and contain only A-Z, a-z, 0-9, _ or -
# GATEWAY_TELEGRAM_INTAKE_MODE: `webhook` for production, `longpoll` for single-replica self-host fallback, `disabled` to skip Telegram intake

View file

@ -542,6 +542,9 @@ class Config:
BACKEND_URL = os.getenv("BACKEND_URL")
# Messaging gateway (Telegram v1)
# Global master switch: when FALSE, no gateway supervisors/workers start and all
# gateway HTTP routes return 404, regardless of the per-channel flags below.
GATEWAY_ENABLED = os.getenv("GATEWAY_ENABLED", "TRUE").upper() == "TRUE"
TELEGRAM_SHARED_BOT_TOKEN = os.getenv("TELEGRAM_SHARED_BOT_TOKEN")
TELEGRAM_SHARED_BOT_USERNAME = os.getenv("TELEGRAM_SHARED_BOT_USERNAME")
TELEGRAM_WEBHOOK_SECRET = os.getenv("TELEGRAM_WEBHOOK_SECRET")

View file

@ -1,2 +1,19 @@
"""Messaging gateway infrastructure for external chat channels."""
from __future__ import annotations
from fastapi import HTTPException, status
from app.config import config
def require_gateway_enabled() -> None:
"""FastAPI dependency that gates all gateway HTTP routes on the global flag.
Returns 404 (rather than 503) when ``GATEWAY_ENABLED`` is FALSE so that
disabling the gateway makes its webhook/OAuth/pairing surface indistinguishable
from a route that does not exist.
"""
if not config.GATEWAY_ENABLED:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found")

View file

@ -96,6 +96,8 @@ async def start_byo_long_poll_supervisors() -> None:
"""Start one BYO long-poll supervisor per active non-system Telegram account."""
global _shutdown_event
if not config.GATEWAY_ENABLED:
return
if (
config.GATEWAY_TELEGRAM_INTAKE_MODE != "longpoll"
and config.GATEWAY_WHATSAPP_INTAKE_MODE != "baileys"

View file

@ -177,6 +177,8 @@ async def _run_discord_gateway() -> None:
async def start_discord_gateway_supervisor() -> None:
global _shutdown_event, _task
if not config.GATEWAY_ENABLED:
return
if not config.GATEWAY_DISCORD_ENABLED:
return
if _task is not None and not _task.done():

View file

@ -6,6 +6,7 @@ import asyncio
import logging
from contextlib import suppress
from app.config import config
from app.gateway.inbox_processor import claim_next_inbound_event, process_inbound_event
logger = logging.getLogger(__name__)
@ -39,6 +40,8 @@ async def _process_inbox_forever() -> None:
async def start_gateway_inbox_worker() -> None:
global _task
if not config.GATEWAY_ENABLED:
return
if _task is not None and not _task.done():
return
_task = asyncio.create_task(_process_inbox_forever(), name="gateway-inbox-worker")

View file

@ -1,6 +1,7 @@
from fastapi import APIRouter
from fastapi import APIRouter, Depends
from app.automations.api import router as automations_router
from app.gateway import require_gateway_enabled
from app.file_storage.api import router as file_storage_router
from .agent_action_log_route import router as agent_action_log_router
@ -73,9 +74,10 @@ router.include_router(editor_router)
router.include_router(export_router)
router.include_router(documents_router)
router.include_router(folders_router)
router.include_router(gateway_router)
router.include_router(gateway_whatsapp_webhook_router)
router.include_router(gateway_whatsapp_baileys_router)
_gateway_enabled_dep = [Depends(require_gateway_enabled)]
router.include_router(gateway_router, dependencies=_gateway_enabled_dep)
router.include_router(gateway_whatsapp_webhook_router, dependencies=_gateway_enabled_dep)
router.include_router(gateway_whatsapp_baileys_router, dependencies=_gateway_enabled_dep)
router.include_router(notes_router)
router.include_router(new_chat_router) # Chat with assistant-ui persistence
router.include_router(agent_revert_router) # POST /threads/{id}/revert/{action_id}