Search code examples
pythondiscord.pypycord

Triggering method from within a loop with Python and Pycord


I'm playing around with Pycord and trying to send a message to a channel X for each element in an array.

The following class will throw a TypeError: MyClient.on_ready() missing 1 required positional argument: 'message' indicating that MyClient.on_ready() needs 2 arguments, one for self, one for message, but every example on how to pass arguments to class methods were only sending the argument.

class MyClient(discord.Client):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
    
    async def on_ready(self, message):
        channel = self.get_channel(123)  # Your channel ID goes here
        await channel.send(message)

client = MyClient()

for comment in comments:   
    if  comment['data']['parent_id'].startswith("t1") and comment['data']['name'] not in comments_json:
        wop = comment['data']['permalink']
        client.on_ready(wop)
        client.run("xxx")   

What am I missing?

EDIT: Added changes from comment, now error message reads as follow:

coroutine 'MyClient.on_ready' was never awaited
  client.on_ready(wop)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Ignoring exception in on_ready
Traceback (most recent call last):
  File "C:\Python310\lib\site-packages\discord\client.py", line 352, in _run_event
    await coro(*args, **kwargs)
TypeError: MyClient.on_ready() missing 1 required positional argument: 'message'

Solution

  • The error you got is because on_ready doesn't take any arguments

    Maybe something like this is what you are looking for, gets an channel object and sends an array (also subclassed just like the code you send)

    import discord
    import os
    import asyncio
    from typing import Iterable, Optional, Any
    
    
    class MyClient(discord.Client):
    
        # > trying to send a message to a channel X for each element in an array.
        def __init__(
            self,
            channel_to_send: int,
            array: Iterable,
            *,
            loop: Optional[asyncio.AbstractEventLoop] = None,
            **options: Any
        ):
            self.channel_to_send = channel_to_send
            self.array = array
            super().__init__(loop=loop, **options)
    
        async def on_ready(self):
            channel_ = await self.fetch_channel(self.channel_to_send)
            for element in self.array:
                await channel_.send(element)
    
    
    channel_id = 917803321929134133 # Replace this with that of yours 
    array = ["foo", "bar", "this", "is", "working"] # Replace this with that of yours
    
    client = MyClient(channel_id, array)
    client.run(os.getenv("DISCORD_TOKEN"))
    

    Result : result