FastAPI-based SSL certificate automation server. - Google Public CA wildcard cert issuance via certbot - Cloudflare DNS-01 challenge with auto EAB key generation - APISIX multi-instance deployment with domain-instance mapping - Vault integration for all secrets - Bearer token auth, retry logic, Discord DM alerts - Auto-renewal scheduler (daily 03:00 UTC) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
44 lines
1.3 KiB
Python
44 lines
1.3 KiB
Python
import logging
|
|
|
|
import httpx
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
DISCORD_API = "https://discord.com/api/v10"
|
|
|
|
|
|
async def send_discord_dm(bot_token: str, user_id: str, message: str) -> bool:
|
|
"""Discord DM으로 알림 전송."""
|
|
if not bot_token or not user_id:
|
|
logger.warning("Discord credentials not configured, skipping alert")
|
|
return False
|
|
|
|
headers = {
|
|
"Authorization": f"Bot {bot_token}",
|
|
"Content-Type": "application/json",
|
|
}
|
|
|
|
try:
|
|
async with httpx.AsyncClient(timeout=15) as client:
|
|
# DM 채널 생성
|
|
resp = await client.post(
|
|
f"{DISCORD_API}/users/@me/channels",
|
|
headers=headers,
|
|
json={"recipient_id": user_id},
|
|
)
|
|
resp.raise_for_status()
|
|
channel_id = resp.json()["id"]
|
|
|
|
# 메시지 전송
|
|
resp = await client.post(
|
|
f"{DISCORD_API}/channels/{channel_id}/messages",
|
|
headers=headers,
|
|
json={"content": message},
|
|
)
|
|
resp.raise_for_status()
|
|
logger.info("Discord alert sent to user %s", user_id)
|
|
return True
|
|
except Exception as e:
|
|
logger.error("Failed to send Discord alert: %s", e)
|
|
return False
|