我正在将Python与discord.py
一起使用。文档 here
我有一个在Discord服务器上运行的机器人,该机器人将服务器与subreddit链接在一起。用户具有各种命令,可以执行诸如获取最高提交,获取最新提交等操作。
我想向机器人添加一些功能,其中之一是关键字通知程序。机器人应该在subreddit中搜索标题中的关键字,然后通知用户列表中是否包含该关键字。我知道如何做到这一点,我已经做了很多次,但是我不知道如何使用Discord机器人来做到这一点。我没有使用asynchio或任何类型的异步编程的经验。
我尝试执行此操作的方式有效,但它非常简陋,绝对不好。在on message()
函数的顶部,我只添加了对search_submissions()
函数的调用,这样,只要有人放置在服务器上发送新消息,该漫游器就会扫描Reddit提交。服务器很忙,可以正常工作,但是我真的想以“适当”的方式来做。
我不知道如何在不将search_submissions()
放入on_message()
内的情况下调用它。
编辑其他代码:
import discord
TOKEN = "redacted"
client = discord.Client()
@client.event
async def reddit_search():
print("Searching")
@client.event
async def on_message(message):
if message.content.startswith("reddit!hot"):
# Get hot
# Do other things.
@client.event
async def on_ready():
print("Connected to Discord as {}.".format(client.user.name))
client.run(TOKEN)
答案 0 :(得分:2)
您可以使用Client.loop.create_task(search_submissions())
向bot事件循环添加一个函数,如下所示:
async def search_submissions():
pass
client = discord.Client()
client.loop.create_task(search_submissions())
client.run(TOKEN)
更新:
如果您希望函数继续运行,可以将其置于while循环中,并在它们之间进行一些睡眠:
async def search_submissions():
while(true):
# do your stuff
await asyncio.sleep(1)
答案 1 :(得分:1)
此处的其他答案未考虑discord.py有用的tasks.loop
装饰器。
要使事件每5秒发生一次,您可以使用
from discord.ext import tasks, commands
class MyCog(commands.Cog):
def __init__(self):
self.foo.start()
def cog_unload(self):
self.printer.cancel()
@tasks.loop(seconds=5.0)
async def foo(self):
print('bar')
更多信息可以在这里找到:https://discordpy.readthedocs.io/en/latest/ext/tasks/
答案 2 :(得分:0)
您希望search_submissions()
函数是 async ,因此您的漫游器的其他功能仍然可以调用,并且漫游器保持响应状态。将其定义为def async
并使用aiohttp
将异步HTTP请求发送到reddit -这样做是发送请求,将控制放到事件循环中,然后在结果获得后再收回控制被传送回来。如果您在此处使用标准的HTTP库,则整个机器人将被阻止,直到结果返回为止。当然,只有当任务主要是受I / O约束而较少受CPU约束时,这才有意义。
然后在search_submissions()
中调用on_message(message)
,但是使用result = await search_submissions()
异步地 调用它。一旦on_message
的结果准备就绪,它将恢复执行search_submissions
。
如果您确实想在等待search_submissions
的同时在同一上下文中执行 (我认为这不太可能),请将其作为task = asyncio.create_task(search_submissions())
分发。这将立即启动任务,并允许您在同一函数中执行其他操作。一旦需要结果,就必须result = await task
。
async def search_submissions():
async with aiohttp.ClientSession() as session:
async with session.get(some_reddit_url) as response:
return await response.read()
@client.event
async def on_message(message):
if message.content.startswith("reddit!hot"):
result = await search_submissions()
await message.channel.send(result)