Search code examples
pythondiscord.pydiscord-interactions

How can i send an ephemeral message in discord.py?


I want a bot to respond with an ephemeral message to a custom command called /help in discord.py. So that when i send /help in my discord server, the message that the user sent gets removed and the bot responds with an ephemeral message.

I have tried to use ctx and discord.InteractionResponse instead of discord.Interaction but it will just return with an error, like: discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'Context' object has no attribute 'response'.

And here is the code:

import discord
from discord.ext import commands

TOKEN = 'my_token'

intents = discord.Intents.default()
intents.message_content = True

bot = commands.Bot(command_prefix='/', intents=intents)

help_text = 'This is a help text'

@bot.event
async def on_ready():
    print(f"{bot.user} is now up and running.")

bot.remove_command('help')

@bot.command()
    async def help(ctx, interaction: discord.Interaction):
        await ctx.channel.purge(limit=1) # Remove the user message
        # await ctx.send(help_text)
        
        # interaction = discord.InteractionResponse
        await interaction.response.send_message(content="Hello", ephemeral=True) # Should send a ephemeral message

bot.run(TOKEN)


Solution

  • You are using a normal commands rather than an interaction. You can think of interaction based stuff as predefined commands you notify discord about. Whenever a new command is created, you have to sync it.

    Calling purge on a channel to remove one message isn't a good idea. If anyone sends a message between the command and response, it might end up deleting the normal message instead.

    Command result example

    import discord
    from discord import app_commands
    TOKEN = 'TOKEN'
    
    intents = discord.Intents.default()
    intents.message_content = True
    bot = discord.Client(intents=intents)
    tree=app_commands.CommandTree(bot)
    
    @tree.command(name="help", description="A basic help command.")
    async def help(interaction):
        #  Since now we have interaction we can send the message as an ephemeral message.
        #  We also dont have to deal with deleting the command message.
        await interaction.response.send_message(content="Help command.", ephemeral=True)
    
    @bot.event
    async def on_ready():
        # Sync commands on command tree with discord.
        await tree.sync()
        print(f"{bot.user} is now up and running.")
        
    bot.run(TOKEN)