Cómo ejecutar código Python adicional en un proyecto de bot de Discord
Estoy tratando de ejecutar mi bot de discordia, salir () o cerrar sesión () desde él, ejecutar otro código de Python y luego volver a iniciar sesión. No tengo experiencia con funciones asíncronas, así que no tengo idea de cuál es el error mensajes está diciendo.
import discord
dToken = "xxxxx"
client = discord.Client()
@client.event
async def on_ready():
print('Logged in as')
print(client.user.name)
print(client.user.id)
guilds = client.guilds
for i in range(len(guilds)):
if str(guilds[i]) == server:
gld = guilds[i]
for channel in gld.text_channels:
if str(channel) == "channelname":
print(str(message)+" sent to channel id "+str(channel.id))
await client.get_channel(channel.id).send(message)
await client.logout()
#run bot
client.run(dToken)
#change message and server name depending on extra code I put here
message = "hello!"
server = "servername"
#run bot again with changes
client.run(dToken)
Tengo que cerrar la sesión () porque esa es la única forma que encontré que puede hacer que se ejecute el código adicional. Pero el código que tengo da el siguiente error:
Traceback (most recent call last):
File "C:/Users/mmh/PycharmProjects/pythonProject/test.py", line 21, in <module>
client.run(dToken)
File "C:\Users\mmh\PycharmProjects\pythonProject\venv\lib\site-packages\discord\client.py", line 665, in run
future = asyncio.ensure_future(runner(), loop=loop)
File "C:\Users\mmh\AppData\Local\Programs\Python\Python37\lib\asyncio\tasks.py", line 608, in ensure_future
task = loop.create_task(coro_or_future)
File "C:\Users\mmh\AppData\Local\Programs\Python\Python37\lib\asyncio\base_events.py", line 402, in create_task
self._check_closed()
File "C:\Users\mmh\AppData\Local\Programs\Python\Python37\lib\asyncio\base_events.py", line 479, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
sys:1: RuntimeWarning: coroutine 'Client.run.<locals>.runner' was never awaited
Process finished with exit code 1
¿Alguien sabe lo que debería estar haciendo?
Respuestas
Hasta donde yo sé, no puedes correr client.rundos veces seguidas (lo intenté yo mismo, obtuve lo mismo RuntimeError). Sin embargo, en este caso, parece que desea enviar un mensaje a dos canales en dos servidores diferentes. Si es así, simplemente puede crear una función dentro on_readypara enviar un mensaje a un canal determinado y luego puede llamar a esa función dos veces:
@client.event
async def on_ready():
async def send_message(server_name, channel_name, message):
# Instead of looping through indices for client.guilds,
# you should iterate over client.guilds itself
# (as you did for gld.text_channels)
for guild in client.guilds:
if guild.name != server_name:
continue
for channel in guild.text_channels:
if channel.name == channel_name:
await channel.send(message)
print(message, 'sent to channel id', channel.id)
return
else:
raise ValueError('could not find channel')
else:
raise ValueError('could not find server')
await send_message('server1', 'textchannel1', 'hello!')
await send_message('server2', 'textchannel2', 'hello!')