AttributeError: 'Client' object has no attribute 'send_message' (Discord Bot)
For some reason send_message isn't working properly on my Discord bot and I can't find anyway to fix it.
import asyncio
import discord
client = discord.Client()
@client.async_event
async def on_message(message):
author = message.author
if message.content.startswith('!test'):
print('on_message !test')
await test(author, message)
async def test(author, message):
print('in test function')
await client.send_message(message.channel, 'Hi %s, i heard you.' % author)
client.run("key")
on_message !test
in test function
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\indit\AppData\Roaming\Python\Python36\site-packages\discord\client.py", line 223, in _run_event
yield from coro(*args, **kwargs)
File "bot.py", line 15, in on_message
await test(author, message)
File "bot.py", line 21, in test
await client.send_message(message.channel, 'Hi %s, i heard you.' % author)
AttributeError: 'Client' object has no attribute 'send_message'
Solution 1:
You are probably running the rewrite version of discord.py, since the discord.Client
object does not a have a send_message
method.
To fix your problem you can just have it as:
async def test(author, message):
await message.channel.send('I heard you! {0.name}'.format(author))
but for what i see you doing I reccomend using the commands extension
This makes creating a bot and commands for the bot much simpler, for example here is some code that does exactly the same as yours
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
@bot.command()
async def test(ctx):
await ctx.send('I heard you! {0}'.format(ctx.author))
bot.run('token')
Solution 2:
As per discord.py
documentation, migration to v1.0 brought a lot of major changes in the API, including the fact that a lot of functionality was moved out of discord.Client
and put into their respective model.
E.g. in your specific case:
Client.send_message(abc.Messageable)
--> abc.Messageable.send()
So your code would be restyled from this:
await client.send_message(message.channel, 'I heard you! {0}'.format(message.author))
to this:
await message.channel.send('I heard you! {0}'.format(message.author))
This makes the code much more consistent and more accurate in depicting the actual discord entities, i.e. it's intuitive that a discord Message
is sent to a Channel
(subclass of abc.Messageable
) and not to the Client
itself.
There is a quite large list of migrations in this sense; you can find them all here
under the Models are Stateful
section.