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:
371
bot.py
371
bot.py
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user