如何解决 Microsoft Bot Framework 中的内容类型错误?

问题描述

我正在使用 Microsoft Bot Builder Python SDK 构建机器人。它托管在 Heroku 上,与 Skype 交换短信效果很好。但是我遇到了发送文件的问题。机器人生成一个 JSON 文件并将其发送给用户。我正在使用附件机器人代码_get_upload_attachment 方法(请参阅下面我的更改),当机器人在本地运行时,文件会毫无问题地发送到 Bot Framework Emulator。部署到 Heroku 后,文件通过 Bot Framework portal 中的测试工具成功发送。但是在触发从Skype发送文件后,出现如下所示的错误。似乎此错误特定于 Skype 频道。

什么可能会引发此错误,我该如何解决

错误

2021-02-18T08:28:32.579790+00:00 app[web.1]: [on_turn_error] unhandled error: Operation returned an invalid status code 'Not Found'
2021-02-18T08:28:32.581176+00:00 app[web.1]: Traceback (most recent call last):
2021-02-18T08:28:32.581226+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/botbuilder/core/bot_adapter.py",line 128,in run_pipeline
2021-02-18T08:28:32.581227+00:00 app[web.1]: context,callback
2021-02-18T08:28:32.581229+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/botbuilder/core/middleware_set.py",line 69,in receive_activity_with_status
2021-02-18T08:28:32.581230+00:00 app[web.1]: return await self.receive_activity_internal(context,callback)
2021-02-18T08:28:32.581247+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/botbuilder/core/middleware_set.py",line 79,in receive_activity_internal
2021-02-18T08:28:32.581248+00:00 app[web.1]: return await callback(context)
2021-02-18T08:28:32.581249+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/botbuilder/core/activity_handler.py",line 68,in on_turn
2021-02-18T08:28:32.581250+00:00 app[web.1]: await self.on_message_activity(turn_context)
2021-02-18T08:28:32.581266+00:00 app[web.1]: File "/app/bot.py",line 140,in on_message_activity
2021-02-18T08:28:32.581267+00:00 app[web.1]: reply.attachments = [await self._get_upload_attachment(turn_context)]
2021-02-18T08:28:32.581268+00:00 app[web.1]: File "/app/bot.py",line 426,in _get_upload_attachment
2021-02-18T08:28:32.581269+00:00 app[web.1]: type = "application/json"
2021-02-18T08:28:32.581288+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/botframework/connector/aio/operations_async/_conversations_operations_async.py",line 1138,in upload_attachment
2021-02-18T08:28:32.581289+00:00 app[web.1]: raise models.ErrorResponseException(self._deserialize,response)
2021-02-18T08:28:32.581316+00:00 app[web.1]: botbuilder.schema._models_py3.ErrorResponseException: Operation returned an invalid status code 'Not Found

获取附件方法

async def _get_upload_attachment(self,turn_context: TurnContext) -> Attachment:
    """
    Creates an "Attachment" to be sent from the bot to the user from an uploaded file.
    :param turn_context:
    :return: Attachment
    """
    with open("/tmp/exports/export.json","rb") as in_file:
        json_data = in_file.read()
    connector = await turn_context.adapter.create_connector_client(
        turn_context.activity.service_url
    )
    conversation_id = turn_context.activity.conversation.id
    response = await connector.conversations.upload_attachment(
        conversation_id,AttachmentData(
            name = "export.json",original_base64 = json_data,type = "application/json"
        )
    )
    base_uri: str = connector.config.base_url
    attachment_uri = (
        base_uri
        + ("" if base_uri.endswith("/") else "/")
        + f"v3/attachments/{response.id}/views/original"
    )
    return Attachment(
        name = "export.json",content_type = "application/json",content_url = attachment_uri,)

UPD: 我已经用 XLSX 替换了 JSON 导出并面临同样的问题:XLSX 文件已成功发送到 Bot Framework portal 中的测试工具(我可以下载并保存它),但是 “机器人遇到了错误错误。要继续运行此机器人,请修复机器人源代码。” 消息返回到 Skype 频道。 Heroku 日志显示与上面的错误示例类似的错误

机器人发送的文件由建议操作按钮触发,如下面的屏幕截图所示。

XLSX file sending by the bot

解决方法

随着您对调试 Python 代码的经验越来越丰富,您可能会发现 Python 堆栈跟踪中的行号指的是多行函数调用的最后一行,而不是第一行。当您考虑解释器如何从上到下一次读取一行时,这是有道理的,并且在知道所有参数是什么之前它无法调用该函数。这意味着即使您在堆栈跟踪中看到的行是 type = "application/json",那只是因为它是函数调用的最后解释行,因此您应该注意正在调用的函数:{{1 }}。您的问题与内容类型无关。

我们可以看到 upload_attachment 抛出“Not Found”错误。您可能会将其识别为与 404 关联的消息。这意味着您的连接器客户端正在调用的底层 REST API operation 对于给定的服务 URL 不存在,这意味着 Skype 通道不支持该操作。这不应该让人感到意外,因为大多数操作都是针对特定渠道的。

我尝试向 Skype conventional way 发送附件,但出现 400 错误:

upload_attachment

这并没有给我们留下很多选择。如果您真的想在 Skype 中向用户发送文件附件,则必须自己将其上传到某个外部服务器,然后将其 URL 提供给用户。如果您不介意将文件上传到公共 URL,那么这将是最简单的,但是如果您希望该文件是私有的,那么您需要将其上传到某个机器人和用户都具有凭据的安全系统.这可能会变得复杂。

您可能对这个答案感到失望,但我不认为您会得到更好的答案。 Skype bot 已经 deprecated 一年多了,这意味着您不应该期望获得任何官方帮助来解决您的 Skype bot 问题。我的建议是切换到另一个聊天平台,例如 Teams。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...