Отправка и получение файлов через бот

Важно!

Статьи в этом документе основаны на SDK bot Framework v4.

Существует два способа отправки файлов и получения файлов от бота:

Использование Graph API

Публикация сообщений с вложениями карт, которые относятся к существующим SharePoint файлам, с Graph API для OneDrive и SharePoint. Чтобы использовать Graph API, получите доступ к следующему через стандартный поток авторизации OAuth 2.0:

  • Папка OneDrive и personal groupchat файлы пользователя.
  • Файлы в канале группы для channel файлов.

Graph API работают во всех Teams области. Дополнительные сведения см. в сообщении отправки вложений в файл сообщений чата.

Кроме того, вы можете отправлять файлы и получать файлы от бота с помощью API Teams бота.

Использование API Teams бота

Примечание

Teams API бота работают только в personal контексте. Они не работают в channel контексте или groupchat в контексте.

С Teams API бот может напрямую отправлять и получать файлы с пользователями в контексте, также известном personal как личные чаты. Реализуют такие функции, как отчет о расходах, распознавание изображений, архивные файлы и электронные подписи, связанные с редактированием контента файлов. Файлы, Teams обычно отображаются в качестве карт и позволяют просматривать в приложении.

В следующих разделах описывается отправка контента файлов в качестве прямого взаимодействия с пользователем, например отправки сообщения. Этот API предоставляется в рамках платформы Teams бота.

Настройка бота для поддержки файлов

Чтобы отправить и получить файлы в боте, установите supportsFiles свойство в манифесте true . Это свойство описано в разделе боты в справке Манифест.

Определение выглядит "supportsFiles": true так. Если бот не supportsFiles включает, функции, перечисленные в этом разделе, не работают.

Получение файлов в личном чате

Когда пользователь отправляет файл боту, он сначала отправляется в OneDrive для бизнес-хранилища. Затем бот получает сообщение, уведомляя пользователя о загрузке пользователя. Действие содержит метаданные файлов, такие как его имя и URL-адрес контента. Пользователь может напрямую читать с этого URL-адреса, чтобы получить двоичный контент.

Действие сообщения с примером вложения файлов

В следующем коде показан пример активности сообщения с вложением файлов:

{
  "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"
    }
  }]
}

В следующей таблице описываются свойства контента вложения:

Свойство Назначение
downloadUrl OneDrive URL-адрес для получения содержимого файла. Пользователь может выдавать прямо HTTP GET из этого URL-адреса.
uniqueId Уникальный файл ID. Это — OneDrive элемента диска, если пользователь отправляет файл боту.
fileType Тип файла, например .pdf или .docx.

В качестве наилучшей практики подтвердите отправку файла, отправив сообщение пользователю.

Upload в личный чат

Отправка файла пользователю

  1. Отправьте сообщение пользователю с запросом разрешения на написание файла. Это сообщение должно содержать FileConsentCard вложение с именем загружаемого файла.
  2. Если пользователь принимает загрузку файла, бот получает действие вызова с URL-адресом расположения.
  3. Чтобы передать файл, бот выполняет непосредственно в HTTP POST предоставленный URL-адрес расположения.
  4. Необязательно удалите исходную карточку согласия, если вы не хотите, чтобы пользователь принял дальнейшие загрузки того же файла.

Сообщение с запросом разрешения на отправку

В следующем сообщении рабочего стола содержится простой объект вложения, запрашивающий разрешение пользователя на отправку файла:

Карточка согласия, запрашивающие разрешение пользователя на отправку файла

Следующее мобильное сообщение содержит объект вложения, запрашивающий разрешение пользователя на отправку файла:

Consent card requesting user permission to upload file on mobile
{
  "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": {
      }
    }
  }]
}

В следующей таблице описываются свойства контента вложения:

Свойство Назначение
description Описывает назначение файла или суммирует его содержимое.
sizeInBytes Предоставляет пользователю оценку размера файла и количества места, необходимого для OneDrive.
acceptContext Дополнительный контекст, который безмолвно передается боту, когда пользователь принимает файл.
declineContext Дополнительный контекст, который безмолвно передается боту при отклонении файла пользователем.

Вызов активности при приеме файла пользователем

Действие вызова отправляется боту, если и когда пользователь принимает файл. В нем OneDrive для бизнеса URL-адрес, который бот может затем выдать для передачи PUT содержимого файла. Сведения о загрузке в URL-адрес OneDrive см. в добавлении bytes к сеансу загрузки.

В следующем коде показан пример краткой версии действия вызова, получаемого ботом:

{
  "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"
    }
  }
}

Аналогично, если пользователь отклонив файл, бот получает следующее событие с таким же общим именем действий:

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

Уведомление пользователя о загруженных файлах

После отправки файла в OneDrive отправьте пользователю сообщение подтверждения. Сообщение должно содержать следующее вложение, которое пользователь может выбрать для предварительного просмотра или открытия OneDrive или локальной FileCard загрузки:

{
  "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",
    }
  }]
}

В следующей таблице описываются свойства контента вложения:

Свойство Назначение
uniqueId OneDrive или SharePoint элемента диска.
fileType Тип файла, например .pdf или .docx.

Извлечение нестантных изображений из сообщения

Извлекай в линию изображения, которые являются частью сообщения с помощью маркера доступа Бота.

Inline image

В следующем коде показан пример получения изображений из сообщения:

private async Task ProcessInlineImage(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    var attachment = turnContext.Activity.Attachments[0];
    var client = _clientFactory.CreateClient();
    // Get Bot's access token to fetch inline image. 
    var token = await new MicrosoftAppCredentials(microsoftAppId, microsoftAppPassword).GetTokenAsync();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    var responseMessage = await client.GetAsync(attachment.ContentUrl);
    // Save the inline image to Files directory.
    var filePath = Path.Combine("Files", "ImageFromUser.png");
    using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
    {
        await responseMessage.Content.CopyToAsync(fileStream);
    }
    // Create reply with image.
    var reply = MessageFactory.Text($"Attachment of {attachment.ContentType} type and size of {responseMessage.Content.Headers.ContentLength} bytes received.");
    reply.Attachments = new List<Attachment>() { 
        GetInlineAttachment() 
    };
    await turnContext.SendActivityAsync(reply, cancellationToken);
}
private static Attachment GetInlineAttachment()
{
    var imagePath = Path.Combine("Files", "ImageFromUser.png");
    var imageData = Convert.ToBase64String(File.ReadAllBytes(imagePath));
    return new Attachment
    {
        Name = @"ImageFromUser.png",
        ContentType = "image/png",
        ContentUrl = $"data:image/png;base64,{imageData}",
    };
}

Базовый пример в C

В следующем коде показан пример обработки отправки файлов и отправки запросов на согласие на файл в диалоговом окте бота:


protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    if (turnContext.Activity.Attachments?[0].ContentType.Contains("image/*") == true)
    {
        // Inline image.
        await ProcessInlineImage(turnContext, cancellationToken);
    }
    else
    {
        string filename = "teams-logo.png";
        string filePath = Path.Combine("Files", filename);
        long fileSize = new FileInfo(filePath).Length;
        await SendFileCardAsync(turnContext, filename, fileSize, cancellationToken);
    }
}
private async Task ProcessInlineImage(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    var attachment = turnContext.Activity.Attachments[0];
    var client = _clientFactory.CreateClient();
    // Get Bot's access token to fetch inline image. 
    var token = await new MicrosoftAppCredentials(microsoftAppId, microsoftAppPassword).GetTokenAsync();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    var responseMessage = await client.GetAsync(attachment.ContentUrl);
    // Save the inline image to Files directory.
    var filePath = Path.Combine("Files", "ImageFromUser.png");
    using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
    {
        await responseMessage.Content.CopyToAsync(fileStream);
    }
    // Create reply with image.
    var reply = MessageFactory.Text($"Attachment of {attachment.ContentType} type and size of {responseMessage.Content.Headers.ContentLength} bytes received.");
    reply.Attachments = new List<Attachment>() { GetInlineAttachment() };
    await turnContext.SendActivityAsync(reply, cancellationToken);
}
private static Attachment GetInlineAttachment()
{
    var imagePath = Path.Combine("Files", "ImageFromUser.png");
    var imageData = Convert.ToBase64String(File.ReadAllBytes(imagePath));
    return new Attachment
    {
        Name = @"ImageFromUser.png",
        ContentType = "image/png",
        ContentUrl = $"data:image/png;base64,{imageData}",
    };
}
private async Task SendFileCardAsync(ITurnContext turnContext, string filename, long filesize, CancellationToken cancellationToken)
{
    var consentContext = new Dictionary<string, string>
    {
        { 
            "filename", filename 
        },
    };
    var fileCard = new FileConsentCard
    {
        Description = "This is the file I want to send you",
        SizeInBytes = filesize,
        AcceptContext = consentContext,
        DeclineContext = consentContext,
    };
    var asAttachment = new Attachment
    {
        Content = fileCard,
        ContentType = FileConsentCard.ContentType,
        Name = filename,
    };
    var replyActivity = turnContext.Activity.CreateReply();
    replyActivity.Attachments = new List<Attachment>() { asAttachment };
    await turnContext.SendActivityAsync(replyActivity, cancellationToken);
}

Пример кода

В следующем примере кода показано, как получить согласие на файл и загрузить Teams с бота:

Пример имени Описание .NET Javascript Python
File upload Демонстрирует, как получить согласие на файл и загрузить Teams с бота. Кроме того, как получить файл, отправленный боту. View View View

Следующий этап