0

I need to send a message in the discord channel based on a trigger that occurs in my program. My program runs in one main "while True" loop. Ideally I'd like to call the "send_message(text, picture)" function.

What i have now:

class MyClient(discord.Client):
    async def on_ready(self):
        print(f'Logged on as {self.user}!')
   
    async def on_message(self, message):
        #This part work correctly, but that's not what I'm asking about.
        if str(message.author)!='BOT' and message.content=="Show":
            print(f'Message from {message.author}: {message.content} in {message.channel.id}')
            is_success, buffer = cv2.imencode(".jpg", frame)
            io_buf = io.BytesIO(buffer)
            await message.channel.send(file=discord.File(io_buf, 'image.png'))
    
    async def my_send(picture_to_send, text_to_send):
        print("trying to send")
        c_id=ID
        channel_to = MyClient.get_channel(id=int(c_id))
        is_success, buffer = cv2.imencode(".jpg", picture_to_send)
        io_buf = io.BytesIO(buffer)
        await channel_to.send(content=str(text_to_send), file=discord.File(io_buf, 'image.png'))

def dis_start():
    intents = discord.Intents.default()
    intents.message_content = True

    client = MyClient(intents=intents)
    client.run('TOKEN')

dis_Call = threading.Thread(target=dis_start, daemon=True)
dis_Call.start()

when i try MyClient.my_send(frame, text) i recieve error "RuntimeWarning: coroutine 'MyClient.my_send' was never awaited".
Maybe I'm trying to do it wrong, tell me how you would do it.

2 Answers2

0

Since the my_send() method is asynchronous (marked with the async keyword), you need to use await to properly call it.

To fix your problem, you should modify the line where you call MyClient.my_send(frame, text) to be await MyClient.my_send(frame, text).

Additionally I noticed that your my_send() method is missing self keyword, which should be always the first parameter of class method.

async def my_send(self, picture_to_send, text_to_send):
Deborisz
  • 196
  • 2
  • Hi! Thank you for your answer. I fixed the typo with the missing 'self' argument. Also I incorrectly tried to call a class method. I tried MyClient.my_send, but MyClient is class name, not an object name. Also i read some about async functions. Ive tried to call my_send with "asycio.run" and "asyncio.create_task". In some cases, I received an error related to asycio loop, at one time an error that await channel.send simply did not execute. In the end, I could not cope with the problem described in my question, but I successfully implemented the functionality that I wanted to do. – Mikhail Byran Apr 13 '23 at 12:58
0

So, due to the complexity of async / await functions, I still did not understand how to correctly execute client.my_send, I made a very bad, but working "crutch" (is that what it's called in English?). Discord.py has a standard on_ready event. We add a While True loop to the async def on_ready function, where we check the value of flag, if flag==True, we send the message and do flag=False. Don't forget that we MUST use await asyncio.sleep(1) so that the loop doesn't run too fast. Since we used asyncio.sleep instead of time.sleep, we do not slow down our program, and I did not notice a serious load on the CPU. How to use it? We place the text of our message in any global variable, and call flag=True. The if flag: is fired, which spins in While True: and our program sends a message with the specified text.

async def on_ready(self):
    print(f'Logged on as {self.user}!')
    channel_to = self.get_channel(ID)
    while True:
        if text_to_dis['flag']:
            print("trying to send")
            text_to_send=''
            for t_i in text_to_dis['text']:
                text_to_send+=t_i+'     
            await channel_to.send(content=str(text_to_send))
            text_to_dis['flag']=False
        await asyncio.sleep(3)

In main program:

text_to_dis['text']=our_text
text_to_dis['flag']=True