Discord机器人开发问题:实现角色定时移除与恢复功能时遭遇Unexpected Indent错误
Fixing Your Discord Bot's Indent Error & Implementing Timed Role Removal/Restoration
Hey there! Let's work through your indent error first, then get that timed role functionality fully working. Here's a breakdown of the issues and a polished, functional solution:
1. Root Causes of Your Indent & Code Issues
Let's start with the bugs that are breaking your code:
- Misplaced Indentation: Your
listrolesandrolesfunctions were defined outside theMyClientclass but weren't structured correctly for Discord's event system. Plus, usingdiscord.Clientmakes command handling clunky—we'll switch tocommands.Botwhich is built for this. - Bad Imports:
import ctxis unnecessary (ctx is a command context passed automatically, not a module)from time time import sleephas a typo—should befrom time import sleepfrom discord.ext import rolelist, roles, rolereferences non-existent modules; delete these entirely
- Duplicate Function Definitions: You have two
async def roles():functions, which will overwrite each other and cause errors. - Scope Problems: Variables like
userandmessageweren't accessible in your standalone functions since they're local to theon_messageevent.
2. Core Logic for Timed Role Management
To make the role removal/restoration work, we need to:
- Capture the target user's existing roles (excluding the default
@everyonerole) - Remove all those roles and assign the
Jailrole - Wait a specified amount of time
- Remove the
Jailrole and restore the user's original roles
3. Fully Corrected & Functional Code
import discord from discord.ext import commands from time import sleep # Use commands.Bot for cleaner command handling, set prefix to ! bot = commands.Bot(command_prefix='!', intents=discord.Intents.all()) @bot.event async def on_ready(): print(f'Logged in as {bot.user}!') @bot.command(name='sendtocourt') async def send_to_court(ctx, member: discord.Member): # Save the user's original roles (skip the default @everyone role) original_roles = [role for role in member.roles if role != ctx.guild.default_role] # Remove all of the user's current roles await member.remove_roles(*original_roles) # Fetch the Jail role (error out if it doesn't exist) jail_role = discord.utils.get(ctx.guild.roles, name="Jail") if not jail_role: await ctx.send("Oops! I couldn't find a 'Jail' role on this server.") return # Assign the Jail role and notify the channel await member.add_roles(jail_role) await ctx.send(f"🔒 Sent {member.mention} to court! They'll be released in 60 seconds.") # Wait 60 seconds (use asyncio.sleep instead if you need to handle other events during the wait) sleep(60) # Restore the user's original roles and notify await member.remove_roles(jail_role) await member.add_roles(*original_roles) await ctx.send(f"🔓 {member.mention} has been released from court!") # Replace with your actual bot token from the Discord Developer Portal bot.run('YOUR_DISCORD_BOT_TOKEN')
Quick Notes for Setup
- Intents: Make sure you enable
Server Members IntentandMessage Content Intentin your Discord Developer Portal under the "Privileged Gateway Intents" section—this lets the bot access member and message data. - Customize Wait Time: Change the
60insleep(60)to any number of seconds you want, or add a parameter to the command (e.g.,!sendtocourt @User 120for 2 minutes). - Command Prefix: Adjust
command_prefix='!'to whatever prefix you prefer (like$or?).
内容的提问来源于stack exchange,提问作者Ethan




