Search code examples
c#botframeworkazure-table-storage

How to retrieve Saved Conversation Data in Azure (Tablelogger)


i was able to saved conversation data using the tablelogger.cs implementation TableLogger.cs

I followed this tutorial to save the conversation history. Logging Conversation History

The code i used to save the chat history was:

 var tableName = ConfigurationManager.AppSettings["TableName"].ToString();
 var account = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);

 Conversation.UpdateContainer(
            builder =>
            {
                account.CreateCloudTableClient().GetTableReference(tableName).DeleteIfExists();
                builder.RegisterModule(new TableLoggerModule(account, tableName));
            });

After checking the Azure table storage explorer I can confirm that information was saved.

enter image description here

My question is now how to retrieve the conversation data and return it as a string so that I can send it to an agent for review?


Solution

  • All your conversation messages (let's say messages and not data as Conversation Data is a different thing in Bot Framework vocabulary, it's about state) are stored in an Azure Table, so if you want to get these messages, you just have to query the table.

    Getting the table items

    You have several options to query the table, for example

    Sample from the doc to get all rows by partition:

    // Retrieve the storage account from the connection string.
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
        CloudConfigurationManager.GetSetting("StorageConnectionString"));
    
    // Create the table client.
    CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
    
    // Create the CloudTable object that represents the "people" table.
    CloudTable table = tableClient.GetTableReference("people");
    
    // Construct the query operation for all customer entities where PartitionKey="Smith".
    TableQuery<CustomerEntity> query = new TableQuery<CustomerEntity>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "Smith"));
    
    // Print the fields for each customer.
    foreach (CustomerEntity entity in table.ExecuteQuery(query))
    {
        Console.WriteLine("{0}, {1}\t{2}\t{3}", entity.PartitionKey, entity.RowKey,
            entity.Email, entity.PhoneNumber);
    }
    

    Documentation to do a more customized request that will fit your needs: https://learn.microsoft.com/en-us/azure/cosmos-db/table-storage-how-to-use-dotnet

    Data organization

    In your capture you can see that the PartitionKey of the table is made of a concatenation of your channel and something that looks like a conversation Id. It is confirmed by the sources of TableLogger here:

    /// <summary>
    /// Construct from an IActivity.
    /// </summary>
    /// <param name="activity"></param>
    public ActivityEntity(IActivity activity)
    {
        PartitionKey = GeneratePartitionKey(activity.ChannelId, activity.Conversation.Id);
        RowKey = GenerateRowKey(activity.Timestamp.Value);
        From = activity.From.Id;
        Recipient = activity.Recipient.Id;
        Activity = activity;
        Version = 3.0;
    }
    

    So you will probably be interested in getting all the lines for a given partitionKey.

    For the other fields: the RowKey is a Timestamp, and Activity is mapped to your bot Activity object so it's an object which contains several informations. You will have to do some JsonConvert.DeserializeObject<Activity> to get the interesting information.