update
This commit is contained in:
92
main.py
Normal file
92
main.py
Normal file
@@ -0,0 +1,92 @@
|
||||
from fastapi import FastAPI, HTTPException, BackgroundTasks
|
||||
from pydantic import BaseModel
|
||||
from bot import MatrixBot
|
||||
import asyncio
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
bot = MatrixBot()
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
# Startup
|
||||
await bot.login()
|
||||
yield
|
||||
# Shutdown
|
||||
await bot.close()
|
||||
|
||||
app = FastAPI(lifespan=lifespan)
|
||||
|
||||
class Notification(BaseModel):
|
||||
service_name: str
|
||||
content: str
|
||||
room_id: str | None = None
|
||||
level: str = "info"
|
||||
|
||||
class JellyfinPayload(BaseModel):
|
||||
notification_type: str
|
||||
item_type: str
|
||||
name: str
|
||||
series_name: str | None = None
|
||||
season: int | None = None
|
||||
episode: int | None = None
|
||||
year: int | None = None
|
||||
overview: str | None = None
|
||||
room_id: str | None = None
|
||||
|
||||
@app.post("/notify")
|
||||
async def send_notification(notification: Notification, background_tasks: BackgroundTasks):
|
||||
"""
|
||||
Send a notification to a Matrix room.
|
||||
"""
|
||||
try:
|
||||
# Format the message to include the service name
|
||||
# Plain text fallback
|
||||
plain_message = f"[{notification.service_name}]\n{notification.content}"
|
||||
# HTML message
|
||||
html_message = f"<b>[{notification.service_name}]</b><br>{notification.content}"
|
||||
|
||||
# We can send it in background to not block the API response
|
||||
background_tasks.add_task(bot.send_message, plain_message, html_message, notification.room_id)
|
||||
return {"status": "queued"}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@app.post("/jellyfin")
|
||||
async def receive_jellyfin_webhook(payload: JellyfinPayload, background_tasks: BackgroundTasks):
|
||||
"""
|
||||
Receive webhook from Jellyfin and forward to Matrix.
|
||||
"""
|
||||
try:
|
||||
if payload.notification_type != "ItemAdded":
|
||||
return {"status": "ignored", "reason": "Not an ItemAdded event"}
|
||||
|
||||
# content construction
|
||||
content = ""
|
||||
if payload.item_type == "Movie":
|
||||
content = f"New Movie: {payload.name}"
|
||||
if payload.year:
|
||||
content += f" ({payload.year})"
|
||||
if payload.overview:
|
||||
content += f"\n{payload.overview}"
|
||||
elif payload.item_type == "Episode":
|
||||
show = payload.series_name or "Unknown Series"
|
||||
s = f"S{payload.season:02d}" if payload.season is not None else "S??"
|
||||
e = f"E{payload.episode:02d}" if payload.episode is not None else "E??"
|
||||
content = f"New Episode: {show} - {s}{e} - {payload.name}"
|
||||
else:
|
||||
# Fallback for Series, Season, etc.
|
||||
content = f"New {payload.item_type}: {payload.name}"
|
||||
|
||||
plain_message = f"[Jellyfin]\n{content}"
|
||||
html_message = f"<b>[Jellyfin]</b><br>{content.replace(chr(10), '<br>')}"
|
||||
|
||||
background_tasks.add_task(bot.send_message, plain_message, html_message, payload.room_id)
|
||||
return {"status": "queued"}
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
async def health_check():
|
||||
return {"status": "ok"}
|
||||
Reference in New Issue
Block a user