Initial commit
This commit is contained in:
commit
bed95c3111
2 changed files with 323 additions and 0 deletions
186
bot.py
Normal file
186
bot.py
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
import discord
|
||||
from discord.ext import commands, tasks
|
||||
from datetime import datetime, timedelta
|
||||
import json
|
||||
import pytz
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
# Retrieve the bot token from the environment variable
|
||||
TOKEN = os.getenv('DISCORD_BOT_TOKEN')
|
||||
|
||||
# Set up intents
|
||||
intents = discord.Intents.default()
|
||||
intents.members = True
|
||||
intents.message_content = True
|
||||
bot = commands.Bot(command_prefix='/tp ', intents=intents)
|
||||
|
||||
# File path for tickets data
|
||||
TICKETS_FILE = 'tickets.json'
|
||||
|
||||
# Load or initialize tickets data
|
||||
def load_tickets_data():
|
||||
if os.path.exists(TICKETS_FILE):
|
||||
with open(TICKETS_FILE, 'r') as f:
|
||||
try:
|
||||
data = json.load(f)
|
||||
print("Loaded tickets data:", data) # Debug log
|
||||
return data
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"Error loading JSON data: {e}")
|
||||
return {}
|
||||
return {}
|
||||
|
||||
tickets_data = load_tickets_data()
|
||||
|
||||
# Helper function to save tickets data
|
||||
def save_tickets_data():
|
||||
with open(TICKETS_FILE, 'w') as f:
|
||||
json.dump(tickets_data, f, indent=4)
|
||||
print("Saved tickets data:", tickets_data) # Debug log
|
||||
|
||||
# Helper function to reload tickets data from the file
|
||||
def reload_tickets_data():
|
||||
global tickets_data
|
||||
tickets_data = load_tickets_data()
|
||||
|
||||
# Command to assign a ticket
|
||||
@bot.command()
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def assign_ticket(ctx, member: discord.Member, email: str, ticket_type: str = "normal"):
|
||||
if ticket_type not in ["normal", "golden"]:
|
||||
await ctx.send("Invalid ticket type. Use 'normal' or 'golden'.")
|
||||
return
|
||||
|
||||
member_id = str(member.id) # Ensure ID is a string
|
||||
if member_id not in tickets_data:
|
||||
tickets_data[member_id] = {"email": email, "tickets": []}
|
||||
|
||||
if ticket_type == "normal":
|
||||
# Assign an individual expiration date for the normal ticket
|
||||
expiration_date = datetime.utcnow() + timedelta(days=365)
|
||||
tickets_data[member_id]["tickets"].append({
|
||||
"type": "normal",
|
||||
"expiration": expiration_date.isoformat()
|
||||
})
|
||||
expiration_message = f", which expires on {expiration_date.strftime('%Y-%m-%d %H:%M:%S')} UTC."
|
||||
else:
|
||||
# Golden tickets do not expire
|
||||
tickets_data[member_id]["tickets"].append({
|
||||
"type": "golden",
|
||||
"expiration": None
|
||||
})
|
||||
expiration_message = ""
|
||||
|
||||
save_tickets_data()
|
||||
reload_tickets_data() # Reload the tickets data to ensure consistency
|
||||
await ctx.send(f"Assigned a {ticket_type} ticket to {member.mention}{expiration_message}.")
|
||||
|
||||
# Command to redeem a ticket
|
||||
@bot.command()
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def redeem_ticket(ctx, member: discord.Member, ticket_type: str):
|
||||
if ticket_type not in ["normal", "golden"]:
|
||||
await ctx.send("Invalid ticket type. Use 'normal' or 'golden'.")
|
||||
return
|
||||
|
||||
member_id = str(member.id) # Ensure ID is a string
|
||||
if member_id not in tickets_data or not tickets_data[member_id]["tickets"]:
|
||||
await ctx.send(f"{member.mention} does not have any tickets.")
|
||||
return
|
||||
|
||||
for i, ticket in enumerate(tickets_data[member_id]["tickets"]):
|
||||
if ticket["type"] == ticket_type:
|
||||
del tickets_data[member_id]["tickets"][i]
|
||||
save_tickets_data()
|
||||
reload_tickets_data() # Reload the tickets data to ensure consistency
|
||||
await ctx.send(f"Redeemed a {ticket_type} ticket for {member.mention}.")
|
||||
return
|
||||
|
||||
await ctx.send(f"{member.mention} does not have any {ticket_type} tickets to redeem.")
|
||||
|
||||
# Command to check a user's tickets (admins only)
|
||||
@bot.command()
|
||||
@commands.has_permissions(administrator=True)
|
||||
async def check_ticket(ctx, member: discord.Member):
|
||||
member_id = str(member.id) # Ensure ID is a string
|
||||
if member_id not in tickets_data or not tickets_data[member_id]["tickets"]:
|
||||
await ctx.send(f"{member.mention} does not have any tickets.")
|
||||
return
|
||||
|
||||
ticket_info = tickets_data[member_id]["tickets"]
|
||||
normal_tickets = [t for t in ticket_info if t["type"] == "normal"]
|
||||
golden_tickets = [t for t in ticket_info if t["type"] == "golden"]
|
||||
|
||||
# Timezone definitions
|
||||
tz_utc = pytz.UTC
|
||||
tz_mst = pytz.timezone('America/Edmonton')
|
||||
|
||||
normal_message = f"{member.mention} has {len(normal_tickets)} normal tickets:\n"
|
||||
for ticket in normal_tickets:
|
||||
expiration_date_utc = datetime.fromisoformat(ticket["expiration"]).astimezone(tz_utc)
|
||||
expiration_date_mst = expiration_date_utc.astimezone(tz_mst)
|
||||
normal_message += f"- Expires on {expiration_date_utc.strftime('%Y-%m-%d %H:%M:%S')} UTC / {expiration_date_mst.strftime('%Y-%m-%d %H:%M:%S')} MST\n"
|
||||
|
||||
golden_message = f"{member.mention} has {len(golden_tickets)} golden tickets."
|
||||
|
||||
await ctx.send(f"{normal_message}{golden_message}")
|
||||
|
||||
# Command to check your own tickets (all users)
|
||||
@bot.command()
|
||||
async def tickets(ctx):
|
||||
member_id = str(ctx.author.id) # Ensure ID is a string
|
||||
if member_id not in tickets_data or not tickets_data[member_id]["tickets"]:
|
||||
# Send a DM if no tickets are found
|
||||
await ctx.author.send("You do not have any tickets.")
|
||||
await ctx.send("I have sent you a DM with your ticket information.")
|
||||
return
|
||||
|
||||
ticket_info = tickets_data[member_id]["tickets"]
|
||||
normal_tickets = [t for t in ticket_info if t["type"] == "normal"]
|
||||
golden_tickets = [t for t in ticket_info if t["type"] == "golden"]
|
||||
|
||||
normal_message = f"You have {len(normal_tickets)} normal tickets:\n"
|
||||
for ticket in normal_tickets:
|
||||
expiration_date = datetime.fromisoformat(ticket["expiration"])
|
||||
normal_message += f"- Expires on {expiration_date.strftime('%Y-%m-%d %H:%M:%S')} UTC\n"
|
||||
|
||||
golden_message = f"You have {len(golden_tickets)} golden tickets."
|
||||
|
||||
# Send the result to the user via DM
|
||||
await ctx.author.send(f"{normal_message}\n{golden_message}")
|
||||
await ctx.send("I have sent you a DM with your ticket information.")
|
||||
|
||||
# Background task to check and remove expired tickets
|
||||
@tasks.loop(hours=24)
|
||||
async def check_expired_tickets():
|
||||
tz = pytz.UTC
|
||||
current_time = datetime.now(tz)
|
||||
to_remove = []
|
||||
|
||||
for member_id, ticket_info in tickets_data.items():
|
||||
tickets_data[member_id]["tickets"] = [
|
||||
ticket for ticket in ticket_info["tickets"]
|
||||
if ticket["type"] == "golden" or current_time < datetime.fromisoformat(ticket["expiration"]).astimezone(tz)
|
||||
]
|
||||
|
||||
# Remove the member if they have no tickets left
|
||||
if not tickets_data[member_id]["tickets"]:
|
||||
to_remove.append(member_id)
|
||||
|
||||
for member_id in to_remove:
|
||||
print(f"Removing expired tickets for user ID: {member_id}") # Debug log
|
||||
del tickets_data[member_id]
|
||||
|
||||
save_tickets_data()
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
print(f'Logged in as {bot.user.name}')
|
||||
check_expired_tickets.start()
|
||||
|
||||
# Run the bot
|
||||
bot.run(TOKEN)
|
||||
137
tickets.json
Normal file
137
tickets.json
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
{
|
||||
"272518615356538887": {
|
||||
"email": "seifer.moringa@gmail.com",
|
||||
"tickets": [
|
||||
{
|
||||
"type": "golden",
|
||||
"expiration": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"928079996403212429": {
|
||||
"email": "metalarms127@gmail.com",
|
||||
"tickets": [
|
||||
{
|
||||
"type": "golden",
|
||||
"expiration": null
|
||||
},
|
||||
{
|
||||
"type": "golden",
|
||||
"expiration": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"526179144967520257": {
|
||||
"email": "nyrvaan@gmail.com",
|
||||
"tickets": [
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2026-10-28T01:04:21.726082"
|
||||
},
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2026-10-28T01:05:18.289342"
|
||||
}
|
||||
]
|
||||
},
|
||||
"865708915924533248": {
|
||||
"email": "romangraham07@gmail.com",
|
||||
"tickets": [
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2026-05-30T01:40:52.106310"
|
||||
},
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2027-04-07T00:09:45.822523"
|
||||
}
|
||||
]
|
||||
},
|
||||
"1131710863343091722": {
|
||||
"email": "atomiccryo@gmail.com",
|
||||
"tickets": [
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2026-05-30T01:41:46.157234"
|
||||
},
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2026-11-01T20:06:20.779733"
|
||||
},
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2027-04-07T00:17:19.067922"
|
||||
}
|
||||
]
|
||||
},
|
||||
"348204092709142538": {
|
||||
"email": "micahelacostapsyd@gmail.com",
|
||||
"tickets": [
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2026-06-01T05:00:16.756179"
|
||||
}
|
||||
]
|
||||
},
|
||||
"267100324127440907": {
|
||||
"email": "mskintner@gmail.com",
|
||||
"tickets": [
|
||||
{
|
||||
"type": "golden",
|
||||
"expiration": null
|
||||
},
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2027-05-01T20:40:03.987511"
|
||||
},
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2027-05-01T20:40:08.497594"
|
||||
},
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2027-05-01T20:40:10.222346"
|
||||
},
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2027-05-01T20:40:11.817248"
|
||||
}
|
||||
]
|
||||
},
|
||||
"1097655473337016481": {
|
||||
"email": "spectre1kj@gmail.com",
|
||||
"tickets": [
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2026-10-25T02:02:36.677040"
|
||||
}
|
||||
]
|
||||
},
|
||||
"265268782455324692": {
|
||||
"email": "hansthelarson@gmail.com",
|
||||
"tickets": [
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2026-10-28T00:46:43.282249"
|
||||
}
|
||||
]
|
||||
},
|
||||
"171471851590123520": {
|
||||
"email": "cartmachine@gmail.com",
|
||||
"tickets": [
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2026-10-29T08:30:40.170348"
|
||||
}
|
||||
]
|
||||
},
|
||||
"928442689874165771": {
|
||||
"email": "Limdul3000@gmail.com",
|
||||
"tickets": [
|
||||
{
|
||||
"type": "normal",
|
||||
"expiration": "2027-02-21T22:17:34.693537"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue