我正在尝试使用我发现的这段代码来检查用户上次在 Discord 服务器的任何频道上发送消息的时间。我找到的来源是最旧的消息,但看起来是我需要的 - 但我在 channel.history().find 上遇到错误。错误是:
AtrributeError: async_generator object has no attribute "find"
.find 不能与 channel.history 一起使用还是我用错了?
#for a given user, check channel history for posts made by that user. @bot.command() async def lastMessage(ctx): users_id = ctx.author.id oldestMessage = None for channel in ctx.guild.text_channels fetchMessage = await channel.history().find(lambda m: m.author.id == users_id) if fetchMessage is None: continue if oldestMessage is None: oldestMessage = fetchMessage else: if fetchMessage.created_at > oldestMessage.created_at: oldestMessage = fetchMessage if (oldestMessage is not None): await ctx.send(f"Oldest message is {oldestMessage.content}") else: await ctx.send("No message found.")
然后我通过循环消息来做到这一点。不过,这将花费大量时间(例如 24 小时)。我想我可以通过向后循环消息来节省一点时间,也许可以将所有消息保存到列表中而不是在循环中重新获取。是否有更好/更快的方法来使用 lambda 执行此操作?
for channel in ctx.guild.text_channels: fetchMessage = None async for message in ctx.channel.history(limit=2000): if message.author == member: fetchMessage = message if newestMessage is None: newestMessage = fetchMessage else: if fetchMessage.created_at < newestMessage.created_at: newestMessage = fetchMessage print(newestMessage)
获取的历史是有序的。因此,如果您发现您发现的第一个事件是该频道中的最新事件,那么您可以继续下一个事件。其次,您可以指定一个 after 命令,例如 6 个月,以防止脚本一直爬回到频道开始。
newestMessage = None for channel in ctx.guild.text_channels: # theoretically you could parallise these too async for message in ctx.channel.history(limit=2000, after=...): if message.author == member: if newestMessage is None: newestMessage = message else: if message.created_at < newestMessage.created_at: newestMessage = message break # User was found no need to continue looking in this channel if newest Message is None: # user never talked else: # was found
此外,您还可以为所有用户执行一次此操作,并将它们存储在字典、csv 文件等中,并每周左右运行一次,最坏的情况下您只需几秒钟即可进行查找。