Bridges Telegram messages to Timmy via python-telegram-bot (optional dependency). The bot token can be supplied through the TELEGRAM_TOKEN env var or at runtime via the new POST /telegram/setup dashboard endpoint, which (re)starts the bot without a restart. Changes: - src/telegram_bot/bot.py — TelegramBot singleton: token persistence (telegram_state.json), lifecycle (start/stop), /start command and message handler that forwards to Timmy - src/dashboard/routes/telegram.py — /telegram/setup and /telegram/status FastAPI routes - src/dashboard/app.py — register telegram router; auto-start/stop bot in lifespan hook - src/config.py — TELEGRAM_TOKEN setting (pydantic-settings) - pyproject.toml — [telegram] optional extra (python-telegram-bot>=21), telegram_bot wheel include - .env.example — TELEGRAM_TOKEN section - .gitignore — exclude telegram_state.json (contains token) - tests/conftest.py — stub telegram/telegram.ext for offline test runs - tests/test_telegram_bot.py — 16 tests covering token helpers, lifecycle, and all dashboard routes (370 total, all passing) https://claude.ai/code/session_01CNBm3ZLobtx3Z1YogHq8ZS
52 lines
1.3 KiB
Python
52 lines
1.3 KiB
Python
"""Dashboard routes for Telegram bot setup and status."""
|
|
|
|
from fastapi import APIRouter
|
|
from pydantic import BaseModel
|
|
|
|
router = APIRouter(prefix="/telegram", tags=["telegram"])
|
|
|
|
|
|
class TokenPayload(BaseModel):
|
|
token: str
|
|
|
|
|
|
@router.post("/setup")
|
|
async def setup_telegram(payload: TokenPayload):
|
|
"""Accept a Telegram bot token, save it, and (re)start the bot.
|
|
|
|
Send a POST with JSON body: {"token": "<your-bot-token>"}
|
|
Get the token from @BotFather on Telegram.
|
|
"""
|
|
from telegram_bot.bot import telegram_bot
|
|
|
|
token = payload.token.strip()
|
|
if not token:
|
|
return {"ok": False, "error": "Token cannot be empty."}
|
|
|
|
telegram_bot.save_token(token)
|
|
|
|
if telegram_bot.is_running:
|
|
await telegram_bot.stop()
|
|
|
|
success = await telegram_bot.start(token=token)
|
|
if success:
|
|
return {"ok": True, "message": "Telegram bot started successfully."}
|
|
return {
|
|
"ok": False,
|
|
"error": (
|
|
"Failed to start bot. Check the token is correct and that "
|
|
'python-telegram-bot is installed: pip install ".[telegram]"'
|
|
),
|
|
}
|
|
|
|
|
|
@router.get("/status")
|
|
async def telegram_status():
|
|
"""Return the current state of the Telegram bot."""
|
|
from telegram_bot.bot import telegram_bot
|
|
|
|
return {
|
|
"running": telegram_bot.is_running,
|
|
"token_set": telegram_bot.token_set,
|
|
}
|