forked from blavese/repo
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
146 lines (115 loc) · 5.6 KB
/
Copy pathmain.py
File metadata and controls
146 lines (115 loc) · 5.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import discord
from discord.ext import commands
import logging
from dotenv import load_dotenv
import os
import asyncio
import webserver
# --- 1. SETUP & CONFIGURATION ---
load_dotenv()
token = os.getenv('ecd') # Your existing token variable
GUILD_ID = int(os.getenv('GID') or 0) # Add this to your .env
CATEGORY_ID = int(os.getenv('CID') or 0) # Add this to your .env
# Enable intents (Crucial for reading members, DMs, and message content)
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
bot = commands.Bot(command_prefix='!', intents=intents)
# Remove the default help command so we can create a custom one
bot.remove_command('help')
# --- 2. HELP COMMAND ---
@bot.command(name='help', help='Shows this message.')
async def custom_help(ctx):
"""Custom help command using an Embed."""
embed = discord.Embed(
title="Modmail Commands List",
description="Commands for managing user Modmail tickets.",
color=discord.Color.blue()
)
embed.add_field(name="✉️ !reply <message>", value="Replies to the user in the current ticket channel.", inline=False)
embed.add_field(name="🔒 !close", value="Closes and deletes the current ticket channel.", inline=False)
embed.set_footer(text=f"Requested by {ctx.author.display_name}",
icon_url=ctx.author.avatar.url if ctx.author.avatar else None)
await ctx.send(embed=embed)
# --- 3. MODMAIL LOGIC (DMs to Server & Server to DMs) ---
@bot.event
async def on_message(message):
# Ignore the bot's own messages
if message.author.bot:
return
# A. Handle DMs sent to the bot (User -> Mod)
if isinstance(message.channel, discord.DMChannel):
guild = bot.get_guild(GUILD_ID)
if not guild:
return
category = discord.utils.get(guild.categories, id=CATEGORY_ID)
if not category:
print("[ERROR] Modmail category not found. Check CATEGORY_ID in .env")
return
# Check if a channel for this user already exists
channel_name = f"ticket-{message.author.id}"
ticket_channel = discord.utils.get(category.text_channels, name=channel_name)
# Create a new ticket channel if one doesn't exist
if not ticket_channel:
ticket_channel = await guild.create_text_channel(
name=channel_name,
category=category,
topic=f"User ID: {message.author.id}" # Storing ID here is crucial for replies
)
await ticket_channel.send(f"🚨 **New Ticket Opened by {message.author.mention}**\nUse `!reply <message>` to respond or `!close` to end it.")
# Construct an embed to relay the user's message
embed = discord.Embed(description=message.content, color=discord.Color.blue())
embed.set_author(name=message.author, icon_url=message.author.display_avatar.url)
# Forward attachments (images, files)
if message.attachments:
embed.set_image(url=message.attachments[0].url)
await ticket_channel.send(embed=embed)
await message.add_reaction("✅")
# B. Handle Mod replies in the server (Mod -> User)
elif message.guild and message.channel.category_id == CATEGORY_ID:
if message.content.startswith("!reply "):
try:
# Extract user ID from the channel topic
user_id = int(message.channel.topic.split(": ")[1])
user = bot.get_user(user_id) or await bot.fetch_user(user_id)
except (ValueError, AttributeError, IndexError):
await message.channel.send("❌ Error: Could not find the linked user for this ticket.")
return
# Slice off the "!reply " command to get the actual message
reply_content = message.content[len("!reply "):]
embed = discord.Embed(description=reply_content, color=discord.Color.green())
embed.set_author(name=message.author, icon_url=message.author.display_avatar.url)
embed.set_footer(text="Staff Reply")
try:
await user.send(embed=embed)
await message.add_reaction("✅")
except discord.Forbidden:
await message.channel.send("❌ Error: Cannot send messages to this user (DMs disabled).")
# Process standard commands (!close, !help)
await bot.process_commands(message)
# --- 4. CLOSE COMMAND ---
@bot.command(name='close', help='Closes the current Modmail ticket.')
@commands.has_permissions(manage_channels=True)
async def close(ctx):
"""Closes the current Modmail ticket channel."""
if ctx.channel.category_id == CATEGORY_ID:
await ctx.send("🔒 Closing this ticket in 5 seconds...")
await asyncio.sleep(5)
await ctx.channel.delete()
else:
await ctx.send("❌ This command can only be used inside a Modmail ticket channel.")
# --- 5. GLOBAL ERROR HANDLING ---
@bot.event
async def on_command_error(ctx, error):
"""A global error handler that catches errors for ALL commands."""
if isinstance(error, commands.MissingPermissions):
await ctx.send("❌ You do not have the required permissions to use this command.")
elif isinstance(error, commands.MissingRequiredArgument):
await ctx.send(f"❌ Missing a required argument: `{error.param.name}`. Type `!help` for usage.")
elif isinstance(error, commands.BadArgument):
await ctx.send("❌ Invalid argument provided.")
webserver.keep_alive()
# --- 6. RUN THE BOT ---
if __name__ == '__main__':
print("🚀 Starting Modmail Bot...")
bot.run(token, log_level=logging.DEBUG)