Telegram-Kanaele als Quelle: Parser, Pipeline, UI-Checkbox, Validate-Endpoint

- Neuer source_type telegram_channel in models.py (Source + Incident)
- DB-Migration: include_telegram Spalte fuer incidents
- feeds/telegram_parser.py: Telethon-basierter Parser (analog RSS)
- Orchestrator: Telegram-Pipeline parallel zu RSS + WebSearch
- sources.py: POST /api/sources/telegram/validate Endpoint
- incidents.py: include_telegram in Create/Update/Response
- dashboard.html: Telegram-Checkbox + Filter-Option
- app.js: FormData, EditModal, SourceStats, TypeLabels
- config.py: TELEGRAM_API_ID, API_HASH, SESSION_PATH
- requirements.txt: telethon hinzugefuegt
Dieser Commit ist enthalten in:
Claude Dev
2026-03-13 13:10:24 +01:00
Ursprung 08aad935c9
Commit 01cad9dac5
10 geänderte Dateien mit 330 neuen und 3215 gelöschten Zeilen

Datei anzeigen

@@ -20,7 +20,7 @@ router = APIRouter(prefix="/api/incidents", tags=["incidents"])
INCIDENT_UPDATE_COLUMNS = {
"title", "description", "type", "status", "refresh_mode",
"refresh_interval", "retention_days", "international_sources", "visibility",
"refresh_interval", "retention_days", "international_sources", "include_telegram", "visibility",
}
@@ -105,9 +105,9 @@ async def create_incident(
now = datetime.now(TIMEZONE).strftime('%Y-%m-%d %H:%M:%S')
cursor = await db.execute(
"""INSERT INTO incidents (title, description, type, refresh_mode, refresh_interval,
retention_days, international_sources, visibility,
retention_days, international_sources, include_telegram, visibility,
tenant_id, created_by, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
(
data.title,
data.description,
@@ -116,6 +116,7 @@ async def create_incident(
data.refresh_interval,
data.retention_days,
1 if data.international_sources else 0,
1 if data.include_telegram else 0,
data.visibility,
tenant_id,
current_user["id"],
@@ -721,6 +722,7 @@ def _build_json_export(
"updated_at": incident.get("updated_at"),
"summary": incident.get("summary"),
"international_sources": bool(incident.get("international_sources")),
"include_telegram": bool(incident.get("include_telegram")),
},
"sources": sources,
"fact_checks": [

Datei anzeigen

@@ -87,6 +87,7 @@ async def get_source_stats(
stats = {
"rss_feed": {"count": 0, "articles": 0},
"web_source": {"count": 0, "articles": 0},
"telegram_channel": {"count": 0, "articles": 0},
"excluded": {"count": 0, "articles": 0},
}
for row in rows:
@@ -516,6 +517,32 @@ async def delete_source(
await db.commit()
@router.post("/telegram/validate")
async def validate_telegram_channel(
data: dict,
current_user: dict = Depends(get_current_user),
):
"""Prueft ob ein Telegram-Kanal erreichbar ist und gibt Kanalinfo zurueck."""
channel_id = data.get("channel_id", "").strip()
if not channel_id:
raise HTTPException(status_code=400, detail="channel_id ist erforderlich")
try:
from feeds.telegram_parser import TelegramParser
parser = TelegramParser()
result = await parser.validate_channel(channel_id)
if result:
return result
raise HTTPException(status_code=404, detail="Kanal nicht erreichbar oder nicht gefunden")
except HTTPException:
raise
except Exception as e:
logger.error("Telegram-Validierung fehlgeschlagen: %s", e, exc_info=True)
raise HTTPException(status_code=500, detail="Telegram-Validierung fehlgeschlagen")
@router.post("/refresh-counts")
async def trigger_refresh_counts(
current_user: dict = Depends(get_current_user),