Discord.py bot 将文件作为命令的参数

Discord.py bot take file as argument to command

我需要通过将文件附加到命令文本来将文件作为 discord bot 命令的参数。我该怎么做?我目前有这个代码,但是文件没有被选为参数:

@bot.command()
async def upload_file(ctx, file:discord.File):
    f = file.fp
    txt = f.read().decode("utf-8")
    file.close()
    print(txt)

为什么文件没有作为参数传递?

而且,更重要的是,我怎样才能做到这一点?

具体错误如下:

Ignoring exception in command upload_file:
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/discord/ext/commands/bot.py", line 863, in invoke
    await ctx.command.invoke(ctx)
  File "/usr/local/lib/python3.7/site-packages/discord/ext/commands/core.py", line 721, in invoke
    await self.prepare(ctx)
  File "/usr/local/lib/python3.7/site-packages/discord/ext/commands/core.py", line 685, in prepare
    await self._parse_arguments(ctx)
  File "/usr/local/lib/python3.7/site-packages/discord/ext/commands/core.py", line 599, in _parse_arguments
    transformed = await self.transform(ctx, param)
  File "/usr/local/lib/python3.7/site-packages/discord/ext/commands/core.py", line 445, in transform
    raise MissingRequiredArgument(param)
discord.ext.commands.errors.MissingRequiredArgument: file is a required argument that is missing.
`

我已经通读了一些 discord py 文档,我相信你的做法是错误的。命令参数只是通过它看到的消息的纯文本上下文进行解析,因此不会以这种方式将附件放在上面,但是您仍然可以做您想做的事,尽管方式不同。

关键是命令的上下文参数(ctx):https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Context

查看文档,您会看到它有一个 Message 实例:https://discordpy.readthedocs.io/en/latest/api.html#discord.Message, which contains a list of Attachments: https://discordpy.readthedocs.io/en/latest/api.html#discord.Attachment

附件有一个 url 参数,用于存储附件上传到 discord 的位置(这是为什么你不能将文件作为参数的关键,附件上传到 discord 的服务器独立于你的不和谐机器人)。然而,url 参数将使您能够下载所述文件的内容并执行任何您想对其进行的处理。所以这里有一些伪代码应该可以工作(同样,这都是粗略浏览文档)使用请求模块下载附件:

@bot.command()
async def upload_file(ctx):
    attachment_url = ctx.message.attachments[0].url
    file_request = requests.get(attachment_url)
    print(file_request.content)

回顾一下,当您将此命令与附件一起发送到您的机器人时,该附件会上传到 discords 服务器,并且 url 和一些其他信息会随消息一起发送到您的命令机器人(和其他人在听)。要获取实际文件数据,您必须从 url 下载文件。从那里,你可以用它做任何你想做的事。请注意,请求库是第 3 方,但(imo)比对 http 的内置支持要好得多。我还建议您在命令中添加一些边缘情况处理,以确保确实存在要处理的附件等。

如果您需要在本地处理文件,有一个非常简单的方法: 在 Context 中: Message 对象有一个名为 attachments 的属性。 discord.Attachment (https://discordpy.readthedocs.io/en/latest/api.html#discord.Attachment)

名单

我不知道为什么,但它总是一个对象的列表

它有一个 save 函数接受 io.BufferedIOBaseos.PathLike (https://discordpy.readthedocs.io/en/latest/api.html#discord.Attachment.save)

并且已经根据传输的对象将文件保存在本地 然后你就可以随心所欲