Spaces:
Running
Running
from flask import Flask, request, jsonify | |
import os | |
import logging | |
from waitress import serve | |
from nacl.signing import VerifyKey | |
from nacl.exceptions import BadSignatureError | |
import threading | |
import requests | |
import time | |
from commands import ping_command, settings_command | |
# Logging konfigurieren | |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') | |
logger = logging.getLogger(__name__) | |
# Konfiguration | |
PUBLIC_KEY = os.getenv('Public_Key', '').strip() | |
APPLICATION_ID = os.getenv('Application_ID', '').strip() | |
PORT = int(os.getenv('PORT', 7860)) # Hugging Face nutzt standardmäßig Port 7860 | |
app = Flask(__name__) | |
try: | |
verify_key = VerifyKey(bytes.fromhex(PUBLIC_KEY)) if PUBLIC_KEY else None | |
logger.info("Successfully initialized verify_key") | |
except Exception as e: | |
logger.error(f"Error initializing verify_key: {str(e)}") | |
verify_key = None | |
def verify_discord_request(): | |
try: | |
signature = request.headers.get('X-Signature-Ed25519') | |
timestamp = request.headers.get('X-Signature-Timestamp') | |
if not signature or not timestamp: | |
return False | |
body = request.data.decode('utf-8') | |
verify_key.verify(f"{timestamp}{body}".encode(), bytes.fromhex(signature)) | |
return True | |
except Exception as e: | |
logger.error(f"Verification error: {str(e)}") | |
return False | |
def health_check(): | |
"""Hugging Face nutzt diesen Endpoint um zu prüfen ob der Space läuft""" | |
return jsonify({ | |
"status": "running", | |
"message": "Discord bot is running!", | |
"public_key_present": bool(PUBLIC_KEY), | |
"verify_key_initialized": verify_key is not None | |
}) | |
def interactions(): | |
if not verify_key: | |
logger.error("verify_key not initialized") | |
return "Configuration error", 500 | |
if not verify_discord_request(): | |
return "Invalid request signature", 401 | |
try: | |
data = request.json | |
# Discord Ping Verification | |
if data.get("type") == 1: | |
return ping_command(data) | |
# Slash Commands | |
if data.get("type") == 2: | |
command = data.get("data", {}).get("name") | |
if command == "settings": | |
return settings_command(data) | |
return jsonify({"type": 1}) | |
except Exception as e: | |
logger.error(f"Error processing request: {str(e)}") | |
return "Internal server error", 500 | |
def health_check_worker(): | |
"""Background worker der regelmäßig den Health-Check Endpoint aufruft""" | |
while True: | |
try: | |
response = requests.get(f"http://localhost:{PORT}/") | |
logger.info(f"Health check status: {response.status_code}") | |
except Exception as e: | |
logger.error(f"Health check failed: {str(e)}") | |
time.sleep(30) | |
if __name__ == "__main__": | |
logger.info(f"Starting Discord bot on port {PORT}...") | |
# Starte Health-Check Worker in separatem Thread | |
health_thread = threading.Thread(target=health_check_worker, daemon=True) | |
health_thread.start() | |
# Starte Server | |
serve(app, host="0.0.0.0", port=PORT) |