I want to set up my discord bot so it can handle commands sent through direct messages instead of just in servers. The main goal is to create a private message command that would remove my ban from all servers where the bot exists.
I’m not sure if this is even doable with discord.py. I need the bot to process DMs as valid commands but only when they come from my user account. My user ID is saved in a variable called adminID.
Here’s an example of how my current server commands work:
@client.command(pass_context=True)
async def roll(ctx, lowNum, highNum):
if ctx.message.author.server_permissions.send_messages or ctx.message.author.id == adminID:
highNum = int(highNum)
lowNum = int(lowNum)
result = random.randint(lowNum, highNum)
result = str(result)
await client.send_message(ctx.message.channel, 'Random result: ' + result)
else:
await client.send_message(ctx.message.channel, 'Access denied @{}!'.format(ctx.message.author))
Can someone help me modify this to work with private messages? Also any sample code for the unban feature would be great.
Hit this exact problem last year building a moderation bot. Everyone else missed the context handling - DMs work differently than server channels. Wrap your DM commands in try-catch blocks since server methods will break in private channels. For unbans, store which servers banned the user instead of trying to unban from every server. Saves API calls and avoids rate limits. If your bot gets kicked from a server while you’re banned, it can’t unban you later - obvious but easy to miss. Discord.py methods return different data types in DMs vs server channels, so test everything. Permission checking works but handle cases where your bot doesn’t have unban perms in some servers.
For DM commands in discord.py, check if the channel is private and verify the sender’s ID matches your adminID. DMs don’t have server context, so you can’t check server permissions like usual.
Here’s how to modify your command:
@client.command(pass_context=True)
async def unban(ctx):
if ctx.message.channel.is_private and ctx.message.author.id == adminID:
for server in client.servers:
try:
await client.unban(server, ctx.message.author)
except:
pass # Bot might not have permissions or user not banned
await client.send_message(ctx.message.channel, 'Unban attempted on all servers')
elif not ctx.message.channel.is_private:
await client.send_message(ctx.message.channel, 'This command only works in DMs')
The is_private attribute tells you if it’s a DM. Your roll command works the same way - just swap the permission check for private channel + adminID verification. Make sure your bot has unban permissions in each server though.
yeah, this works but watch out for discord.py versions. newer ones use isinstance(ctx.channel, discord.DMChannel) since is_private got deprecated. if you’re in a ton of servers, the unban loop might timeout - throw in some delays between attempts.