from fastapi import APIRouter, Query from typing import Optional, Dict, Any from backend.services.telegram_notification_service import TelegramNotificationService router = APIRouter() # Initialize service telegram_service = TelegramNotificationService() @router.get("/api/settings/telegram") async def get_telegram_settings(): """ Get Telegram settings with masked token. Returns: - enabled: bool - mask_token: str (only last 4 chars visible) - chat_id: str - thresholds: dict - toggles: dict - last_test_at: ISO datetime or None - last_delivery_at: ISO datetime or None """ return telegram_service.get_masked_settings() @router.post("/api/settings/telegram") async def save_telegram_settings(settings: Dict[str, Any]): """ Save Telegram settings securely. Body: { "token": "bot_token", "chat_id": "chat_id", "enabled": true/false, "thresholds": { "signal_score": 0.7, "whale_amount_usd": 250000 }, "toggles": { "trading_signal": true, "whale_transfer": true, "provider_offline": true, "news_negative": true } } Returns: { "ok": true/false } """ # Validate required fields if 'token' not in settings or 'chat_id' not in settings: return {'ok': False, 'detail': 'Missing token or chat_id'} # Load current settings to preserve timestamps current = telegram_service.load_settings() # Update with new values updated_settings = { 'token': settings.get('token'), 'chat_id': settings.get('chat_id'), 'enabled': settings.get('enabled', True), 'thresholds': settings.get('thresholds', { 'signal_score': 0.7, 'whale_amount_usd': 250000 }), 'toggles': settings.get('toggles', { 'trading_signal': True, 'whale_transfer': True, 'provider_offline': True, 'news_negative': True }), 'last_test_at': current.get('last_test_at'), 'last_delivery_at': current.get('last_delivery_at') } # Save settings success = telegram_service.save_settings(updated_settings) return {'ok': success} @router.post("/api/settings/telegram/test") async def test_telegram_notification(): """ Send a test message to verify Telegram configuration. Returns: { "ok": true/false, "detail": "success or error message" } """ result = telegram_service.send_test_message() return result @router.get("/api/logs/recent") async def get_recent_logs(limit: int = Query(default=50, ge=1, le=500)): """ Get recent log events from events.jsonl Args: limit: Number of recent events to return Returns: List of log event objects """ events = telegram_service.get_recent_logs(limit) return { 'count': len(events), 'events': events } @router.post("/api/notifications/signal") async def send_signal_notification(signal: Dict[str, Any]): """ Send trading signal notification. Body example: { "symbol": "BTC", "score": 0.85, "timeframe": "1h", "entry_price": 87500, "stop_loss": 86000, "take_profit": 90000 } """ success = telegram_service.notify_trading_signal(signal) return {'ok': success} @router.post("/api/notifications/whale") async def send_whale_notification(transfer: Dict[str, Any]): """ Send whale transfer notification. Body example: { "token_symbol": "ETH", "amount_usd": 5000000, "from_address": "0xabc...", "to_address": "0xdef...", "txid": "0x123..." } """ success = telegram_service.notify_whale_transfer(transfer) return {'ok': success} @router.post("/api/notifications/provider") async def send_provider_notification(data: Dict[str, Any]): """ Send provider offline notification. Body example: { "provider": "binance", "last_good": "2025-11-26T10:30:00Z" } """ provider = data.get('provider', 'unknown') last_good = data.get('last_good', 'unknown') success = telegram_service.notify_provider_offline(provider, last_good) return {'ok': success} @router.post("/api/notifications/news") async def send_news_notification(news: Dict[str, Any]): """ Send negative news notification. Body example: { "title": "Bitcoin crashes", "summary": "Market sees significant downturn...", "url": "https://...", "published_at": "2025-11-26T10:00:00Z", "sentiment_label": "negative" } """ success = telegram_service.notify_news_negative(news) return {'ok': success}