0

I have a discord bot that sends a message every once in a while based on a web scraping application (won't show that here because it is 500 lines long and someone else could compete for something with it) This is the code that sends the message:

import discord
import time
import asyncio

#the reason it is in while true is so it sends more frequently than once every 30 minutes for testing
while True:

    bot = discord.Client()
    @bot.event 
    async def on_ready():
        channel = bot.get_channel(866363006974820355)
        await channel.send("Test")
        print("Sent")
        await bot.close()
      

    print("started")
    
    bot.run('hiddentoken')

After the bot closes the loop it goes back to the bot.run() and gives the following exception: Event loop is closed. How do I reopen the event loop before I do bot.run()? Do I need to or is there a workaround I can use. Note: I tried just keeping the bot open all of the time but it logs out of discord after a bit.

  • with `await bot.close()` you close the websocket connection. So there isn't any connection to the discord server. I guess due to this the event loop is also closed. [Discord.py Wiki client.close()](https://discordpy.readthedocs.io/en/latest/api.html?highlight=close#discord.Client.close). Maybe just don't close the bot? – Doluk Jul 21 '21 at 23:11
  • Can you add a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) of what the web scraping does? Or something that is a proxy to it? I suspect the code is blocking, which will freeze your bot. – Benjin Jul 22 '21 at 12:26
  • @Doluk I tried to not close the loop but what happens is that when the bot gets back to the `bot.run()` it just freezes and doesn’t do anything. – thegamebegins25 Jul 22 '21 at 13:36
  • @Benjin It searches a website, then eBay to see if there’s profit on an item. No proxy, and it doesn’t work in my test script which is exactly what you see in my initial answer. – thegamebegins25 Jul 22 '21 at 14:30
  • Like I said, my best guess is that something is blocking. Without seeing the code it can't be more than a guess. Have a look [here](https://stackoverflow.com/questions/53587063/using-subprocess-to-avoid-long-running-task-from-disconnecting-discord-py-bot/53597795#53597795), it might solve your problem. It won't keep the loop open, but maybe the bot won't freeze and close anymore. – Benjin Jul 22 '21 at 18:01
  • @Benjin It worked! At first I didn't know what you meant by 'Blocking', but now I do. – thegamebegins25 Jul 23 '21 at 19:29

1 Answers1

0

This is not my response, this is @Benjin. This is where he answered.

praw relies on the requests library, which is synchronous meaning that the code is blocking. This can cause your bot to freeze if the blocking code takes too long to execute.

To get around this, a separate thread can be created that handles the blocking code. Below is an example of this. Note how blocking_function will use time.sleep to block for 10 minutes (600 seconds). This should be more than enough to freeze and eventually crash the bot. However, since the function is in it's own thread using run_in_executor, the bot continues to operate as normal.

import time
import asyncio
from discord.ext import commands
from concurrent.futures import ThreadPoolExecutor

def blocking_function():
    print('entering blocking function')
    time.sleep(600)
    print('sleep has been completed')
    return 'Pong'

client = commands.Bot(command_prefix='!')

@client.event
async def on_ready():
    print('client ready')

@client.command()
async def ping():
    loop = asyncio.get_event_loop()
    block_return = await loop.run_in_executor(ThreadPoolExecutor(), blocking_function)
    await client.say(block_return)

client.run('token')