modified: app.py

modified:   bot.py
	modified:   templates/navigation.html
	modified:   templates/privacy_policy.html
	new file:   templates/user_contact.html
This commit is contained in:
SimolZimol
2025-08-24 22:42:16 +02:00
parent 52739bf189
commit ae57673029
5 changed files with 999 additions and 19 deletions

371
bot.py
View File

@@ -687,6 +687,81 @@ async def process_manager():
except Exception as e:
logger.error(f"Error in process manager: {e}")
# Contact Messages Task
@tasks.loop(minutes=15)
async def check_contact_messages():
"""Automatically checks for pending contact messages every 15 minutes"""
try:
connection = connect_to_database()
cursor = connection.cursor()
# Hole alle pending Nachrichten
cursor.execute("""
SELECT id, user_id, username, subject, category, priority, message,
server_context, submitted_at
FROM contact_messages
WHERE status = 'pending'
ORDER BY submitted_at ASC
""")
pending_messages = cursor.fetchall()
if pending_messages:
logger.info(f"Found {len(pending_messages)} pending contact messages")
processed_count = 0
for msg in pending_messages:
msg_id, user_id, username, subject, category, priority, message, server_context, submitted_at = msg
try:
# Hole User-Informationen von Discord
user = client.get_user(int(user_id))
if not user:
try:
user = await client.fetch_user(int(user_id))
except:
user = None
message_data = {
'user_id': user_id,
'user_name': user.display_name if user else username.split('#')[0],
'username': username,
'avatar_url': user.avatar.url if user and user.avatar else None,
'subject': subject,
'category': category,
'priority': priority,
'message': message,
'server_context': server_context
}
# Sende an Admin
success = await send_contact_message_to_admin(message_data)
if success:
# Markiere als versendet
cursor.execute("""
UPDATE contact_messages
SET status = 'sent', responded_at = %s
WHERE id = %s
""", (int(time.time()), msg_id))
processed_count += 1
logger.info(f"Sent contact message {msg_id} to admin")
except Exception as e:
logger.error(f"Error processing contact message {msg_id}: {e}")
continue
connection.commit()
if processed_count > 0:
logger.info(f"Automatically processed {processed_count} contact messages")
cursor.close()
close_database_connection(connection)
except Exception as e:
logger.error(f"Error in check_contact_messages task: {e}")
async def handle_expired_process(process_uuid, process_type, data):
"""Handles different types of expired processes"""
try:
@@ -1775,6 +1850,11 @@ async def on_ready():
if not process_manager.is_running():
process_manager.start()
# Start the contact messages checker
if not check_contact_messages.is_running():
check_contact_messages.start()
logger.info("Contact messages checker started (15-minute intervals)")
logger.info("Bot is ready!")
logger.info(f"Logged in as: {client.user.name}")
logger.info(f"Client ID: {client.user.id}")
@@ -2883,6 +2963,137 @@ def create_warnings_table():
if connection:
close_database_connection(connection)
def create_contact_messages_table():
"""Creates the contact_messages table if it doesn't exist"""
connection = None
cursor = None
try:
connection = connect_to_database()
cursor = connection.cursor()
create_table_query = """
CREATE TABLE IF NOT EXISTS contact_messages (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id VARCHAR(50) NOT NULL,
username VARCHAR(100) NOT NULL,
subject VARCHAR(100) NOT NULL,
category VARCHAR(50) NOT NULL,
priority VARCHAR(20) NOT NULL,
message TEXT NOT NULL,
server_context VARCHAR(200),
submitted_at BIGINT NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
responded_at BIGINT,
response TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id),
INDEX idx_status (status),
INDEX idx_submitted_at (submitted_at)
)
"""
cursor.execute(create_table_query)
connection.commit()
logger.info("Contact messages table checked/created successfully")
except Exception as e:
logger.error(f"Error creating contact messages table: {e}")
finally:
if cursor:
cursor.close()
if connection:
close_database_connection(connection)
async def send_contact_message_to_admin(message_data):
"""Sends a contact message to the admin via Discord DM"""
try:
# Your Discord User ID
ADMIN_DISCORD_ID = 253922739709018114
admin_user = client.get_user(ADMIN_DISCORD_ID)
if not admin_user:
admin_user = await client.fetch_user(ADMIN_DISCORD_ID)
if admin_user:
# Priority emoji mapping
priority_emojis = {
"low": "🟢",
"medium": "🟡",
"high": "🟠",
"urgent": "🔴"
}
# Category emoji mapping
category_emojis = {
"bug_report": "🐛",
"feature_request": "💡",
"account_issue": "👤",
"moderation": "🛡️",
"giveaway": "🎁",
"privacy": "🔒",
"technical": "⚙️",
"other": ""
}
# Create Discord Embed
embed = discord.Embed(
title="📨 New Contact Form Submission",
color=0x667eea,
timestamp=datetime.utcnow()
)
# User Information
embed.add_field(
name="👤 User Information",
value=f"**Name:** {message_data.get('user_name', 'Unknown')}\n"
f"**Username:** {message_data.get('username', 'Unknown')}\n"
f"**Discord ID:** `{message_data.get('user_id', 'Unknown')}`",
inline=False
)
# Message Details
embed.add_field(
name="📋 Message Details",
value=f"**Subject:** {message_data.get('subject', 'No subject')}\n"
f"**Category:** {category_emojis.get(message_data.get('category', 'other'), '')} {message_data.get('category', 'other').replace('_', ' ').title()}\n"
f"**Priority:** {priority_emojis.get(message_data.get('priority', 'low'), '')} {message_data.get('priority', 'low').upper()}",
inline=False
)
# Server Context (if provided)
if message_data.get('server_context'):
embed.add_field(
name="🖥️ Server Context",
value=message_data.get('server_context'),
inline=False
)
# Message Content
message_content = message_data.get('message', 'No message content')
if len(message_content) > 1024:
message_content = message_content[:1021] + "..."
embed.add_field(
name="💬 Message",
value=f"```{message_content}```",
inline=False
)
# Footer
embed.set_footer(text="Multus Bot Web Panel Contact Form")
# Set avatar thumbnail if available
if message_data.get('avatar_url'):
embed.set_thumbnail(url=message_data.get('avatar_url'))
await admin_user.send(embed=embed)
logger.info(f"Contact message sent to admin for user {message_data.get('user_id')}")
return True
except Exception as e:
logger.error(f"Error sending contact message to admin: {e}")
return False
async def get_user_warnings(user_id, guild_id, active_only=True):
"""Retrieves warning records for a user
@@ -5263,9 +5474,169 @@ async def delnotes(ctx):
else:
await send_response(f"No notes found for user {ctx.author.name}.")
@client.command()
async def process_contact_messages(ctx):
"""Prozessiert ausstehende Kontaktnachrichten (Admin only)"""
if ctx.author.id != 253922739709018114: # Ihre Discord ID
await ctx.send("You don't have permission to use this command.")
return
try:
connection = connect_to_database()
cursor = connection.cursor()
# Hole alle pending Nachrichten
cursor.execute("""
SELECT id, user_id, username, subject, category, priority, message,
server_context, submitted_at
FROM contact_messages
WHERE status = 'pending'
ORDER BY submitted_at ASC
""")
pending_messages = cursor.fetchall()
if not pending_messages:
await ctx.send("No pending contact messages found.")
cursor.close()
close_database_connection(connection)
return
processed_count = 0
for msg in pending_messages:
msg_id, user_id, username, subject, category, priority, message, server_context, submitted_at = msg
try:
# Hole User-Informationen von Discord
user = client.get_user(int(user_id))
if not user:
user = await client.fetch_user(int(user_id))
message_data = {
'user_id': user_id,
'user_name': user.display_name if user else username.split('#')[0],
'username': username,
'avatar_url': user.avatar.url if user and user.avatar else None,
'subject': subject,
'category': category,
'priority': priority,
'message': message,
'server_context': server_context
}
# Sende an Admin
success = await send_contact_message_to_admin(message_data)
if success:
# Markiere als versendet
cursor.execute("""
UPDATE contact_messages
SET status = 'sent', responded_at = %s
WHERE id = %s
""", (int(time.time()), msg_id))
processed_count += 1
except Exception as e:
logger.error(f"Error processing contact message {msg_id}: {e}")
continue
connection.commit()
cursor.close()
close_database_connection(connection)
await ctx.send(f"Processed {processed_count}/{len(pending_messages)} contact messages successfully.")
except Exception as e:
await ctx.send(f"Error processing contact messages: {e}")
logger.error(f"Error in process_contact_messages: {e}")
@client.command()
async def contact_status(ctx):
"""Zeigt den Status der Kontaktnachrichten-Überwachung (Admin only)"""
if ctx.author.id != 253922739709018114: # Ihre Discord ID
await ctx.send("You don't have permission to use this command.")
return
try:
connection = connect_to_database()
cursor = connection.cursor()
# Statistiken abrufen
cursor.execute("SELECT COUNT(*) FROM contact_messages WHERE status = 'pending'")
pending_count = cursor.fetchone()[0]
cursor.execute("SELECT COUNT(*) FROM contact_messages WHERE status = 'sent'")
sent_count = cursor.fetchone()[0]
cursor.execute("SELECT COUNT(*) FROM contact_messages")
total_count = cursor.fetchone()[0]
# Letzte Nachricht info
cursor.execute("""
SELECT subject, submitted_at FROM contact_messages
ORDER BY submitted_at DESC LIMIT 1
""")
last_message = cursor.fetchone()
cursor.close()
close_database_connection(connection)
# Status des Task Loops
task_status = "🟢 Running" if check_contact_messages.is_running() else "🔴 Stopped"
# Nächste Ausführung berechnen
if check_contact_messages.is_running():
next_run = check_contact_messages.next_iteration
if next_run:
next_run_str = f"<t:{int(next_run.timestamp())}:R>"
else:
next_run_str = "Soon"
else:
next_run_str = "Task not running"
embed = discord.Embed(
title="📊 Contact Messages Status",
color=0x667eea,
timestamp=datetime.utcnow()
)
embed.add_field(
name="📋 Message Statistics",
value=f"**Pending:** {pending_count}\n"
f"**Processed:** {sent_count}\n"
f"**Total:** {total_count}",
inline=True
)
embed.add_field(
name="⏰ Task Status",
value=f"**Status:** {task_status}\n"
f"**Interval:** Every 15 minutes\n"
f"**Next Check:** {next_run_str}",
inline=True
)
if last_message:
last_subject = last_message[0][:50] + "..." if len(last_message[0]) > 50 else last_message[0]
embed.add_field(
name="📝 Latest Message",
value=f"**Subject:** {last_subject}\n"
f"**Submitted:** <t:{int(last_message[1])}:R>",
inline=False
)
embed.set_footer(text="Contact Messages Auto-Check System")
await ctx.send(embed=embed)
except Exception as e:
await ctx.send(f"Error getting contact status: {e}")
logger.error(f"Error in contact_status: {e}")
try:
# Initialize database tables
create_warnings_table()
create_contact_messages_table()
logger.info("Database tables initialized successfully")
loop.run_until_complete(client.start(TOKEN))