How do you make a Discord bot respond to commands in DMs? (Python)

4.4k views Asked by At

I've just started writing Discord bots. I'm currently working on a bot that helps with Dungeons & Dragons games (dice rolling and initiative tracking are working at the moment). I've gotten my bot to send private rolls to a DM with the user that called the command within the server, but within the actual DM, the bot only responds to the help command.

I've read through this explanation, but it still doesn't seem useful to me, since I want it to respond to commands in DMs rather than grab the content of the messages sent to it in DMs. For example, let's say I'm in a server with the bot, and I use the whisperRoll command, which causes the bot to send me a DM with my dice roll result. Now that I have a private chat with the bot, I'd like to make another roll just for myself so that other players can't see it, so I try to use the roll command in the DM channel. What I'd like it to do is respond to the command in the DM in the same way it would respond in a server.

I'm wondering if there's possibly a set of default commands that are registered as "valid" for the bot to respond to in DMs that I'm missing? I can't really find an answer to this anywhere, and I don't even know where to start.

Thanks so much for the help!

EDIT: My current code, which is giving me a CommandInvokeError:

def _prefix_callable(bot, msg):
    prefix = '!'
    guild = msg.guild
    if p.prefixInfo == []:
        pass
    else:
        prefix = p.getPrefix(guild)
    
    if not guild:
        return commands.when_mentioned_or(prefix)(bot, msg)
    return commands.when_mentioned_or(prefix)(bot, msg)

bot = commands.Bot(command_prefix=_prefix_callable, description=description, help_command = None)

p.getPrefix(guild) calls this code:

def getPrefix(self, guild):
        for data in self.prefixInfo:
            if data[0] == str(hash(guild)):
                return data[1]
        return "!"

I'm currently having it search through a csv to find the right prefix for the given guild.

2

There are 2 answers

4
Axisnix On

For usage in dms with prefix

def get_prefix(message):
    prefix = "?"  # default prefix
    if not message.guild:  # if in dms
        return commands.when_mentioned_or(prefix)(bot, message)
    #you can set a guild/server specific one here
    return commands.when_mentioned_or(prefix)(bot, message)


bot = commands.Bot(command_prefix=get_prefix, case_insensitive=True) #bot allows you to make commands 

Then for the command, you would need to do:

@bot.command()
async def whisperroll(ctx):
    await ctx.author.send("some random thing")
0
Ian Cheung On

You can use the discord.channel.DMChannel object

For example:

async def check(ctx, arg):
    if isinstance(ctx.channel, discord.channel.DMChannel):
        await ctx.send(arg)