Saving Bot Activities in Azure SQL Database
Tags: azure, azurebotservice, database, azuresql
Published: 2022-02-10 10:23:06

In this blog post, we’ll walkthrough of how to integrate Bot Framework v4 SDK with [Azure SQL Database](https://azure.microsoft.com/en-us/products/azure-sql/database/#overview) and save Bot activities/ conversations into the database.

We’ll leverage [`Bot.Builder.Community.Storage.EntityFramework`](https://www.nuget.org/packages/Bot.Builder.Community.Storage.EntityFramework/) package to save conversations using EntityFrameworkTranscriptStore with TranscriptLoggerMiddleware into Azure SQL Database.

---

## Let’s start –

## Create Azure Sql Database:

If you are new to Azure SQL and looking to understand more about different offerings of Azure SQL, you can start with [this article](https://docs.microsoft.com/en-us/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview).

Once you have decided the type of Azure SQL Database that suits your requirement, you can navigate to the [Select SQL Deployment options](https://ms.portal.azure.com/#create/Microsoft.AzureSQL) page and create your Database.

> For this demo, I have created a single database in the [serverless compute tier](https://docs.microsoft.com/en-us/azure/azure-sql/database/serverless-tier-overview).

You can follow [this article](https://docs.microsoft.com/en-us/azure/azure-sql/database/single-database-create-quickstart?tabs=azure-portal) which explains the steps of creating an Azure SQL Database.

## Connect to the database:

Once your Azure sql database is created, you can use the [Query editor (preview)](https://docs.microsoft.com/en-us/azure/azure-sql/database/single-database-create-quickstart?tabs=azure-portal#query-the-database) in the Azure portal to connect to the database and execute queries. Alternatively, you can also connect your database using [SSMS](https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver15) and [Azure Data Studio](https://docs.microsoft.com/en-us/sql/azure-data-studio/download-azure-data-studio?view=sql-server-ver15), etc.

- In the Azure portal, search for and select SQL databases, and then select your database from the list.
- On the page for your database, select Query editor (preview) in the left menu.
- Enter your server admin login information and select OK

![Query editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ue7zj05u9ul86j78dgqr.png)

> **Note:** Click on the `Connection strings` link in the above blade and copy the connection string somewhere which we’ll use later in this demo.

## Create tables in your Azure SQL database:

Now, you need to create tables in your Azure SQL database to store the Bot Activities.

- Execute the [CreateTableScript.sql](https://github.com/abhimantiwari/botbuilder-community-dotnet/blob/develop/samples/EntityFramework%20Storage%20Sample/CreateTableScript.sql) script in your Azure SQL Database.
- Once you execute the `CreateTableScript.sql` script in your Azure SQL Database, you should be able to see these two tables (
`BotDataEntity` & `TranscriptEntity`) created.

> We have just created the table, it doesn’t contain any data yet.

## Getting Bot project ready:

For this Demo, we will be using [Bot Framework](https://dev.botframework.com/) v4 Echo bot sample which accepts input from the user and echoes it back.

You may download the working code sample from [GitHub](https://github.com/abhimantiwari/botbuilder-community-dotnet/tree/develop/samples/EntityFramework%20Storage%20Sample) or make the following changes to your existing Bot project.

- Import these packages into your Bot project.

![Packages](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/47q7zf82k2pgbhuwc2pr.png)

- Add the following code to your bot project’s `Startup.cs`.

```
var loggerConnectionString = Configuration["StoreConnectionString"];
var logger = new EntityFrameworkTranscriptStore(loggerConnectionString);
     services.AddSingleton<ITranscriptStore>(logger);
```

![Startup.cs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h8hdzfxm71afenndfrlc.png)

- Add `ITranscriptStore` as one of the parameters to `AdapterWithErrorHandler` class, and Use `TranscriptLoggerMiddleware`:

```
public AdapterWithErrorHandler(ITranscriptStore transcriptLogger, IConfiguration configuration, ILogger<BotFrameworkHttpAdapter> logger, ConversationState conversationState = null)
              : base(configuration, logger)
          {
              Use(new TranscriptLoggerMiddleware(transcriptLogger));
```

![AdapterWithErrorHandler](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pg63q9ovhjncjr4ujj3q.png)

- The ConnectionString you have copied from Azure sql database, put that into your Bot project against `StoreConnectionString` key in appsettings.json file, something like shown below –

```
      {
        "MicrosoftAppId": "",
        "MicrosoftAppPassword": "",
        "StoreConnectionString": "Server=tcp:YourSQLServerName.database.windows.net,1433;Initial Catalog=YourDatabaseName;Persist Security Info=False;User ID=YourSqlUserId;Password=YourSqlPassword;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
      }
```

> **Note:**
> I have left `MicrosoftAppId` and `MicrosoftAppPassword` blank as I’ll be running my Bot locally in Emulator but if your Bot is deployed on some remote server e.g., Azure app service or Bot needs to communicate to other external services e.g., Cognitive services, then you will need to put MicrosoftAppId and MicrosoftAppPassword as well to authenticate your Bot.

We are almost done. Now you should be able to run your Bot project.

## Let’s see it in Action:

Run your bot code/ project (in case you have already hosted it to some web server e.g., Azure app service, you may skip this part) –

- If you are running from the terminal, navigate to your Bot project folder and run dotnet run command.

```
    #run the bot
    dotnet run
```

- If you are running from Visual Studio
        
1. - Launch Visual Studio
2. - File -> Open -> Project/Solution
3. - Navigate to your Bot project folder e.g., EntityFrameworkTranscriptStoreExample
4. - Select your Bot project file e.g., EntityFrameworkTranscriptStoreExample.csproj file
5. - Press F5 to run the project

> **Note:** As a prerequisite to run this project, make sure you have [.NET Core](https://dotnet.microsoft.com/en-us/download) (>=3.1) version installed on your machine.

## Test the Bot using Bot Framework Emulator:

[Bot Framework Emulator](https://github.com/microsoft/botframework-emulator) is a desktop application that allows Bot developers to Test and debug their bots on localhost or run remotely through a tunnel. You may install the Bot Framework Emulator from [here](https://github.com/Microsoft/BotFramework-Emulator/releases).

## Connect to the bot using Bot Framework Emulator:

- Launch Bot Framework Emulator
- File -> Open Bot
- Enter a Bot URL e.g., `http://localhost:3978/api/messages`. You may also enter the URL of the remote web server hosting the Bot code but, in that case, you will also need to provide `MicrosoftAppId` and `MicrosoftAppPassword` for Bot to successfully authenticate.

_Once connected, send some messages to your Bot, and it should echo them back._

![Emulator](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d8u61jgwvao4ljy5lqln.png)

## Logs:

Let’s **Connect the database** to see if Bot Activities are being recorded. You should see the messages saved into the Azure SQL tables we have created.

- `BotDataEntity` should store one entry for each unique connection.
- `TranscriptEntity` should contain all the conversations.

![SQLDBData](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/im34mxwl36v3qjtv252j.png)
If you query the tables, you should be able to fetch all the messages exchanged between the user and Bot.

![SavedBotActivities](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9npyw4fy1j0pxhprxitw.png)

> **Caution:**
> Please note that depending on your Bot, you may need to specify in your Bot’s terms of use directly to notify your users whenever storing user data is involved.