Search code examples
pythondiscorddiscord.pynextcord

Why I can't send messages in a @tasks.loop in discord.py?


I have a problem: I can't send message in a @tasks.loop() function.

When I try to get the channel object with self.client.get_channel(channlid), it return me a Nonetype variable.

My code :

import nextcord
from nextcord.ext import commands
from nextcord.ext import tasks
from datetime import date, datetime

channlid = 934533675083792465
global channel
def setup(client):
    client.add_cog(Blagues(client))

class Blagues(commands.Cog):
    def __init__(self, client):
        self.client = client
        self.index = 0
        self.blaguedujour.start()
    
    @tasks.loop(seconds=1)
    async def blaguedujour(self):
        channel = self.client.get_channel(channlid)
        channel.send("a")


    
    @commands.command()
    async def test(self, ctx):
        await ctx.send("test")

my error:

PS C:\Users\baron_btjit4i> & C:/Users/baron_btjit4i/AppData/Local/Programs/Python/Python39/python.exe c:/Users/baron_btjit4i/Desktop/Autrebot/main.py
Unhandled exception in internal background task 'blaguedujour'.
Traceback (most recent call last):
  File "C:\Users\baron_btjit4i\AppData\Local\Programs\Python\Python39\lib\site-packages\nextcord\ext\tasks\__init__.py", line 168, in _loop
    await self.coro(*args, **kwargs)
  File "c:\Users\baron_btjit4i\Desktop\Autrebot\Cogs\blagues.py", line 20, in blaguedujour
    channel.send("a")
AttributeError: 'NoneType' object has no attribute 'send'

Can you help me ?


Solution

  • Problem

    You're calling client.get_channel before the client is ready. So, the client cannot find the channel you're looking for, and channel becomes None.

    This happens because you are starting blaguedujour in the initialization of your Blagues class.

    Solution

    Explanation

    Instead of starting the task in __init__, you should start in when the client is ready, in on_ready. This can be accomplished by adding a commands.Cog.listener() in your Blagues cog.

    Code

    class Blagues(commands.Cog):
        def __init__(self, client):
            self.client = client
            self.index = 0
        
        @tasks.loop(seconds=1)
        async def blaguedujour(self):
            channel = self.client.get_channel(channlid)
            channel.send("a")
    
        @commands.Cog.listener()
        async def on_ready():
            self.blaguedujour.start()
    
        
        @commands.command()
        async def test(self, ctx):
            await ctx.send("test")
    

    Aside

    channel.send() is a coroutine: it must be awaited. Use await channel.send("a") instead.