通过你的 bot 发送和接收文件Send and receive files through your bot

重要

本节中的文章基于 v3 Bot 框架 SDK。The articles in this section are based on the v3 Bot Framework SDK. 如果您要查找当前文档(SDK 版本4.6 或更高版本),请参阅 "对话 bot " 部分。If you're looking for current documentation (version 4.6 or later of the SDK) see the Conversational Bots section.

有两种方法可以在 bot 之间发送文件:There are two ways to send files to and from a bot:

  • 使用 Microsoft Graph Api。Using the Microsoft Graph APIs. 此方法适用于团队中所有范围内的 bot:This method works for bots in all scopes in Teams:
    • personal
    • channel
    • groupchat
  • 使用团队 Api。Using the Teams APIs. 这些仅支持一个上下文中的文件:These only support files in one context:
    • personal

使用 Microsoft Graph ApiUsing the Microsoft Graph APIs

您可以使用适用于OneDrive 和 SharePoint的 Microsoft Graph api,使用包含卡片附件的邮件发布引用现有 SharePoint 文件的邮件。You can post messages with card attachments referencing existing SharePoint files using the Microsoft Graph APIs for OneDrive and SharePoint. 使用图形 Api 需要通过标准 OAuth 2.0 授权流获取对用户的 OneDrive personal文件夹groupchat (对于和文件)或团队频道中的文件( channel对于文件)的访问权限。Using the Graph APIs requires obtaining access to a user's OneDrive folder (for personal and groupchat files) or the files in a team's channels (for channel files) through the standard OAuth 2.0 authorization flow. 此方法适用于所有团队作用域。This method works in all Teams scopes.

使用团队 Bot ApiUsing the Teams Bot APIs

备注

此方法仅在personal上下文中有效。This method works only in the personal context. 它在channelgroupchat上下文中不起作用。It does not work in the channel or groupchat context.

你的 bot 可以使用团队 Api 直接在personal上下文中的用户发送和接收文件(也称为个人聊天)。Your bot can directly send and receive files with users in the personal context, also known as personal chats, using Teams APIs. 这样,您就可以实现费用报告、图像识别、文件存档、电子签名和其他涉及直接操作文件内容的方案。This lets you implement expense reporting, image recognition, file archival, e-signatures, and other scenarios involving direct manipulation of file content. 在团队中共享的文件通常显示为卡片,并允许进行丰富的应用程序内查看。Files shared in Teams typically appear as cards, and allow rich in-app viewing.

以下各节介绍如何执行此操作以通过直接用户交互(如发送邮件)发送文件内容。The following sections describe how to do this to send file content as a result of direct user interaction, like sending a message. 此 API 作为 Microsoft 团队 Bot 平台的一部分提供。This API is provided as part of the Microsoft Teams Bot Platform.

将你的 bot 配置为支持文件Configure your bot to support files

为了在你的 bot 中发送和接收文件,您必须将清单中supportsFiles的属性设置为trueIn order to send and receive files in your bot, you have to set the supportsFiles property in the manifest to true. 此属性在清单参考的 " bot " 部分中进行描述。This property is described in the bots section of the Manifest reference.

定义将如下所示: "supportsFiles": trueThe definition will look like this: "supportsFiles": true. 如果你的 bot 未启用supportsFiles,以下功能将不起作用。If your bot does not enable supportsFiles, the following features will not work.

在个人聊天中接收文件Receiving files in personal chat

当用户向你的 bot 发送文件时,首先将该文件上传到用户的 OneDrive for Business 存储。When a user sends a file to your bot, the file is first uploaded to the user's OneDrive for Business storage. 然后,你的 bot 将收到一条消息活动,通知用户上传。Your bot will then receive a message activity notifying you of the user upload. 该活动将包含文件元数据,例如其名称和内容 URL。The activity will contain file metadata, such as its name and the content URL. 您可以直接从该 URL 读取以提取其二进制内容。You can directly read from this URL to fetch its binary content.

通过工作组移动应用程序上的 bot 发送和接收文件Send and receive files through bot on Teams mobile app

备注

不支持在移动设备上向 bot 发送和接收文件。Sending and receiving files to bots on mobile devices is not supported.

带有文件附件的邮件活动示例Message activity with file attachment example

{
  "attachments": [{
    "contentType": "application/vnd.microsoft.teams.file.download.info",
    "contentUrl": "https://contoso.sharepoint.com/personal/johnadams_contoso_com/Documents/Applications/file_example.txt",
    "name": "file_example.txt",
    "content": {
      "downloadUrl" : "https://download.link",
      "uniqueId": "1150D938-8870-4044-9F2C-5BBDEBA70C9D",
      "fileType": "txt",
      "etag": "123"
    }
  }]
}

下表描述了附件的内容属性:The following table describes the content properties of the attachment:

属性Property 用途Purpose
downloadUrl OneDrive URL,用于提取文件内容。OneDrive URL for fetching the content of the file. 您可以HTTP GET直接从此 URL 发出。You can issue an HTTP GET directly from this URL.
uniqueId 唯一的文件 ID。Unique file ID. 如果用户将文件发送到你的 bot,这将是 OneDrive 驱动器项目 ID。This will be the OneDrive drive item ID, in the case of the user sending a file to your bot.
fileType 文件扩展名类型,如 pdf 或 .docx。File extension type, such as pdf or docx.

作为一种最佳做法,您应通过向用户发送回邮件来确认文件上载。As a best practice, you should acknowledge the file upload by sending back a message to the user.

将文件上传到个人聊天Uploading files to personal chat

将文件上传到用户涉及以下步骤:Uploading a file to a user involves the following steps:

  1. 向用户发送一封邮件,请求写入该文件的权限。Send a message to the user requesting permission to write the file. 此邮件必须包含要FileConsentCard上载的文件的名称附件。This message must contain a FileConsentCard attachment with the name of the file to be uploaded.
  2. 如果用户接受文件下载,则你的 bot 将收到具有位置 URL 的调用活动。If the user accepts the file download, your bot will receive an Invoke activity with a location URL.
  3. 若要转移文件,你的 bot 将HTTP POST直接执行提供的位置 URL 中的。To transfer the file, your bot performs an HTTP POST directly into the provided location URL.
  4. (可选)如果您不希望允许用户接受对同一文件的更多上载,则可以删除原始同意卡。Optionally, you can remove the original consent card if you do not want to allow the user to accept further uploads of the same file.

邮件请求上载的权限Message requesting permission to upload

此邮件包含一个简单的附件对象,该对象请求用户上载文件的权限。This message contains a simple attachment object requesting user permission to upload the file.

同意卡的屏幕截图请求用户上载文件的权限

{
  "attachments": [{
    "contentType": "application/vnd.microsoft.teams.card.file.consent",
    "name": "file_example.txt",
    "content": {
      "description": "<Purpose of the file, such as: this is your monthly expense report>",
      "sizeInBytes": 1029393,
      "acceptContext": {
      },
      "declineContext": {
      }
    }
  }]
}

下表描述了附件的内容属性:The following table describes the content properties of the attachment:

属性Property 用途Purpose
description 文件的说明。Description of the file. 可能会向用户显示描述其用途或汇总其内容的用户。May be shown to the user to describe its purpose or to summarize its content.
sizeInBytes 为用户提供文件大小和 OneDrive 中所需的空间量的估计值。Provides the user an estimate of the file size and the amount of space it will take in OneDrive.
acceptContext 用户接受文件时将以静默方式传输到你的 bot 的其他上下文。Additional context that will be silently transmitted to your bot when the user accepts the file.
declineContext 当用户拒绝文件时,将以静默方式传输到你的 bot 的其他上下文。Additional context that will be silently transmitted to your bot when the user declines the file.

用户接受文件时调用活动Invoke activity when the user accepts the file

当用户接受文件时,会向你的 bot 发送一个 invoke 活动。An invoke activity is sent to your bot if and when the user accepts the file. 它包含 OneDrive for Business 占位符 URL,你的 bot 可以通过它发出PUT进入以转移文件内容。It contains the OneDrive for Business placeholder URL that your bot can then issue a PUT into to transfer the file contents. 有关上载到 OneDrive URL 的信息,请参阅本文:将字节上传到上传会话for information on uploading to the OneDrive URL read this article: Upload bytes to the upload session.

下面的示例展示了你的 bot 将接收的 invoke 活动的 abridged 版本:The following example shows an abridged version of the invoke activity that your bot will receive:

{
  ...

  "name": "fileConsent/invoke",
  "value": {
    "type": "fileUpload",
    "action": "accept",
    "context": {
    },
    "uploadInfo": {
      "contentUrl": "https://contoso.sharepoint.com/personal/johnadams_contoso_com/Documents/Applications/file_example.txt",
      "name": "file_example.txt",
      "uploadUrl": "https://upload.link",
      "uniqueId": "1150D938-8870-4044-9F2C-5BBDEBA70C8C",
      "fileType": "txt",
      "etag": "123"
    }
  }
}

同样,如果用户拒绝该文件,你的 bot 将收到以下事件,其中包含相同的总体活动名称:Similarly, if the user declines the file, your bot will receive the following event, with the same overall activity name:

{
  "name": "fileConsent/invoke",
  "value": {
    "type": "fileUpload",
    "action": "decline",
    "context": {
    }
  }
}

通知用户有关上载的文件Notifying the user about an uploaded file

将文件上传到用户的 OneDrive 之后,无论您使用的是上述机制还是 OneDrive 用户委派 Api,都应向用户发送一条确认消息。After uploading a file to the user's OneDrive, whether you use the mechanism described above or OneDrive user delegated APIs, you should send a confirmation message to the user. 此邮件应包含用户FileCard可单击的附件,可在 OneDrive 中进行预览、在 OneDrive 中打开或在本地下载。This message should contain a FileCard attachment that the user can click on, either to preview it, open it in OneDrive, or download locally.

{
  "attachments": [{
    "contentType": "application/vnd.microsoft.teams.card.file.info",
    "contentUrl": "https://contoso.sharepoint.com/personal/johnadams_contoso_com/Documents/Applications/file_example.txt",
    "name": "file_example.txt",
    "content": {
      "uniqueId": "1150D938-8870-4044-9F2C-5BBDEBA70C8C",
      "fileType": "txt",
    }
  }]
}

下表描述了附件的内容属性:The following table describes the content properties of the attachment:

属性Property 用途Purpose
uniqueId OneDrive/SharePoint 驱动器项目 ID。OneDrive/SharePoint drive item ID.
fileType 文件类型,如 pdf 或 .docx。File type, such as pdf or docx.

C 中的基本示例#Basic example in C#

下面的示例展示了如何在你的 bot 对话框中处理文件上载和发送文件同意请求。The following sample shows how you can handle file uploads and send file consent requests in your bot's dialog.


// This sample dialog shows two simple flows:
// 1) A silly example of receiving a file from the user, processing the key elements,
//    and then constructing the attachment and sending it back.
// 2) Creating a new file consent card requesting user permission to upload a file.
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
    var replyMessage = context.MakeMessage();
    Attachment returnCard;

    var message = await result as Activity;

    // Check to see if the user is sending the bot a file.
    if (message.Attachments != null && message.Attachments.Any())
    {
        var attachment = message.Attachments.First();

        if (attachment.ContentType == FileDownloadInfo.ContentType)
        {
            FileDownloadInfo downloadInfo = (attachment.Content as JObject).ToObject<FileDownloadInfo>();
            if (downloadInfo != null)
            {
                returnCard = CreateFileInfoAttachment(downloadInfo, attachment.Name, attachment.ContentUrl);
                replyMessage.Attachments.Add(returnCard);
            }
        }
    }
    else
    {
        // Illustrates creating a file consent card.
        returnCard = CreateFileConsentAttachment();
        replyMessage.Attachments.Add(returnCard);
    }
    await context.PostAsync(replyMessage);
}


private static Attachment CreateFileInfoAttachment(FileDownloadInfo downloadInfo, string name, string contentUrl)
{
    FileInfoCard card = new FileInfoCard()
    {
        FileType = downloadInfo.FileType,
        UniqueId = downloadInfo.UniqueId
    };

    Attachment att = card.ToAttachment();
    att.ContentUrl = contentUrl;
    att.Name = name;

    return att;
}

private static Attachment CreateFileConsentAttachment()
{
    JObject acceptContext = new JObject();
    // Fill in any additional context to be sent back when the user accepts the file.

    JObject declineContext = new JObject();
    // Fill in any additional context to be sent back when the user declines the file.

    FileConsentCard card = new FileConsentCard()
    {
        AcceptContext = acceptContext,
        DeclineContext = declineContext,
        SizeInBytes = 102635,
        Description = "File description"
    };

    Attachment att = card.ToAttachment();
    att.Name = "Example file";

    return att;
}