Reputation: 75
I want to write a bot message to discord without command. But I got a problem when I run the code. The error says: 'NoneType' object has no attribute 'send'
Traceback (most recent call last): File "D:/Development/Code Python/Bot Discord/discord-testbot.py", line 18, in my_background_task await channel.send(channel, 'New')
AttributeError: 'NoneType' object has no attribute 'send'
import discord
client = discord.Client()
@client.event
async def on_ready():
print('Bot is ready')
async def my_background_task():
await client.wait_until_ready()
await channel.send(channel, 'Bot say')
client.loop.create_task(my_background_task())
client.run(tokenBot)
If I remove line channel = client.get_channel(574514361394266125)
, then it raises another error, saying the name 'channel' is not defined.
Upvotes: 6
Views: 23503
Reputation: 405
Disclaimer: I just found this question today. I know it is already solved, but I thought I may leave my answer for future use or for other users.
This is a solution I have just for sending direct messages (in my case):
# DM message
@client.command(aliases=["dm"])
@commands.has_permissions(administrator=True)
async def _dm_(ctx, content, user_id):
# Variables
user = client.get_user(int(user_id))
msg = "Sending to DM!"
# Process
await ctx.send(msg)
print(msg)
await user.send(content)
In this case, my issue initially was filling in user_id
through discord as a string. Now, it takes it in as a string and then converts the ID to an integer.
Upvotes: 1
Reputation: 374
It works for me. It seems that you're calling client.get_channel(id)
before your client.wait_until_ready()
(you've sent the edited code so I cannot guarantee it).
This code works fine for me :
async def background():
await client.wait_until_ready()
channel = client.get_channel(int(MY_CHANNEL))
await channel.send("Test")
client.loop.create_task(background())
Since the discord.py v1.1 you can declare and manage your background task easier and safer.
This is how we do in a cog :
import discord
from discord.ext import tasks, commands
class OnReady_Message(commands.Cog):
def __init__(self, client):
self.client = client
self.send_onready_message.start()
def cog_unload(self):
self.send_onready_message.close()
return
# task
@tasks.loop(count = 1) # do it only one time
async def send_onready_message(self):
channel = self.client.get_channel(int(MY_CHANNEL))
await channel.send("Test")
@send_onready_message.before_loop # wait for the client before starting the task
async def before_send(self):
await self.client.wait_until_ready()
return
@send_onready_message.after_loop # destroy the task once it's done
async def after_send(self):
self.send_onready_message.close()
return
Finally to run the task send_onready_message()
we can create a Task_runner()
object or simply create in instance of the task.
This will allow you run all your tasks easily :
# importing the tasks
from cogs.tasks.on_ready_task import OnReady_Message
class Task_runner:
def __init__(self, client)
self.client = client
def run_tasks(self):
OnReady_Message(self.client)
return
In your main file :
import discord
from discord.ext import commands
from cogs.tasks.task_runner import Task_runner
client = commands.Bot(command_prefix = PREFIX)
runner = Task_runner(client)
runner.run_tasks()
client.run(token)
Without the Task_runner()
we have :
import discord
from discord.ext import commands
from cogs.tasks.on_ready_task import OnReady_Message
client = commands.Bot(command_prefix = PREFIX)
OnReady_Message(client)
client.run(TOKEN)
The example above can only work if your discord.py version is up to date.
To know if it is, you can run in your terminal :
>>> import discord
>>> discord.__version__
'1.2.3'
If your version is older, you can update it by using this command in your terminal :
pip install discord.py --upgrade
Hope it helped !
Upvotes: 7