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

@@ -52,6 +52,7 @@ class IncidentCreate(BaseModel):
refresh_interval: int = Field(default=15, ge=10, le=10080)
retention_days: int = Field(default=0, ge=0, le=999)
international_sources: bool = True
include_telegram: bool = False
visibility: str = Field(default="public", pattern="^(public|private)$")
@@ -64,6 +65,7 @@ class IncidentUpdate(BaseModel):
refresh_interval: Optional[int] = Field(default=None, ge=10, le=10080)
retention_days: Optional[int] = Field(default=None, ge=0, le=999)
international_sources: Optional[bool] = None
include_telegram: Optional[bool] = None
visibility: Optional[str] = Field(default=None, pattern="^(public|private)$")
@@ -80,6 +82,7 @@ class IncidentResponse(BaseModel):
summary: Optional[str]
sources_json: Optional[str] = None
international_sources: bool = True
include_telegram: bool = False
created_by: int
created_by_username: str = ""
created_at: str
@@ -95,7 +98,7 @@ class SourceCreate(BaseModel):
name: str = Field(min_length=1, max_length=200)
url: Optional[str] = None
domain: Optional[str] = None
source_type: str = Field(default="rss_feed", pattern="^(rss_feed|web_source|excluded)$")
source_type: str = Field(default="rss_feed", pattern="^(rss_feed|web_source|excluded|telegram_channel)$")
category: str = Field(default="sonstige", pattern="^(nachrichtenagentur|oeffentlich-rechtlich|qualitaetszeitung|behoerde|fachmedien|think-tank|international|regional|boulevard|sonstige)$")
status: str = Field(default="active", pattern="^(active|inactive)$")
notes: Optional[str] = None
@@ -105,7 +108,7 @@ class SourceUpdate(BaseModel):
name: Optional[str] = Field(default=None, max_length=200)
url: Optional[str] = None
domain: Optional[str] = None
source_type: Optional[str] = Field(default=None, pattern="^(rss_feed|web_source|excluded)$")
source_type: Optional[str] = Field(default=None, pattern="^(rss_feed|web_source|excluded|telegram_channel)$")
category: Optional[str] = Field(default=None, pattern="^(nachrichtenagentur|oeffentlich-rechtlich|qualitaetszeitung|behoerde|fachmedien|think-tank|international|regional|boulevard|sonstige)$")
status: Optional[str] = Field(default=None, pattern="^(active|inactive)$")
notes: Optional[str] = None