Make a cog that sends a message every 10 seconds in a specified chat discord.py

Viewed 963
from discord.ext import commands, tasks



class sendmessage10seconds(commands.Cog):

    def __init__(self, client):
        self.client = client
        print("Cog is running")


    @tasks.loop(seconds=10)
    async def sendmessage(ctx, self):
        channel = self.get_channel(802273252973477960)
        await channel.send("Hi")
    sendmessage.start()

def setup(client):
    client.add_cog(sendmessage10seconds(client))

This is my code so far. When I run it I get this error:

Traceback (most recent call last):
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/tasks/__init__.py", line 101, in _loop
    await self.coro(*args, **kwargs)
TypeError: sendmessage() missing 2 required positional arguments: 'ctx' and 'self'

What am I doing wrong?

1 Answers
  1. self goes always as a first argument, not second
async def sendmessage(self, ctx):
  1. You need to pass the ctx parameter, when starting the task (or don't pass it at all, there's no need for that)

  2. There's no such thing as self.get_channel (remember, you're not inheriting from discord.Client or commands.Bot), it's self.client.get_channel

channel = self.client.get_channel(...)
  1. You need to start the task in a function or a command
@commands.command()
async def start(self, ctx):
    self.sendmessage.start() # Pass the `ctx` parameter accordingly

EDIT: Starting the loop in the __init__ method

def __init__(self, client):
    self.client = client
    self.sendmessages.start()

Note: you should add wait until the bot is ready loading the internal cache, one way of doing that is using the decorator {task}.before_loop and using Bot.wait_until_ready

@sendmessage.before_loop
async def before_sendmessage(self):
    await self.client.wait_until_ready()

Your full fixed code

from discord.ext import commands, tasks


class sendmessage10seconds(commands.Cog):
    def __init__(self, client):
        self.client = client
        self.sendmessage.start()


    @tasks.loop(seconds=10)
    async def sendmessage(self): # You can pass the `ctx` parameter if you want, but there's no point in doing that
        channel = self.client.get_channel(802273252973477960)
        await channel.send("Hi")


    @sendmessage.before_loop
    async def before_sendmessage(self):
        await self.client.wait_until_ready()


def setup(client):
    client.add_cog(sendmessage10seconds(client))
Related