Alibrown commited on
Commit
2b7cf34
·
verified ·
1 Parent(s): ce4657d

Update app/app.py

Browse files
Files changed (1) hide show
  1. app/app.py +184 -34
app/app.py CHANGED
@@ -8,26 +8,38 @@ import threading
8
  import requests
9
  import time
10
  from commands import ping_command, settings_command
 
11
 
12
  # Logging konfigurieren
13
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 
 
 
 
 
 
 
14
  logger = logging.getLogger(__name__)
15
 
16
- # Konfiguration
17
  PUBLIC_KEY = os.getenv('Public_Key', '').strip()
18
  APPLICATION_ID = os.getenv('Application_ID', '').strip()
19
- PORT = int(os.getenv('PORT', 7860)) # Hugging Face nutzt standardmäßig Port 7860
20
 
 
21
  app = Flask(__name__)
 
22
 
 
23
  try:
24
  verify_key = VerifyKey(bytes.fromhex(PUBLIC_KEY)) if PUBLIC_KEY else None
25
- logger.info("Successfully initialized verify_key")
26
  except Exception as e:
27
- logger.error(f"Error initializing verify_key: {str(e)}")
28
  verify_key = None
29
 
30
  def verify_discord_request():
 
31
  try:
32
  signature = request.headers.get('X-Signature-Ed25519')
33
  timestamp = request.headers.get('X-Signature-Timestamp')
@@ -37,63 +49,201 @@ def verify_discord_request():
37
  verify_key.verify(f"{timestamp}{body}".encode(), bytes.fromhex(signature))
38
  return True
39
  except Exception as e:
40
- logger.error(f"Verification error: {str(e)}")
41
  return False
42
 
43
- @app.route("/", methods=["GET"])
44
- def health_check():
45
- """Hugging Face nutzt diesen Endpoint um zu prüfen ob der Space läuft"""
46
- return jsonify({
47
- "status": "running",
48
- "message": "Discord bot is running!",
49
- "public_key_present": bool(PUBLIC_KEY),
50
- "verify_key_initialized": verify_key is not None
51
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
 
53
  @app.route("/interactions", methods=["POST"])
54
  def interactions():
 
55
  if not verify_key:
56
- logger.error("verify_key not initialized")
57
- return "Configuration error", 500
58
 
59
  if not verify_discord_request():
60
- return "Invalid request signature", 401
61
 
62
  try:
63
  data = request.json
64
 
65
  # Discord Ping Verification
66
  if data.get("type") == 1:
67
- return ping_command(data)
68
 
69
  # Slash Commands
70
  if data.get("type") == 2:
71
  command = data.get("data", {}).get("name")
72
- if command == "settings":
 
 
 
 
 
 
 
 
 
 
 
 
73
  return settings_command(data)
 
 
74
 
75
  return jsonify({"type": 1})
76
 
77
  except Exception as e:
78
- logger.error(f"Error processing request: {str(e)}")
79
- return "Internal server error", 500
80
 
 
 
 
 
 
 
 
 
 
 
 
81
  def health_check_worker():
82
- """Background worker der regelmäßig den Health-Check Endpoint aufruft"""
83
  while True:
84
  try:
85
  response = requests.get(f"http://localhost:{PORT}/")
86
- logger.info(f"Health check status: {response.status_code}")
87
  except Exception as e:
88
- logger.error(f"Health check failed: {str(e)}")
89
- time.sleep(30)
90
 
 
91
  if __name__ == "__main__":
92
- logger.info(f"Starting Discord bot on port {PORT}...")
93
-
94
- # Starte Health-Check Worker in separatem Thread
95
- health_thread = threading.Thread(target=health_check_worker, daemon=True)
96
- health_thread.start()
97
-
98
- # Starte Server
99
- serve(app, host="0.0.0.0", port=PORT)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  import requests
9
  import time
10
  from commands import ping_command, settings_command
11
+ from bank import BankSystem, BankAccount, TransactionError
12
 
13
  # Logging konfigurieren
14
+ logging.basicConfig(
15
+ level=logging.INFO,
16
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
17
+ handlers=[
18
+ logging.FileHandler('discord_bot.log'),
19
+ logging.StreamHandler()
20
+ ]
21
+ )
22
  logger = logging.getLogger(__name__)
23
 
24
+ # Umgebungsvariablen und Konfiguration
25
  PUBLIC_KEY = os.getenv('Public_Key', '').strip()
26
  APPLICATION_ID = os.getenv('Application_ID', '').strip()
27
+ PORT = int(os.getenv('PORT', 7860)) # Hugging Face Standard-Port
28
 
29
+ # Flask App und Bank-System initialisieren
30
  app = Flask(__name__)
31
+ bank_system = BankSystem()
32
 
33
+ # Discord Verifizierungsschlüssel initialisieren
34
  try:
35
  verify_key = VerifyKey(bytes.fromhex(PUBLIC_KEY)) if PUBLIC_KEY else None
36
+ logger.info("Discord Verifizierungsschlüssel erfolgreich initialisiert")
37
  except Exception as e:
38
+ logger.error(f"Fehler beim Initialisieren des Verifizierungsschlüssels: {str(e)}")
39
  verify_key = None
40
 
41
  def verify_discord_request():
42
+ """Überprüft die Authentizität der Discord-Anfrage"""
43
  try:
44
  signature = request.headers.get('X-Signature-Ed25519')
45
  timestamp = request.headers.get('X-Signature-Timestamp')
 
49
  verify_key.verify(f"{timestamp}{body}".encode(), bytes.fromhex(signature))
50
  return True
51
  except Exception as e:
52
+ logger.error(f"Verifikationsfehler: {str(e)}")
53
  return False
54
 
55
+ # Bank-bezogene Command-Handler
56
+ def handle_balance_command(data):
57
+ """Verarbeitet den Balance-Check Befehl"""
58
+ user_id = data.get("member", {}).get("user", {}).get("id")
59
+ try:
60
+ account = bank_system.get_account(user_id)
61
+ if not account:
62
+ account = bank_system.create_account(user_id)
63
+ return jsonify({
64
+ "type": 4,
65
+ "data": {
66
+ "content": f"💰 Dein Kontostand: {account.format_balance()}"
67
+ }
68
+ })
69
+ except Exception as e:
70
+ logger.error(f"Fehler beim Balance-Check: {str(e)}")
71
+ return jsonify({
72
+ "type": 4,
73
+ "data": {
74
+ "content": "❌ Fehler beim Abrufen des Kontostands."
75
+ }
76
+ })
77
+
78
+ def handle_transfer_command(data):
79
+ """Verarbeitet Überweisungsbefehle"""
80
+ options = data.get("data", {}).get("options", [{}])[0].get("options", [])
81
+ user_id = data.get("member", {}).get("user", {}).get("id")
82
+
83
+ # Parameter aus den Optionen extrahieren
84
+ target_id = next((opt.get("value") for opt in options if opt.get("name") == "user"), None)
85
+ amount = next((float(opt.get("value")) for opt in options if opt.get("name") == "amount"), None)
86
+
87
+ try:
88
+ bank_system.transfer_between_accounts(user_id, target_id, amount)
89
+ return jsonify({
90
+ "type": 4,
91
+ "data": {
92
+ "content": f"✅ Erfolgreich {amount:,.2f} Credits an <@{target_id}> überwiesen!"
93
+ }
94
+ })
95
+ except TransactionError as e:
96
+ return jsonify({
97
+ "type": 4,
98
+ "data": {
99
+ "content": f"❌ Überweisungsfehler: {str(e)}"
100
+ }
101
+ })
102
+ except Exception as e:
103
+ logger.error(f"Unerwarteter Fehler bei Überweisung: {str(e)}")
104
+ return jsonify({
105
+ "type": 4,
106
+ "data": {
107
+ "content": "❌ Ein unerwarteter Fehler ist aufgetreten."
108
+ }
109
+ })
110
+
111
+ def handle_daily_command(data):
112
+ """Verarbeitet den täglichen Bonus-Befehl"""
113
+ user_id = data.get("member", {}).get("user", {}).get("id")
114
+ try:
115
+ result = bank_system.daily_reward(user_id)
116
+ return jsonify({
117
+ "type": 4,
118
+ "data": {
119
+ "content": f"🎁 {result}"
120
+ }
121
+ })
122
+ except Exception as e:
123
+ logger.error(f"Fehler beim Daily Reward: {str(e)}")
124
+ return jsonify({
125
+ "type": 4,
126
+ "data": {
127
+ "content": "❌ Fehler beim Abholen der täglichen Belohnung."
128
+ }
129
+ })
130
 
131
+ # Haupt-Route für Discord-Interaktionen
132
  @app.route("/interactions", methods=["POST"])
133
  def interactions():
134
+ """Hauptendpunkt für alle Discord-Interaktionen"""
135
  if not verify_key:
136
+ logger.error("Verifizierungsschlüssel nicht initialisiert")
137
+ return "Konfigurationsfehler", 500
138
 
139
  if not verify_discord_request():
140
+ return "Ungültige Anfrage-Signatur", 401
141
 
142
  try:
143
  data = request.json
144
 
145
  # Discord Ping Verification
146
  if data.get("type") == 1:
147
+ return jsonify({"type": 1})
148
 
149
  # Slash Commands
150
  if data.get("type") == 2:
151
  command = data.get("data", {}).get("name")
152
+
153
+ # Bank-bezogene Befehle
154
+ if command == "bank":
155
+ subcommand = data.get("data", {}).get("options", [{}])[0].get("name")
156
+ if subcommand == "balance":
157
+ return handle_balance_command(data)
158
+ elif subcommand == "transfer":
159
+ return handle_transfer_command(data)
160
+ elif subcommand == "daily":
161
+ return handle_daily_command(data)
162
+
163
+ # Andere Befehle
164
+ elif command == "settings":
165
  return settings_command(data)
166
+ elif command == "ping":
167
+ return ping_command(data)
168
 
169
  return jsonify({"type": 1})
170
 
171
  except Exception as e:
172
+ logger.error(f"Fehler bei der Verarbeitung der Anfrage: {str(e)}")
173
+ return "Interner Serverfehler", 500
174
 
175
+ # Health Check Endpoint
176
+ @app.route("/", methods=["GET"])
177
+ def health_check():
178
+ """Endpoint für Hugging Face Health Checks"""
179
+ return jsonify({
180
+ "status": "running",
181
+ "message": "Discord Bot läuft!",
182
+ "public_key_present": bool(PUBLIC_KEY),
183
+ "verify_key_initialized": verify_key is not None,
184
+ "bank_system_status": "active"
185
+ })
186
  def health_check_worker():
187
+ """Background Worker für regelmäßige Health Checks"""
188
  while True:
189
  try:
190
  response = requests.get(f"http://localhost:{PORT}/")
191
+ logger.info(f"Health Check Status: {response.status_code}")
192
  except Exception as e:
193
+ logger.error(f"Health Check fehlgeschlagen: {str(e)}")
194
+ time.sleep(30) # 30 Sekunden Pause zwischen den Checks
195
 
196
+ # Hauptausführung
197
  if __name__ == "__main__":
198
+ try:
199
+ logger.info(f"Starte Discord Bot auf Port {PORT}...")
200
+ logger.info("Initialisiere Bank-System...")
201
+
202
+ # Starte Health-Check Worker in separatem Thread
203
+ health_thread = threading.Thread(target=health_check_worker, daemon=True)
204
+ health_thread.start()
205
+
206
+ # Registriere Slash-Commands (einmalig bei Bot-Start)
207
+ BANK_COMMANDS = {
208
+ "name": "bank",
209
+ "description": "Bank-bezogene Befehle",
210
+ "options": [
211
+ {
212
+ "name": "balance",
213
+ "description": "Zeigt deinen aktuellen Kontostand",
214
+ "type": 1
215
+ },
216
+ {
217
+ "name": "transfer",
218
+ "description": "Überweise Credits an einen anderen Benutzer",
219
+ "type": 1,
220
+ "options": [
221
+ {
222
+ "name": "user",
223
+ "description": "Der Empfänger der Überweisung",
224
+ "type": 6,
225
+ "required": True
226
+ },
227
+ {
228
+ "name": "amount",
229
+ "description": "Die Menge an Credits",
230
+ "type": 10,
231
+ "required": True
232
+ }
233
+ ]
234
+ },
235
+ {
236
+ "name": "daily",
237
+ "description": "Hole dir deine tägliche Belohnung ab",
238
+ "type": 1
239
+ }
240
+ ]
241
+ }
242
+
243
+ # Starte Server
244
+ logger.info("Server wird gestartet...")
245
+ serve(app, host="0.0.0.0", port=PORT)
246
+
247
+ except Exception as e:
248
+ logger.critical(f"Kritischer Fehler beim Starten des Bots: {str(e)}")
249
+ raise