File size: 3,522 Bytes
71634bf
 
163eb6d
9f2ee93
37574c6
 
993ae60
 
 
163eb6d
 
9f2ee93
 
 
 
163eb6d
71634bf
993ae60
 
3faff69
993ae60
37574c6
71634bf
37574c6
3faff69
 
 
 
 
 
71634bf
993ae60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163eb6d
 
993ae60
9f2ee93
993ae60
3faff69
 
993ae60
9f2ee93
163eb6d
71634bf
 
3faff69
 
 
37574c6
993ae60
3faff69
9f2ee93
37574c6
 
 
993ae60
37574c6
993ae60
37574c6
993ae60
 
37574c6
993ae60
 
3faff69
993ae60
 
 
 
 
 
 
 
 
37574c6
 
993ae60
 
 
 
 
 
 
 
 
 
 
 
163eb6d
71634bf
993ae60
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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

# 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

@app.route("/", methods=["GET"])
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
    })

@app.route("/interactions", methods=["POST"])
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:
            logger.info("Responding to ping verification")
            return jsonify({"type": 1})
        
        # Slash Commands
        if data.get("type") == 2:
            command = data.get("data", {}).get("name")
            logger.info(f"Received command: {command}")
            
            if command == "settings":
                return jsonify({
                    "type": 4,
                    "data": {
                        "content": "✅ Bot ist aktiv und verifiziert!"
                    }
                })
        
        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)