File size: 5,721 Bytes
46724e2 0b89c44 46724e2 0b89c44 46724e2 0b89c44 46724e2 0b89c44 46724e2 0b89c44 |
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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# Discord Bot Boilerplate by S. Volkan Kücükbudak
# Dev Link: https://github.com/VolkanSah/HF-Discord-Bot
# HF-Demo: https://huggingface.co./spaces/Alibrown/AI-Discord-free/
# You can use it for free (privat and commercial) do not sell my script, only your own work!
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()
BOT_TOKEN = os.getenv('BOT_TOKEN', '').strip()
PORT = int(os.getenv('PORT', 7860)) # Hugging Face nutzt standardmäßig Port 7860
app = Flask(__name__)
# Schlüssel zur Überprüfung von Anfragen initialisieren
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)
def register_commands():
"""Registriere Befehle bei Discord"""
url = f"https://discord.com/api/v10/applications/{APPLICATION_ID}/commands"
headers = {
"Authorization": f"Bot {BOT_TOKEN}"
}
json = {
"name": "settings",
"description": "Prüft den Status des Bots",
"type": 1
}
response = requests.post(url, headers=headers, json=json)
if response.status_code == 200:
logger.info("Command successfully registered")
else:
logger.error(f"Failed to register command: {response.status_code} - {response.json()}")
def setup_discord_channel_and_role(guild_id):
"""Erstellt einen Log-Channel und eine Rolle in der angegebenen Guild"""
headers = {
"Authorization": f"Bot {BOT_TOKEN}"
}
# Channel erstellen
channel_url = f"https://discord.com/api/v10/guilds/{guild_id}/channels"
channel_json = {
"name": "bot-logs",
"type": 0 # Text-Channel
}
channel_response = requests.post(channel_url, headers=headers, json=channel_json)
if channel_response.status_code == 201:
logger.info("Log-Channel successfully created")
else:
logger.error(f"Failed to create log-channel: {channel_response.status_code} - {channel_response.json()}")
# Rolle erstellen
role_url = f"https://discord.com/api/v10/guilds/{guild_id}/roles"
role_json = {
"name": "Bot Commander",
"permissions": "8" # Administrator-Rechte
}
role_response = requests.post(role_url, headers=headers, json=role_json)
if role_response.status_code == 201:
logger.info("Role successfully created")
else:
logger.error(f"Failed to create role: {role_response.status_code} - {role_response.json()}")
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()
# Registriere Slash-Command
register_commands()
# Starte Server
serve(app, host="0.0.0.0", port=PORT)
|