Enviar e receber arquivos usando o bot

Importante

  • Este artigo é baseado no SDK do Bot Framework v4.
  • Os bots não dão suporte ao envio e recebimento de arquivos em ambientes do GCC-High (Governmernt Community Cloud High) e do Departamento de Defesa (DOD).

Há duas maneiras de enviar e receber arquivos de um bot:

Usar as APIs do Graph

Poste mensagens com anexos de cartão que se referem a arquivos existentes do SharePoint usando as APIs do Graph para OneDrive e SharePoint. Para usar as APIs do Graph, obtenha acesso a qualquer um dos seguintes por meio do fluxo de autorização padrão do OAuth 2.0:

  • A pasta do OneDrive de um usuário para arquivos personal e groupchat.
  • Os arquivos no canal de uma equipe para channel arquivos.

As APIs do Graph funcionam em todos os escopos do Teams. Para obter mais informações, consulte enviar anexos de arquivo de mensagem de chat.

Como alternativa, você pode enviar e receber arquivos de um bot usando as APIs de bot do Teams.

Usando as APIs de Bot do Teams

As APIs de bot do Teams funcionam somente no contexto personal. Eles não funcionam no channel contexto ou groupchat .

Seu bot pode enviar e receber arquivos diretamente com usuários no contexto personal, também conhecido como chats pessoais, usando APIs do Teams. Implemente recursos, como relatórios de despesas, reconhecimento de imagem, arquivamento de arquivos e assinaturas eletrônicas que envolvem a edição do conteúdo do arquivo. Os arquivos compartilhados no Teams normalmente aparecem como cartões e permitem a exibição avançada no aplicativo.

As próximas seções descrevem como enviar conteúdo de arquivo como interação direta do usuário, como enviar uma mensagem. Essa API é fornecida como parte da Plataforma de Bot do Microsoft Teams.

Configurar o bot para dar suporte a arquivos

Para enviar e receber arquivos no bot, defina a propriedade supportsFiles no manifesto como true. Essa propriedade é descrita na seção bots da referência de manifesto.

A definição tem esta aparência: "supportsFiles": true. Se o bot não habilitar supportsFiles, os recursos listados nesta seção não funcionarão.

Receber arquivos no chat pessoal

Quando um usuário envia um arquivo para o bot, o arquivo é carregado pela primeira vez no armazenamento do OneDrive for Business do usuário. Em seguida, o bot recebe uma atividade de mensagem notificando o usuário sobre o upload do usuário. A atividade conterá metadados de arquivo, como seu nome e a URL de conteúdo. Você pode ler diretamente dessa URL para buscar seu conteúdo binário.

Exemplo de atividade de mensagem com anexo de arquivo

O código a seguir mostra um exemplo de atividade de mensagem com anexo de arquivo:

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

A tabela a seguir descreve as propriedades de conteúdo do anexo:

Propriedade Objetivo
downloadUrl URL do OneDrive para buscar o conteúdo do arquivo. Você pode emitir um HTTP GET diretamente dessa URL.
uniqueId ID de arquivo exclusiva. Essa é a ID do item de unidade do OneDrive, caso o usuário envie um arquivo para o bot.
fileType Tipo de arquivo, como .pdf ou .docx.

Como prática recomendada, confirme o upload do arquivo enviando uma mensagem de volta ao usuário.

Carregar arquivos no chat pessoal

Para carregar um arquivo para um usuário:

  1. Envie uma mensagem para o usuário solicitando permissão para gravar o arquivo. Esta mensagem deve conter um anexo FileConsentCard com o nome do arquivo a ser carregado.
  2. Se o usuário aceitar o download do arquivo, seu bot receberá uma atividade de invocação com uma URL de local.
  3. Para transferir o arquivo, o bot executa um HTTP POST diretamente na URL de local fornecida.
  4. Opcionalmente, você pode remover o cartão de consentimento original se não quiser permitir que o usuário aceite uploads adicionais do mesmo arquivo.

Mensagem solicitando permissão para carregar

Esta mensagem da área de trabalho contém um objeto de anexo simples solicitando permissão de usuário para carregar o arquivo:

Cartão de consentimento solicitando permissão do usuário para carregar o arquivo

Esta mensagem móvel contém um objeto de anexo solicitando permissão de usuário para carregar o arquivo:

Consentimento cartão solicitando permissão do usuário para carregar arquivo no celular
{
  "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": {
      }
    }
  }]
}

A tabela a seguir descreve as propriedades de conteúdo do anexo:

Propriedade Objetivo
description Descreve a finalidade do arquivo ou resume seu conteúdo.
sizeInBytes Fornece ao usuário uma estimativa do tamanho do arquivo e da quantidade de espaço que ele levará no OneDrive.
acceptContext Contexto adicional que será transmitido silenciosamente para o bot quando o usuário aceitar o arquivo.
declineContext Contexto adicional que será transmitido silenciosamente para o bot quando o usuário recusar o arquivo.

Atividade de invocação quando o usuário aceitar o arquivo

Uma atividade de invocação é enviada ao bot se e quando o usuário aceita o arquivo. Ele contém OneDrive for Business URL de espaço reservado para a qual o bot pode emitir um PUT para transferir o conteúdo do arquivo. Para obter informações sobre como carregar para a URL do OneDrive, consulteCarregar bytes para a sessão de upload.

O código a seguir mostra um exemplo de uma versão concisa da atividade de invocação que o bot recebe:

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

Da mesma forma, se o usuário recusar o arquivo, seu bot receberá o seguinte evento, com o mesmo nome de atividade geral:

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

Notificando o usuário sobre um arquivo carregado

Depois de carregar um arquivo no OneDrive do usuário, envie uma mensagem de confirmação para o usuário. A mensagem deve conter o seguinte anexo FileCard que o usuário pode selecionar, visualizar ou abri-lo no OneDrive ou baixar localmente:

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

A tabela a seguir descreve as propriedades de conteúdo do anexo:

Propriedade Objetivo
uniqueId ID do item da unidade do OneDrive/SharePoint.
fileType Tipo de arquivo, como .pdf ou .docx.

Buscar imagens embutidas da mensagem

Busque imagens embutidas que fazem parte da mensagem usando o token de acesso do Bot.

Imagens em linha

O código a seguir mostra um exemplo de busca de imagens embutidas da mensagem:

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}​​​​​",
    }​​​​​;
}​​​​​

Exemplo básico em C#

O código a seguir mostra um exemplo de como lidar com uploads de arquivos e enviar solicitações de consentimento de arquivo na caixa de diálogo do bot:


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);
}

Exemplo de código

O exemplo de código a seguir demonstra como obter o consentimento do arquivo e carregar arquivos no Teams de um bot:

Nome de exemplo Descrição .NET Node.js Python Manifesto
Upload de arquivos Este exemplo mostra como obter o consentimento do arquivo e carregar arquivos no Teams usando o bot. Além disso, como receber um arquivo enviado a um bot. View View View View

Guias passo a passo

Siga o guia passo a passo para carregar links no Teams usando bots.

Próxima etapa

Confira também