Gravar diretamente no armazenamento
APLICA-SE A: SDK v4
Você pode ler e gravar diretamente em seu objeto de armazenamento sem usar middleware ou objeto de contexto. Isso pode ser apropriado para dados que seu bot usa para preservar uma conversa ou dados que vêm de uma fonte fora do fluxo de conversa do bot. Neste modelo de armazenamento de dados, os dados são lidos diretamente do armazenamento em vez de usar um gerenciador de estado. Os exemplos de código neste artigo mostram como ler e gravar dados no armazenamento usando memória, Cosmos DB, Azure Blob e armazenamento de transcrição de Blob do Azure.
Nota
Os SDKs JavaScript, C# e Python do Bot Framework continuarão a ser suportados, no entanto, o Java SDK está sendo desativado com suporte final de longo prazo terminando em novembro de 2023.
Os bots existentes construídos com o Java SDK continuarão a funcionar.
Para a criação de novos bots, considere usar o Microsoft Copilot Studio e leia sobre como escolher a solução de copilot certa.
Para obter mais informações, consulte O futuro da criação de bots.
Pré-requisitos
- Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.
- Familiaridade com a criação de um bot localmente.
- Modelos do Bot Framework SDK v4 para Visual Studio (C#), Node.js ou Yeoman.
Nota
Você pode instalar os modelos de dentro do Visual Studio.
- No menu, selecione Extensões e, em seguida, Gerenciar extensões.
- Na caixa de diálogo Gerenciar extensões, procure e instale modelos do SDK do Bot Framework v4 para Visual Studio.
Para obter informações sobre como implantar bots .NET no Azure, consulte como provisionar e publicar um bot.
Sobre este exemplo
O código de exemplo neste artigo começa com a estrutura de um bot de eco básico e, em seguida, estende a funcionalidade desse bot adicionando código adicional (fornecido abaixo). Esse código estendido cria uma lista para preservar as entradas do usuário à medida que são recebidas. A cada turno, a lista completa de entradas do usuário, salvas na memória, é ecoada de volta para o usuário. A estrutura de dados que contém essa lista de entradas é então modificada para salvar no armazenamento. Vários tipos de armazenamento são explorados à medida que funcionalidades adicionais são adicionadas a este código de exemplo.
Importante
Este artigo contém exemplos de código herdado usando cadeias de conexão em arquivos de configuração para conexão interna ao armazenamento. A Microsoft recomenda que você use o fluxo de autenticação mais seguro disponível. Se você estiver se conectando a um recurso do Azure, Identidades Gerenciadas para recursos do Azure é o método de autenticação recomendado.
Armazenamento de memória
O SDK do Bot Framework permite armazenar entradas do usuário usando armazenamento na memória. Como o armazenamento na memória é limpo cada vez que o bot é reiniciado, ele é mais adequado para fins de teste e não se destina ao uso em produção. Tipos de armazenamento persistentes, como armazenamento de banco de dados, são melhores para bots de produção.
Crie um bot básico
O restante deste tópico se baseia em um bot Echo. O código de exemplo do bot Echo pode ser criado localmente seguindo as instruções de início rápido para Criar um bot.
Substitua o código no EchoBot.cs pelo seguinte código:
using System;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Schema;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
// Represents a bot saves and echoes back user input.
public class EchoBot : ActivityHandler
{
// Create local Memory Storage.
private static readonly MemoryStorage _myStorage = new MemoryStorage();
// Create cancellation token (used by Async Write operation).
public CancellationToken cancellationToken { get; private set; }
// Class for storing a log of utterances (text of messages) as a list.
public class UtteranceLog : IStoreItem
{
// A list of things that users have said to the bot
public List<string> UtteranceList { get; } = new List<string>();
// The number of conversational turns that have occurred
public int TurnNumber { get; set; } = 0;
// Create concurrency control where this is used.
public string ETag { get; set; } = "*";
}
// Echo back user input.
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
// preserve user input.
var utterance = turnContext.Activity.Text;
// Make empty local log-items list.
UtteranceLog logItems = null;
// See if there are previous messages saved in storage.
try
{
string[] utteranceList = { "UtteranceLog" };
logItems = _myStorage.ReadAsync<UtteranceLog>(utteranceList).Result?.FirstOrDefault().Value;
}
catch
{
// Inform the user an error occurred.
await turnContext.SendActivityAsync("Sorry, something went wrong reading your stored messages!");
}
// If no stored messages were found, create and store a new entry.
if (logItems is null)
{
// Add the current utterance to a new object.
logItems = new UtteranceLog();
logItems.UtteranceList.Add(utterance);
// Set initial turn counter to 1.
logItems.TurnNumber++;
// Show user new user message.
await turnContext.SendActivityAsync($"{logItems.TurnNumber}: The list is now: {string.Join(", ", logItems.UtteranceList)}");
// Create dictionary object to hold received user messages.
var changes = new Dictionary<string, object>();
{
changes.Add("UtteranceLog", logItems);
}
try
{
// Save the user message to your Storage.
await _myStorage.WriteAsync(changes, cancellationToken);
}
catch
{
// Inform the user an error occurred.
await turnContext.SendActivityAsync("Sorry, something went wrong storing your message!");
}
}
// Else, our storage already contained saved user messages, add new one to the list.
else
{
// add new message to list of messages to display.
logItems.UtteranceList.Add(utterance);
// increment turn counter.
logItems.TurnNumber++;
// show user new list of saved messages.
await turnContext.SendActivityAsync($"{logItems.TurnNumber}: The list is now: {string.Join(", ", logItems.UtteranceList)}");
// Create Dictionary object to hold new list of messages.
var changes = new Dictionary<string, object>();
{
changes.Add("UtteranceLog", logItems);
};
try
{
// Save new list to your Storage.
await _myStorage.WriteAsync(changes,cancellationToken);
}
catch
{
// Inform the user an error occurred.
await turnContext.SendActivityAsync("Sorry, something went wrong storing your message!");
}
}
}
}
Inicie seu bot
Execute seu bot localmente.
Inicie o emulador e conecte seu bot
Instalar o emulador do Bot Framework Em seguida, inicie o emulador e, em seguida, conecte-se ao seu bot no emulador:
- Selecione o link Criar nova configuração de bot na guia Bem-vindo do emulador.
- Preencha os campos para se conectar ao seu bot, dadas as informações na página da Web exibidas quando você iniciou o bot.
Interaja com seu bot
Envie uma mensagem para o seu bot. O bot listará as mensagens que recebeu.
O restante deste artigo demonstrará como salvar no armazenamento persistente em vez da memória interna do bot.
Usando o Cosmos DB
Importante
A classe de armazenamento do Cosmos DB foi preterida. Os contêineres originalmente criados com CosmosDbStorage não tinham nenhuma chave de partição definida e receberam a chave de partição padrão de _/partitionKey.
Os contêineres criados com o armazenamento do Cosmos DB podem ser usados com o armazenamento particionado do Cosmos DB. Leia Particionamento no Azure Cosmos DB para obter mais informações.
Observe também que, ao contrário do armazenamento herdado do Cosmos DB, o armazenamento particionado do Cosmos DB não cria automaticamente um banco de dados em sua conta do Cosmos DB. Você precisa criar um novo banco de dados manualmente, mas ignore a criação manual de um contêiner, pois CosmosDbPartitionedStorage criará o contêiner para você.
Agora que você usou o armazenamento de memória, atualizaremos o código para usar o Azure Cosmos DB. O Cosmos DB é o banco de dados multimodelo distribuído globalmente pela Microsoft. O Azure Cosmos DB permite dimensionar de forma elástica e independente a taxa de transferência e o armazenamento em qualquer número de regiões geográficas do Azure. Ele oferece garantia de rendimento, latência, disponibilidade e consistência com SLAs (Service Level Agreements, contratos de nível de serviço) abrangentes.
Configurar um recurso do Cosmos DB
Para usar o Cosmos DB em seu bot, você precisará criar um recurso de banco de dados antes de entrar no código. Para obter uma descrição detalhada do banco de dados do Cosmos DB e da criação de aplicativos, consulte o início rápido para .NET, Node.js ou Python.
Criar a conta de base de dados
Aceda ao portal do Azure para criar um conta do Azure Cosmos DB. Procure e selecione Azure Cosmos DB.
Na página Azure Cosmos DB, selecione Novo para abrir a página Criar Conta do Azure Cosmos DB.
Forneça valores para os seguintes campos:
- Subscrição. Selecione a subscrição do Azure que quer utilizar para esta conta do Azure Cosmos.
- Grupo de recursos. Selecione um grupo de recursos existente ou selecione Criar novo e insira um nome para um novo grupo de recursos.
-
Nome da conta. Introduza um nome para identificar a conta do Azure Cosmos. Uma vez que documents.azure.com é anexado ao nome que indicar para criar o URI, utilize um nome exclusivo. Observe as seguintes diretrizes:
- O nome deve ser exclusivo no Azure.
- O nome deve ter entre 3 e 31 caracteres.
- O nome pode incluir apenas letras minúsculas, números e o caractere hífen (-).
- API. Selecione Core(SQL)
- Localização. Selecione um local mais próximo de seus usuários para oferecer a eles o acesso mais rápido aos dados.
Selecione Rever + Criar.
Depois de validado, selecione Criar.
A criação da conta demora alguns minutos. Aguarde o portal exibir os Parabéns! Sua conta do Azure Cosmos DB foi criada página.
Adicionar uma base de dados
Nota
Não crie o recipiente sozinho. Seu bot irá criá-lo para você ao criar seu cliente interno do Cosmos DB, garantindo que ele esteja configurado corretamente para armazenar o estado do bot.
Navegue até a página Data Explorer na sua conta do Cosmos DB recém-criada e escolha Novo Banco de Dados na lista suspensa Novo Contêiner . Um painel será aberto no lado direito da janela, onde você pode inserir os detalhes do novo banco de dados.
Insira um ID para seu novo banco de dados e, opcionalmente, defina a taxa de transferência (você pode alterar isso mais tarde) e, finalmente, selecione OK para criar seu banco de dados. Anote esse ID de banco de dados para uso posterior ao configurar seu bot.
Agora que você criou uma conta do Cosmos DB e um banco de dados, você precisa copiar alguns dos valores para integrar seu novo banco de dados ao seu bot. Para recuperá-los, navegue até a guia Chaves na seção de configurações do banco de dados da sua conta do Cosmos DB. Nesta página, você precisará de seu URI (ponto de extremidade do Cosmos DB) e sua CHAVE PRIMÁRIA (chave de autorização).
Agora você deve ter uma conta do Cosmos DB com um banco de dados e os seguintes valores prontos para uso em suas configurações de bot.
- URI
- Chave Primária
- ID da Base de Dados
Adicionar informações de configuração do Cosmos DB
Use os detalhes que você anotou na parte anterior deste artigo para definir seu ponto de extremidade, chave de autorização e ID do banco de dados. Finalmente, você deve escolher um nome apropriado para o contêiner que será criado em seu banco de dados para armazenar o estado do bot. No exemplo abaixo, o contêiner do Cosmos DB criado será chamado de "bot-storage".
Adicione as seguintes informações ao seu arquivo de configuração.
appsettings.json
"CosmosDbEndpoint": "<your-CosmosDb-URI>",
"CosmosDbAuthKey": "<your-primary-key>",
"CosmosDbDatabaseId": "<your-database-id>",
"CosmosDbContainerId": "bot-storage"
Instalando pacotes do Cosmos DB
Certifique-se de ter os pacotes necessários para o Cosmos DB.
Instale o pacote NuGet Microsoft.Bot.Builder.Azure. Para obter mais informações sobre como usar o NuGet, consulte Instalar e gerenciar pacotes no Visual Studio usando o Gerenciador de Pacotes NuGet.
Implementação do Cosmos DB
Nota
A versão 4.6 introduziu um novo provedor de armazenamento do Cosmos DB, a classe de armazenamento particionado do Cosmos DB, e a classe de armazenamento original do Cosmos DB foi preterida. Os contêineres criados com o armazenamento do Cosmos DB podem ser usados com o armazenamento particionado do Cosmos DB. Leia Particionamento no Azure Cosmos DB para obter mais informações.
Ao contrário do armazenamento herdado do Cosmos DB, o armazenamento particionado do Cosmos DB não cria automaticamente um banco de dados em sua conta do Cosmos DB. Você precisa criar um novo banco de dados manualmente, mas ignore a criação manual de um contêiner, pois CosmosDbPartitionedStorage criará o contêiner para você.
O código de exemplo a seguir é executado usando o mesmo código de bot que o exemplo de armazenamento de memória fornecido acima, com as exceções listadas aqui. Os trechos de código abaixo mostram uma implementação do armazenamento do Cosmos DB para 'myStorage' que substitui o armazenamento de memória local.
Primeiro, você precisa atualizar Startup.cs para fazer referência à biblioteca do Azure do construtor de bots:
using Microsoft.Bot.Builder.Azure;
Em seguida, no ConfigureServices
método em Startup.cs, crie o CosmosDbPartitionedStorage
objeto. Isso será passado para o construtor através da EchoBot
injeção de dependência.
// Use partitioned CosmosDB for storage, instead of in-memory storage.
services.AddSingleton<IStorage>(
new CosmosDbPartitionedStorage(
new CosmosDbPartitionedStorageOptions
{
CosmosDbEndpoint = Configuration.GetValue<string>("CosmosDbEndpoint"),
AuthKey = Configuration.GetValue<string>("CosmosDbAuthKey"),
DatabaseId = Configuration.GetValue<string>("CosmosDbDatabaseId"),
ContainerId = Configuration.GetValue<string>("CosmosDbContainerId"),
CompatibilityMode = false,
}));
No EchoBot.cs altere a declaração _myStorage
da private static readonly MemoryStorage _myStorage = new MemoryStorage();
variável para o seguinte:
// variable used to save user input to CosmosDb Storage.
private readonly IStorage _myStorage;
Em seguida, passe o IStorage
objeto para o EchoBot
construtor:
public EchoBot(IStorage storage)
{
if (storage is null) throw new ArgumentNullException();
_myStorage = storage;
}
Inicie seu bot do Cosmos DB
Execute seu bot localmente.
Teste seu bot do Cosmos DB com o Bot Framework Emulator
Agora inicie o Bot Framework Emulator e conecte-se ao seu bot:
- Selecione o link criar uma nova configuração de bot na guia Bem-vindo do emulador.
- Preencha os campos para se conectar ao seu bot, dadas as informações na página da Web exibidas quando você iniciou o bot.
Interaja com seu bot do Cosmos DB
Envie uma mensagem para seu bot, e o bot listará as mensagens recebidas.
Ver os dados do Cosmos DB
Depois de executar seu bot e salvar suas informações, você pode exibir os dados armazenados no portal do Azure na guia Data Explorer .
Usando o armazenamento de Blob
O Armazenamento de blobs do Azure é a solução de armazenamento de objetos da Microsoft para a cloud. O Armazenamento de blobs está otimizado para armazenar grandes quantidades de dados não estruturados, como dados de texto ou binários. Esta seção explica como criar uma conta e um contêiner de armazenamento de blob do Azure e, em seguida, como fazer referência ao contêiner de armazenamento de blob do bot.
Para obter mais informações sobre o Armazenamento de Blob, consulte O que é o armazenamento de Blob do Azure?
Crie sua conta de armazenamento de Blob
Para usar o armazenamento de Blob em seu bot, você precisará configurar algumas coisas antes de entrar no código.
No portal do Azure, selecione Todos os serviços.
Na seção Em destaque da página Todos os serviços, selecione Contas de armazenamento.
Na página Contas de armazenamento, selecione Novo.
No campo Assinatura, selecione a assinatura na qual criar a conta de armazenamento.
No campo Grupo de recursos, selecione um grupo de recursos existente ou selecione Criar novo e insira um nome para o novo grupo de recursos.
No campo Nome da conta de armazenamento, insira um nome para a conta. Observe as seguintes diretrizes:
- O nome deve ser exclusivo no Azure.
- O nome deve ter entre 3 e 24 caracteres.
- O nome pode incluir apenas números e letras minúsculas.
No campo Local, selecione um local para a conta de armazenamento ou use o local padrão.
Para o restante das configurações, configure o seguinte:
- Desempenho: Padrão. Saiba mais sobre desempenho.
- Tipo de conta: BlobStorage. Saiba mais sobre contas de armazenamento.
- Replicação: deixe a configuração padrão. Saiba mais sobre redundância.
Na seção Detalhes do projeto da página Criar conta de armazenamento, selecione os valores desejados para assinatura e grupo de recursos.
Na seção Detalhes da instância da página Criar conta de armazenamento, insira o nome da conta de armazenamento e selecione valores para Local, Tipo de conta e Replicação.
Selecione Rever + criar para rever as definições da conta de armazenamento.
Depois de validado, selecione Criar.
Criar contêiner de armazenamento de Blob
Depois que sua conta de armazenamento de Blob for criada, abra-a e, em seguida:
Selecione Gerenciador de Armazenamento (Visualização).
Em seguida, clique com o botão direito do mouse em BLOB CONTAINERS
Selecione Criar contêiner de blob na lista suspensa.
Insira um nome no formulário Novo contêiner . Você usará esse nome para o valor de seu "nome de contêiner de blob" para fornecer acesso à sua conta de armazenamento de Blob. Observe as seguintes diretrizes:
- Este nome só pode conter letras minúsculas, números e hífenes.
- Este nome deve começar com uma letra ou um número.
- Cada hífen deve ser precedido e seguido por um caractere válido sem hífen.
- O nome deve ter entre 3 e 63 caracteres.
Adicionar informações de configuração de armazenamento de Blob
Encontre as chaves de armazenamento de Blob necessárias para configurar o armazenamento de Blob para seu bot, conforme mostrado acima:
- No portal do Azure, abra sua conta de armazenamento de Blob e selecione Chaves de acesso na seção Configurações .
- Para configurar seu bot para acessar sua conta de armazenamento de Blob, use Cadeia de conexão como o valor para a cadeia de conexão de blob.
Adicione as seguintes informações ao seu arquivo de configuração.
appsettings.json
"BlobConnectionString": "<your-blob-connection-string>",
"BlobContainerName": "<your-blob-container-name>",
Instalando pacotes de armazenamento de Blob
Se não tiver sido instalado anteriormente, instale os seguintes pacotes.
Instale o pacote NuGet Microsoft.Bot.Builder.Azure.Blobs. Para obter mais informações sobre como usar o NuGet, consulte Instalar e gerenciar pacotes no Visual Studio usando o Gerenciador de Pacotes NuGet.
Implementação de armazenamento de Blob
O armazenamento de Blob é usado para armazenar o estado do bot.
Nota
A partir da versão 4.10, Microsoft.Bot.Builder.Azure.AzureBlobStorage
foi preterido. Use o novo Microsoft.Bot.Builder.Azure.Blobs.BlobsStorage
em seu lugar.
O código de exemplo a seguir é executado usando o mesmo código de bot que o exemplo de armazenamento de memória fornecido acima, com as exceções listadas aqui.
Os trechos de código abaixo mostram uma implementação de armazenamento de Blob para 'myStorage' que substitui o armazenamento de memória local.
Primeiro, você precisa atualizar Startup.cs para fazer referência à biblioteca de blobs do Azure do construtor de bots :
Startup.cs
using Microsoft.Bot.Builder.Azure.Blobs;
Em seguida, no ConfigureServices
método em Startup.cs, crie o BlobsStorage
objeto, passando os valores de appsettings.json
. Isso será passado para o construtor através da EchoBot
injeção de dependência.
//Use Azure Blob storage, instead of in-memory storage.
services.AddSingleton<IStorage>(
new BlobsStorage(
Configuration.GetValue<string>("BlobConnectionString"),
Configuration.GetValue<string>("BlobContainerName")
));
Agora você primeiro precisa atualizar EchoBot.cs para fazer referência à biblioteca de blobs do Azure do construtor de bots :
EchoBot.cs
using Microsoft.Bot.Builder.Azure.Blobs;
Em seguida, remova ou comente a linha de código que cria a variável MemoryStorage 'private static readonly MemoryStorage _myStorage = new MemoryStorage();', e crie uma nova variável que será usada para salvar a entrada do usuário no Blob Storage.
EchoBot.cs
// variable used to save user input to CosmosDb Storage.
private readonly IStorage _myStorage;
Em seguida, passe o IStorage
objeto para o EchoBot
construtor:
public EchoBot(IStorage storage)
{
if (storage is null) throw new ArgumentNullException();
_myStorage = storage;
}
Depois que o armazenamento estiver definido para apontar para sua conta de Armazenamento de Blob, o código do bot armazenará e recuperará dados do armazenamento de Blobs.
Depois que o armazenamento estiver definido para apontar para sua conta de Armazenamento de Blob, o código do bot armazenará e recuperará dados do armazenamento de Blobs.
Inicie o bot de armazenamento de Blob
Execute seu bot localmente.
Inicie o emulador e conecte seu bot de armazenamento de Blob
Em seguida, inicie o emulador e, em seguida, conecte-se ao seu bot no emulador:
- Selecione o link Criar nova configuração de bot na guia "Bem-vindo" do emulador.
- Preencha os campos para se conectar ao seu bot, dadas as informações na página da Web exibidas quando você iniciou o bot.
Interaja com seu bot de armazenamento de Blob
Envie uma mensagem para seu bot e o bot listará as mensagens que receber.
Ver os dados de armazenamento de Blob
Depois de executar seu bot e salvar suas informações, podemos visualizá-lo na guia Gerenciador de Armazenamento no portal do Azure.
Armazenamento de transcrição de blob
O armazenamento de transcrição de blob do Azure fornece uma opção de armazenamento especializada que permite salvar e recuperar facilmente conversas do usuário na forma de uma transcrição gravada. O armazenamento de transcrição de blob do Azure é útil para capturar automaticamente entradas de usuário a serem examinadas durante a depuração do desempenho do bot.
Nota
Atualmente, o Python não oferece suporte ao armazenamento de transcrição de Blob do Azure. Embora o JavaScript suporte o armazenamento de transcrição Blob, as instruções a seguir são apenas para C#.
Configurar um contêiner de armazenamento de transcrição de Blob
O armazenamento de transcrição de blob do Azure pode usar a mesma conta de armazenamento de blob criada seguindo as etapas detalhadas nas seções "Criar sua conta de armazenamento de blob" e "Adicionar informações de configuração" acima. Agora adicionamos um contêiner para armazenar nossas transcrições
- Abra sua conta de armazenamento de blob do Azure.
- Selecione Gerenciador de Armazenamento.
- Clique com o botão direito do mouse em BLOB CONTAINERS e selecione create blob container.
- Insira um nome para o contêiner de transcrição e selecione OK. (Inserimos mybottranscripts)
Implementação de armazenamento de transcrição de Blob
O código a seguir conecta o ponteiro _myTranscripts
de armazenamento de transcrição à sua nova conta de armazenamento de transcrição de blob do Azure. Para criar esse link com um novo nome de contêiner, <your-blob-transcript-container-name>, ele cria um novo contêiner dentro do armazenamento de Blob para armazenar seus arquivos de transcrição.
O armazenamento de transcrições de Blob foi projetado para armazenar transcrições de bots.
Nota
A partir da versão 4.10, Microsoft.Bot.Builder.Azure.AzureBlobTranscriptStore
foi preterido. Use o novo Microsoft.Bot.Builder.Azure.Blobs.BlobsTranscriptStore
em seu lugar.
echoBot.cs
using Microsoft.Bot.Builder.Azure.Blobs;
public class EchoBot : ActivityHandler
{
...
private readonly BlobsTranscriptStore _myTranscripts = new BlobsTranscriptStore("<your-azure-storage-connection-string>", "<your-blob-transcript-container-name>");
...
}
Armazenar conversas de usuário em transcrições de blob do Azure
Depois que um contêiner de blob estiver disponível para armazenar transcrições, você poderá começar a preservar as conversas dos usuários com seu bot. Essas conversas podem ser usadas posteriormente como uma ferramenta de depuração para ver como os usuários interagem com seu bot. Cada conversa de reinicialização do emulador inicia a criação de uma nova lista de conversas de transcrição. O código a seguir preserva as entradas de conversa do usuário em um arquivo de transcrição armazenado.
- A transcrição atual é salva usando
LogActivityAsync
. - As transcrições salvas são recuperadas usando
ListTranscriptsAsync
o . Neste código de exemplo, a ID de cada transcrição armazenada é salva em uma lista chamada "storedTranscripts". Essa lista é usada posteriormente para gerenciar o número de transcrições de blob armazenadas que retemos.
echoBot.cs
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
await _myTranscripts.LogActivityAsync(turnContext.Activity);
List<string> storedTranscripts = new List<string>();
PagedResult<Microsoft.Bot.Builder.TranscriptInfo> pagedResult = null;
var pageSize = 0;
do
{
pagedResult = await _myTranscripts.ListTranscriptsAsync("emulator", pagedResult?.ContinuationToken);
pageSize = pagedResult.Items.Count();
// transcript item contains ChannelId, Created, Id.
// save the channelIds found by "ListTranscriptsAsync" to a local list.
foreach (var item in pagedResult.Items)
{
storedTranscripts.Add(item.Id);
}
} while (pagedResult.ContinuationToken != null);
...
}
Gerenciar transcrições de blob armazenadas
Embora as transcrições armazenadas possam ser usadas como uma ferramenta de depuração, com o tempo o número de transcrições armazenadas pode crescer mais do que você se importa em preservar. O código adicional incluído abaixo usa DeleteTranscriptAsync
para remover todos, exceto os últimos três itens de transcrição recuperados do seu armazenamento de transcrição de blob.
echoBot.cs
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
await _myTranscripts.LogActivityAsync(turnContext.Activity);
List<string> storedTranscripts = new List<string>();
PagedResult<Microsoft.Bot.Builder.TranscriptInfo> pagedResult = null;
var pageSize = 0;
do
{
pagedResult = await _myTranscripts.ListTranscriptsAsync("emulator", pagedResult?.ContinuationToken);
pageSize = pagedResult.Items.Count();
// transcript item contains ChannelId, Created, Id.
// save the channelIds found by "ListTranscriptsAsync" to a local list.
foreach (var item in pagedResult.Items)
{
storedTranscripts.Add(item.Id);
}
} while (pagedResult.ContinuationToken != null);
// Manage the size of your transcript storage.
for (int i = 0; i < pageSize; i++)
{
// Remove older stored transcripts, save just the last three.
if (i < pageSize - 3)
{
string thisTranscriptId = storedTranscripts[i];
try
{
await _myTranscripts.DeleteTranscriptAsync("emulator", thisTranscriptId);
}
catch (System.Exception ex)
{
await turnContext.SendActivityAsync("Debug Out: DeleteTranscriptAsync had a problem!");
await turnContext.SendActivityAsync("exception: " + ex.Message);
}
}
}
...
}
Para obter mais informações sobre a classe, consulte Armazenamento de transcrição de Blob do Azure.
Informações Adicionais
Gerencie simultaneidade usando eTags
Em nosso exemplo de código de bot, definimos a eTag
propriedade de cada IStoreItem
um como *
. O eTag
membro (tag de entidade) do seu objeto store é usado no Cosmos DB para gerenciar simultaneidade. O eTag
informa ao banco de dados o que fazer se outra instância do bot tiver alterado o objeto no mesmo armazenamento em que o bot está gravando.
Vitórias na última escrita - permitir substituições
Um eTag
valor de propriedade de asterisco (*
) indica que o último gravador vence. Ao criar um novo armazenamento de dados, você pode definir eTag
uma propriedade para *
indicar que não salvou anteriormente os dados que está escrevendo ou que deseja que o último gravador substitua qualquer propriedade salva anteriormente. Se a simultaneidade não for um problema para seu bot, definir a eTag
propriedade como *
para quaisquer dados que você esteja escrevendo habilitará as substituições.
Manter a simultaneidade e evitar substituições
Ao armazenar seus dados no Cosmos DB, use um valor diferente *
do se quiser impedir o eTag
acesso simultâneo a uma propriedade e evitar substituir alterações de outra instância do bot. O bot recebe uma resposta de erro com a mensagem etag conflict key=
quando tenta salvar dados de estado e o eTag
não é o mesmo valor que o eTag
no armazenamento.
Por padrão, o repositório do Cosmos DB verifica a eTag
propriedade de um objeto de armazenamento quanto à igualdade sempre que um bot grava nesse item e, em seguida, atualiza-o para um novo valor exclusivo após cada gravação. Se a eTag
propriedade na gravação não corresponder à eTag
no armazenamento, isso significa que outro bot ou thread alterou os dados.
Por exemplo, digamos que você queira que seu bot edite uma nota salva, mas não quer que seu bot substitua as alterações feitas por outra instância do bot. Se outra instância do bot tiver feito edições, você deseja que o usuário edite a versão com as atualizações mais recentes.
Primeiro, crie uma classe que implemente o IStoreItem
.
EchoBot.cs
public class Note : IStoreItem
{
public string Name { get; set; }
public string Contents { get; set; }
public string ETag { get; set; }
}
Em seguida, crie uma nota inicial criando um objeto de armazenamento e adicione o objeto à sua loja.
EchoBot.cs
// create a note for the first time, with a non-null, non-* ETag.
var note = new Note { Name = "Shopping List", Contents = "eggs", ETag = "x" };
var changes = Dictionary<string, object>();
{
changes.Add("Note", note);
};
await NoteStore.WriteAsync(changes, cancellationToken);
Em seguida, acesse e atualize a nota mais tarde, mantendo a que eTag
você leu na loja.
EchoBot.cs
var note = NoteStore.ReadAsync<Note>("Note").Result?.FirstOrDefault().Value;
if (note != null)
{
note.Contents += ", bread";
var changes = new Dictionary<string, object>();
{
changes.Add("Note1", note);
};
await NoteStore.WriteAsync(changes, cancellationToken);
}
Se a nota foi atualizada na loja antes de você escrever suas alterações, a chamada para Write
lançará uma exceção.
Para manter a simultaneidade, sempre leia uma propriedade do armazenamento e, em seguida, modifique a propriedade lida para que a eTag
seja mantida. Se você ler os dados do usuário do armazenamento, a resposta conterá a propriedade eTag. Se você alterar os dados e gravar dados atualizados no armazenamento, sua solicitação deverá incluir a propriedade eTag que especifica o mesmo valor que você leu anteriormente. No entanto, escrever um objeto com seu eTag
definido para *
permitirá que a gravação substitua quaisquer outras alterações.
Próximos passos
Agora que você sabe como ler e escrever diretamente do armazenamento, vamos dar uma olhada em como você pode usar o gerenciador de estado para fazer isso por você.