Files
HarborForge.Backend/app/services/discord_wakeup.py

73 lines
2.8 KiB
Python

from __future__ import annotations
from datetime import datetime, timezone
from typing import Any
import requests
from fastapi import HTTPException
from app.services.harborforge_config import get_discord_wakeup_config
DISCORD_API_BASE = "https://discord.com/api/v10"
WAKEUP_CATEGORY_NAME = "HarborForge Wakeup"
def _headers(bot_token: str) -> dict[str, str]:
return {
"Authorization": f"Bot {bot_token}",
"Content-Type": "application/json",
}
def _ensure_category(guild_id: str, bot_token: str) -> str | None:
resp = requests.get(f"{DISCORD_API_BASE}/guilds/{guild_id}/channels", headers=_headers(bot_token), timeout=15)
if not resp.ok:
raise HTTPException(status_code=502, detail=f"Discord list channels failed: {resp.text}")
for ch in resp.json():
if ch.get("type") == 4 and ch.get("name") == WAKEUP_CATEGORY_NAME:
return ch.get("id")
payload = {"name": WAKEUP_CATEGORY_NAME, "type": 4}
created = requests.post(f"{DISCORD_API_BASE}/guilds/{guild_id}/channels", headers=_headers(bot_token), json=payload, timeout=15)
if not created.ok:
raise HTTPException(status_code=502, detail=f"Discord create category failed: {created.text}")
return created.json().get("id")
def create_private_wakeup_channel(discord_user_id: str, title: str, message: str) -> dict[str, Any]:
cfg = get_discord_wakeup_config()
guild_id = cfg.get("guild_id")
bot_token = cfg.get("bot_token")
if not guild_id or not bot_token:
raise HTTPException(status_code=400, detail="Discord wakeup config is incomplete")
category_id = _ensure_category(guild_id, bot_token)
channel_name = f"wake-{discord_user_id[-6:]}-{int(datetime.now(timezone.utc).timestamp())}"
payload = {
"name": channel_name,
"type": 0,
"parent_id": category_id,
"permission_overwrites": [
{"id": guild_id, "type": 0, "deny": "1024"},
{"id": discord_user_id, "type": 1, "allow": "1024"},
],
"topic": title,
}
created = requests.post(f"{DISCORD_API_BASE}/guilds/{guild_id}/channels", headers=_headers(bot_token), json=payload, timeout=15)
if not created.ok:
raise HTTPException(status_code=502, detail=f"Discord create channel failed: {created.text}")
channel = created.json()
sent = requests.post(
f"{DISCORD_API_BASE}/channels/{channel['id']}/messages",
headers=_headers(bot_token),
json={"content": message},
timeout=15,
)
if not sent.ok:
raise HTTPException(status_code=502, detail=f"Discord send message failed: {sent.text}")
return {
"guild_id": guild_id,
"channel_id": channel.get("id"),
"channel_name": channel.get("name"),
"message_id": sent.json().get("id"),
}