0
votes

What I'm trying to do is to make my discord bot send a message to a channel in my server when I supply it the command "!say" through DM.

I've tried a lot of different codes, but usually, it ends up with the Attribute Error "X object has no attribute Y"

from discord.ext import commands

bot = commands.Bot(command_prefix='!')

@bot.command()
async def say(ctx):
    channel = bot.get_channel('584307345065246725')
    await channel.send(ctx)

The error message always shows up when I DM the bot, expecting for it to send the required message.

2
The id you're passing to get_channel should be an int, not a string. Also, ctx is going to be an invocation context object, which doesn't work as the contents of a message. What exactly do you want to send? - Patrick Haugh

2 Answers

1
votes

There is a pretty simple thing going on with your code snippet that needs to be corrected before it'll do what you're attempting to make it do.

First off, take a look at the API section for Client.get_channel (which you're calling):

get_channel(id)
Returns a channel with the given ID.

Parameters
id (int) – The ID to search for.

Returns
The returned channel or None if not found.

Return type
Optional[Union[abc.GuildChannel, abc.PrivateChannel]]

So, when you do this: channel = bot.get_channel('584307345065246725'), you're passing an incorrect argument. As per the API, the only parameter must be an int, but you are passing a string. Simply get rid of the single quotes and that should be fine.

Protip: Under "Returns," the API states that it can return None if the channel isn't found, which is what is happening to you, since you're passing in a string. Hence, channel becomes the NoneType object you see in the error. So when you do channel.send... you get the picture.

1
votes

The channel id is an int, not a string

@bot.command()
async def say(ctx):
    channel = bot.get_channel(584307345065246725)
    await channel.send(ctx)

What I didn't quite understand is why you couldn't just do:

from discord.ext import commands

bot = commands.Bot(command_prefix='!')

@bot.command(pass_context=True)
async def say(ctx):
    await ctx.send(ctx)

But I could be mistaken about what you are trying to do.