modified: Dockerfile
modified: bot.py modified: requirements.txt
This commit is contained in:
@@ -21,6 +21,11 @@ COPY . .
|
|||||||
|
|
||||||
# Environment variables
|
# Environment variables
|
||||||
ENV DISCORD_TOKEN=$DISCORD_TOKEN
|
ENV DISCORD_TOKEN=$DISCORD_TOKEN
|
||||||
|
ENV MYSQL_HOST=$MYSQL_HOST
|
||||||
|
ENV MYSQL_PORT=$MYSQL_PORT
|
||||||
|
ENV MYSQL_USER=$MYSQL_USER
|
||||||
|
ENV MYSQL_PASSWORD=$MYSQL_PASSWORD
|
||||||
|
ENV MYSQL_DATABASE=$MYSQL_DATABASE
|
||||||
|
|
||||||
# Start the bot
|
# Start the bot
|
||||||
CMD ["python", "bot.py"]
|
CMD ["python", "bot.py"]
|
||||||
|
|||||||
62
bot.py
62
bot.py
@@ -5,6 +5,7 @@ import os
|
|||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import json
|
import json
|
||||||
|
import mysql.connector
|
||||||
|
|
||||||
# Load environment variables
|
# Load environment variables
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
@@ -17,6 +18,43 @@ intents.guilds = True
|
|||||||
|
|
||||||
bot = commands.Bot(command_prefix='!', intents=intents)
|
bot = commands.Bot(command_prefix='!', intents=intents)
|
||||||
|
|
||||||
|
# MySQL connection setup
|
||||||
|
MYSQL_HOST = os.getenv('MYSQL_HOST', 'localhost')
|
||||||
|
MYSQL_PORT = int(os.getenv('MYSQL_PORT', '3306'))
|
||||||
|
MYSQL_USER = os.getenv('MYSQL_USER', 'root')
|
||||||
|
MYSQL_PASSWORD = os.getenv('MYSQL_PASSWORD', '')
|
||||||
|
MYSQL_DATABASE = os.getenv('MYSQL_DATABASE', 'tickets')
|
||||||
|
|
||||||
|
def get_db_connection():
|
||||||
|
return mysql.connector.connect(
|
||||||
|
host=MYSQL_HOST,
|
||||||
|
port=MYSQL_PORT,
|
||||||
|
user=MYSQL_USER,
|
||||||
|
password=MYSQL_PASSWORD,
|
||||||
|
database=MYSQL_DATABASE
|
||||||
|
)
|
||||||
|
|
||||||
|
def init_db():
|
||||||
|
conn = get_db_connection()
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS tickets (
|
||||||
|
ticket_id VARCHAR(32) PRIMARY KEY,
|
||||||
|
message_id BIGINT,
|
||||||
|
channel_id BIGINT,
|
||||||
|
title VARCHAR(255),
|
||||||
|
project VARCHAR(255),
|
||||||
|
status VARCHAR(32),
|
||||||
|
creator BIGINT,
|
||||||
|
created_at VARCHAR(32),
|
||||||
|
reference_message_id VARCHAR(32),
|
||||||
|
archived BOOLEAN DEFAULT FALSE
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
# Ticket storage (in production, use a database)
|
# Ticket storage (in production, use a database)
|
||||||
tickets = {}
|
tickets = {}
|
||||||
ticket_counter = 1
|
ticket_counter = 1
|
||||||
@@ -51,6 +89,7 @@ def save_config():
|
|||||||
async def on_ready():
|
async def on_ready():
|
||||||
print(f'{bot.user} has connected to Discord!')
|
print(f'{bot.user} has connected to Discord!')
|
||||||
load_config()
|
load_config()
|
||||||
|
init_db()
|
||||||
try:
|
try:
|
||||||
synced = await bot.tree.sync()
|
synced = await bot.tree.sync()
|
||||||
print(f"Synced {len(synced)} command(s)")
|
print(f"Synced {len(synced)} command(s)")
|
||||||
@@ -139,7 +178,7 @@ async def create_ticket(
|
|||||||
ticket_message = await active_channel.send(embed=embed)
|
ticket_message = await active_channel.send(embed=embed)
|
||||||
|
|
||||||
# Store ticket data
|
# Store ticket data
|
||||||
tickets[ticket_id] = {
|
ticket = {
|
||||||
"message_id": ticket_message.id,
|
"message_id": ticket_message.id,
|
||||||
"channel_id": active_channel.id,
|
"channel_id": active_channel.id,
|
||||||
"title": title,
|
"title": title,
|
||||||
@@ -149,6 +188,7 @@ async def create_ticket(
|
|||||||
"created_at": datetime.utcnow().isoformat(),
|
"created_at": datetime.utcnow().isoformat(),
|
||||||
"reference_message_id": message_id
|
"reference_message_id": message_id
|
||||||
}
|
}
|
||||||
|
save_ticket(ticket_id, ticket)
|
||||||
|
|
||||||
# Confirm to user
|
# Confirm to user
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
@@ -180,16 +220,14 @@ async def update_status(
|
|||||||
# Convert to uppercase for consistency
|
# Convert to uppercase for consistency
|
||||||
ticket_id = ticket_id.upper()
|
ticket_id = ticket_id.upper()
|
||||||
|
|
||||||
# Check if ticket exists
|
ticket = load_ticket(ticket_id)
|
||||||
if ticket_id not in tickets:
|
if not ticket:
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
f"❌ Ticket `{ticket_id}` not found!",
|
f"❌ Ticket `{ticket_id}` not found!",
|
||||||
ephemeral=True
|
ephemeral=True
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
ticket = tickets[ticket_id]
|
|
||||||
|
|
||||||
# Map status choice to display text
|
# Map status choice to display text
|
||||||
status_map = {
|
status_map = {
|
||||||
"pending": TicketStatus.PENDING,
|
"pending": TicketStatus.PENDING,
|
||||||
@@ -201,6 +239,7 @@ async def update_status(
|
|||||||
old_status = ticket["status"]
|
old_status = ticket["status"]
|
||||||
new_status_text = status_map[new_status]
|
new_status_text = status_map[new_status]
|
||||||
ticket["status"] = new_status_text
|
ticket["status"] = new_status_text
|
||||||
|
save_ticket(ticket_id, ticket)
|
||||||
|
|
||||||
# Get the ticket message
|
# Get the ticket message
|
||||||
channel = bot.get_channel(ticket["channel_id"])
|
channel = bot.get_channel(ticket["channel_id"])
|
||||||
@@ -291,8 +330,10 @@ async def archive_ticket(interaction, ticket_id, message, current_channel):
|
|||||||
await message.delete()
|
await message.delete()
|
||||||
|
|
||||||
# Update ticket storage
|
# Update ticket storage
|
||||||
tickets[ticket_id]["channel_id"] = archive_channel.id
|
ticket = load_ticket(ticket_id)
|
||||||
tickets[ticket_id]["archived"] = True
|
ticket["channel_id"] = archive_channel.id
|
||||||
|
ticket["archived"] = True
|
||||||
|
save_ticket(ticket_id, ticket)
|
||||||
|
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
f"✅ Ticket `{ticket_id}` marked as completed and archived to {archive_channel.mention}",
|
f"✅ Ticket `{ticket_id}` marked as completed and archived to {archive_channel.mention}",
|
||||||
@@ -304,8 +345,7 @@ async def list_tickets(interaction: discord.Interaction):
|
|||||||
"""List all active tickets"""
|
"""List all active tickets"""
|
||||||
|
|
||||||
active_tickets = [
|
active_tickets = [
|
||||||
(tid, t) for tid, t in tickets.items()
|
(t["ticket_id"], t) for t in load_all_tickets(archived=False)
|
||||||
if not t.get("archived", False)
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if not active_tickets:
|
if not active_tickets:
|
||||||
@@ -340,14 +380,14 @@ async def ticket_info(interaction: discord.Interaction, ticket_id: str):
|
|||||||
|
|
||||||
ticket_id = ticket_id.upper()
|
ticket_id = ticket_id.upper()
|
||||||
|
|
||||||
if ticket_id not in tickets:
|
ticket = load_ticket(ticket_id)
|
||||||
|
if not ticket:
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
f"❌ Ticket `{ticket_id}` not found!",
|
f"❌ Ticket `{ticket_id}` not found!",
|
||||||
ephemeral=True
|
ephemeral=True
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
ticket = tickets[ticket_id]
|
|
||||||
creator = await bot.fetch_user(ticket["creator"])
|
creator = await bot.fetch_user(ticket["creator"])
|
||||||
|
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
discord.py>=2.3.0
|
discord.py>=2.3.0
|
||||||
python-dotenv>=1.0.0
|
python-dotenv>=1.0.0
|
||||||
aiohttp>=3.9.0
|
aiohttp>=3.9.0
|
||||||
|
mysql-connector-python>=8.0.0
|
||||||
Reference in New Issue
Block a user