FIX: Discord notifikace se od začátku tiše zahazovaly — bot REST fallback
Some checks failed
CI and deploy / deploy (push) Has been cancelled
CI and deploy / migration-check (push) Has started running

Všechny site webhook URL jsou NULL a env DISCORD_WEBHOOK_URL nebyl nastaven
→ send_discord vždy skončil na 'not configured, skipping' (uživatel: 'nikdy
mi nic nepřišlo'). Fix: fallback přes bota (REST POST do DISCORD_EV_CHANNEL_ID
— token už v .env, žádný webhook netřeba); webhook má přednost, kdyby ho
uživatel později nastavil per site. Bot navíc při startu pošle ' online'
(viditelný důkaz, 1× per deploy).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dusan Vojacek
2026-06-12 13:44:30 +02:00
parent ee3581da02
commit b651191fdb
2 changed files with 35 additions and 11 deletions

View File

@@ -193,6 +193,13 @@ async def run_discord_bot() -> None:
@client.event
async def on_ready() -> None:
logger.info("Discord bot připojen jako %s", client.user)
try:
channel_id = int(getattr(get_settings(), "discord_ev_channel_id", 0) or 0)
ch = client.get_channel(channel_id) if channel_id else None
if ch is not None:
await ch.send("✅ EMS bot online — notifikace aktivní")
except Exception:
logger.exception("Discord on_ready ping failed")
@client.event
async def on_interaction(interaction: discord.Interaction) -> None:

View File

@@ -195,24 +195,41 @@ async def send_discord(
"""
kind = "daily" if level == "info" else "error"
webhook_url = await _get_site_webhook_url(conn, site_id, kind)
if not webhook_url:
logger.debug("Discord webhook not configured, skipping notification")
return False
emoji = {"info": "", "warning": "⚠️", "error": "", "critical": "🚨"}.get(level, "")
content = f"{emoji} **EMS** [{level.upper()}]\n{message}"
if webhook_url:
try:
async with httpx.AsyncClient(timeout=10) as client:
resp = await client.post(webhook_url, json={"content": content})
resp.raise_for_status()
return True
except Exception as e:
logger.warning("Discord webhook failed: %s — zkouším bot fallback", e)
# Fallback: bot REST (kanál z DISCORD_EV_CHANNEL_ID) — webhooky per site
# nebyly nikdy nastavené, takže bez fallbacku se notifikace tiše zahazovaly.
return await _send_via_bot(content)
async def _send_via_bot(content: str) -> bool:
s = get_settings()
token = (getattr(s, "discord_bot_token", "") or "").strip()
channel = (getattr(s, "discord_ev_channel_id", "") or "").strip()
if not token or not channel:
logger.debug("Discord: žádný webhook ani bot — notifikace zahozena")
return False
try:
async with httpx.AsyncClient(timeout=10) as client:
resp = await client.post(
webhook_url,
json={
"content": f"{emoji} **EMS Alert** [{level.upper()}]\n{message}",
},
r = await client.post(
f"https://discord.com/api/v10/channels/{channel}/messages",
headers={"Authorization": f"Bot {token}"},
json={"content": content[:1900]},
)
resp.raise_for_status()
r.raise_for_status()
return True
except Exception as e:
logger.warning("Discord notification failed: %s", e)
logger.warning("Discord bot fallback failed: %s", e)
return False