[英]How do I send a message from a thread using discord.py?
我希望我的 discord 用户能够排队一些任务。 在此示例中,它只是 ping 网站,但我最终希望它执行其他长时间运行的任务。 当我运行我的机器人时,出现以下错误:
ping-bot.py:22: RuntimeWarning: coroutine 'respond_to_channel' was never awaited
respond_to_channel()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
这是代码:
import os, discord, subprocess, asyncio
from discord import app_commands
from dotenv import load_dotenv
from time import sleep
from threading import Thread
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
CHANNEL=os.getenv('CHANNEL_ID')
GUILD=os.getenv('GUILD_ID')
queue = []
def ping_test():
global queue
old_queue = queue.copy()
while True:
if queue != old_queue and len(queue) > 0:
old_queue = queue.copy()
retcode = subprocess.call("ping " + "-c 5 " + old_queue[0][0], shell=True)
queue.pop(0)
if len(queue) > 0:
respond_to_channel()
print(f"Now working on {queue[0][0]}")
sleep(1)
async def respond_to_channel():
ping_channel = client.get_channel(CHANNEL)
await ping_channel.send(f"Testing... Now working on {queue[0][0]}")
class MyClient(discord.Client):
def __init__(self):
super().__init__(intents=discord.Intents.default())
self.synced = False
daemon = Thread(target=ping_test, daemon=True, name='Monitor')
daemon.start()
async def on_ready(self):
print(f'Logged on as {self.user}!')
if not self.synced:
await tree.sync(guild = discord.Object(id = GUILD))
self.synced = True
client = MyClient()
tree = app_commands.CommandTree(client)
@tree.command(name = "greet", description = "Greetings!", guild = discord.Object(id = GUILD))
async def self(interaction: discord.Interaction, name: str):
await interaction.response.send_message(f"Hello {name}! I was made with Discord.py!")
print(f'Sent from {interaction.user}')
@tree.command(name = "ping-test", description = "Use my computer to ping websites", guild = discord.Object(id = GUILD))
async def self(interaction: discord.Interaction, website: str):
queue.append([website, interaction.user.id])
await interaction.response.send_message(f"Hello <@{interaction.user.id}>! You want me to ping {website}. There are currently {len(queue) - 1} jobs in front of you.", file=discord.File('test.png'))
client.run(TOKEN)
我找到了一些适用于 ping 测试的“解决方案”,但我将允许我的 discord 用户使用我的计算机执行一些可能需要 5 分钟以上的计算量大的任务。 如果任务需要超过几分钟,我发现的这些其他解决方案会破坏机器人。
出于这个原因,我决定实现一个线程来处理列表中的项目,完成后将在频道中标记用户。
我实际上想使用discord.ext.tasks
,因为它会为您处理所有事情并在异步循环中运行,因此不会中断。
我将线程调用更改为
@tasks.loop(seconds = 1)
async def ping_test():
global queue
global being_worked
global client
ping_channel = client.get_channel(CHANNEL)
if len(queue) > 0:
if queue[0] != being_worked[0]:
being_worked = queue.copy()
retcode = subprocess.call("ping " + "-c 5 " + being_worked[0][0], shell=True)
queue.pop(0)
await ping_channel.send(f"Done working on {being_worked[0][0]}")
if len(queue) > 0:
await ping_channel.send(f"Testing... Now working on {queue[0][0]}")
print(f"Now working on {queue[0][0]}")
return
所以现在完整的代码如下所示:
import os, discord, subprocess
from discord import app_commands
from discord.ext import tasks
from dotenv import load_dotenv
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
CHANNEL=int(os.getenv('CHANNEL_ID'))
GUILD=os.getenv('GUILD_ID')
queue = []
being_worked = []
@tasks.loop(seconds = 1)
async def ping_test():
global queue
global being_worked
global client
ping_channel = client.get_channel(CHANNEL)
if len(queue) > 0:
if queue != being_worked:
being_worked = queue.copy()
retcode = subprocess.call("ping " + "-c 15 " + being_worked[0][0], shell=True)
queue.pop(0)
await ping_channel.send(f"Done working on {being_worked[0][0]}")
if len(queue) > 0:
await ping_channel.send(f"Testing... Now working on {queue[0][0]}")
print(f"Now working on {queue[0][0]}")
return
class MyClient(discord.Client):
def __init__(self):
super().__init__(intents=discord.Intents.default())
self.synced = False
async def on_ready(self):
print(f'Logged on as {self.user}!')
if not self.synced:
await tree.sync(guild = discord.Object(id = GUILD))
self.synced = True
await ping_test.start()
client = MyClient()
tree = app_commands.CommandTree(client)
@tree.command(name = "greet", description = "Greetings!", guild = discord.Object(id = GUILD))
async def self(interaction: discord.Interaction, name: str):
await interaction.response.send_message(f"Hello {name}! I was made with Discord.py!")
print(f'Sent from {interaction.user}')
@tree.command(name = "ping-test", description = "Use my computer to ping websites", guild = discord.Object(id = GUILD))
async def self(interaction: discord.Interaction, website: str):
queue.append([website, interaction.user.id])
await interaction.response.send_message(f"Hello <@{interaction.user.id}>! You want me to ping {website}. There are currently {len(queue) - 1} jobs in front of you.", file=discord.File('test.png'))
client.run(TOKEN)
在 function respond_to_channel()
前面添加await
应该可以解决这个问题。
await respond_to_channel()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.