Manchmal muss ein Bot eine Unterhaltung von vorne starten. Wenn ein Benutzer beispielsweise nach einem bestimmten Zeitraum nicht reagiert. In diesem Artikel werden zwei Methoden für das Ablaufen einer Unterhaltung beschrieben:
Der Beispielcode in diesem Artikel beginnt mit der Struktur eines Bots mit mehreren Durchläufen und erweitert die Funktionalität des Bots anschließend durch Hinzufügen von zusätzlichem Code (in den folgenden Abschnitten enthalten). Dieser erweiterte Code veranschaulicht, wie der Unterhaltungszustand nach Ablauf eines bestimmten Zeitraums gelöscht wird.
Diese Art der ablaufenden Unterhaltung wird durch Hinzufügen einer Eigenschaft für den letzten Zugriff zum Unterhaltungszustand des Bots erreicht. Dieser Eigenschaftswert wird dann vor der Verarbeitung von Aktivitäten mit der aktuellen Zeit innerhalb des Aktivitätshandlers verglichen.
appsettings.json
Fügen Sie zunächst eine ExpireAfterSeconds
-Einstellung zu „appsettings.json“ hinzu:
{
"MicrosoftAppId": "",
"MicrosoftAppPassword": "",
"ExpireAfterSeconds": 30
}
Bots\DialogBot.cs
Fügen Sie dann ExpireAfterSeconds
-, LastAccessedTimeProperty
- und DialogStateProperty
-Felder zur Botklasse hinzu und initialisieren Sie sie im Konstruktor des Bots. Fügen Sie dem Konstruktor auch einen IConfiguration
-Parameter hinzu, mit dem der ExpireAfterSeconds
-Wert abgerufen werden soll.
Anstatt den Eigenschafts-Accessor für den Dialogstatus inline in der OnMessageActivityAsync
-Methode zu erstellen, wird er zur Initialisierungszeit erstellt und aufgezeichnet. Der Bot benötigt den Statuseigenschaftsaccessor nicht nur zum Ausführen des Dialogfelds, sondern auch zum Löschen des Dialogzustands.
protected readonly int ExpireAfterSeconds;
protected readonly IStatePropertyAccessor<DateTime> LastAccessedTimeProperty;
protected readonly IStatePropertyAccessor<DialogState> DialogStateProperty;
// Existing fields omitted...
public DialogBot(IConfiguration configuration, ConversationState conversationState, UserState userState, T dialog, ILogger<DialogBot<T>> logger)
{
ConversationState = conversationState;
UserState = userState;
Dialog = dialog;
Logger = logger;
ExpireAfterSeconds = configuration.GetValue<int>("ExpireAfterSeconds");
DialogStateProperty = ConversationState.CreateProperty<DialogState>(nameof(DialogState));
LastAccessedTimeProperty = ConversationState.CreateProperty<DateTime>(nameof(LastAccessedTimeProperty));
}
Fügen Sie schließlich Code zur OnTurnAsync
-Methode des Bots hinzu, um den Dialogzustand zu löschen, wenn die Unterhaltung zu alt ist.
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default)
{
// Retrieve the property value, and compare it to the current time.
var lastAccess = await LastAccessedTimeProperty.GetAsync(turnContext, () => DateTime.UtcNow, cancellationToken).ConfigureAwait(false);
if ((DateTime.UtcNow - lastAccess) >= TimeSpan.FromSeconds(ExpireAfterSeconds))
{
// Notify the user that the conversation is being restarted.
await turnContext.SendActivityAsync("Welcome back! Let's start over from the beginning.").ConfigureAwait(false);
// Clear state.
await ConversationState.ClearStateAsync(turnContext, cancellationToken).ConfigureAwait(false);
}
await base.OnTurnAsync(turnContext, cancellationToken).ConfigureAwait(false);
// Set LastAccessedTime to the current time.
await LastAccessedTimeProperty.SetAsync(turnContext, DateTime.UtcNow, cancellationToken).ConfigureAwait(false);
// Save any state changes that might have occurred during the turn.
await ConversationState.SaveChangesAsync(turnContext, false, cancellationToken).ConfigureAwait(false);
await UserState.SaveChangesAsync(turnContext, false, cancellationToken).ConfigureAwait(false);
}
.env
Fügen Sie zunächst eine ExpireAfterSeconds
-Einstellung zu „.env“ hinzu:
MicrosoftAppId=
MicrosoftAppPassword=
ExpireAfterSeconds=30
bots\dialogBot.js
Fügen Sie als dann Felder zu DialogBot
hinzu und aktualisieren Sie den Konstruktor. Fügen Sie lokale Felder für expireAfterSeconds
und lastAccessedTimeProperty
hinzu.
Fügen Sie expireAfterSeconds
als Parameter in den Konstruktor ein und erstellen Sie das erforderliche StatePropertyAccessor
:
constructor(expireAfterSeconds, conversationState, userState, dialog) {
// Existing code omitted...
this.lastAccessedTimeProperty = this.conversationState.createProperty('LastAccessedTime');
this.expireAfterSeconds = expireAfterSeconds;
// Existing code omitted...
}
Fügen Sie der run
-Methode des Bots Code hinzu:
async run(context) {
// Retrieve the property value, and compare it to the current time.
const now = new Date();
const lastAccess = new Date(await this.lastAccessedTimeProperty.get(context, now.toISOString()));
if (now !== lastAccess && ((now.getTime() - lastAccess.getTime()) / 1000) >= this.expireAfterSeconds) {
// Notify the user that the conversation is being restarted.
await context.sendActivity("Welcome back! Let's start over from the beginning.");
// Clear state.
await this.conversationState.clear(context);
}
await super.run(context);
// Set LastAccessedTime to the current time.
await this.lastAccessedTimeProperty.set(context, now.toISOString());
// Save any state changes. The load happened during the execution of the Dialog.
await this.conversationState.saveChanges(context, false);
await this.userState.saveChanges(context, false);
}
index.js
Aktualisieren Sie schließlich index.js
, um den ExpireAfterSeconds
-Parameter an DialogBot
zu senden:
const bot = new DialogBot(process.env.ExpireAfterSeconds, conversationState, userState, dialog);
application.properties
Fügen Sie zunächst eine ExpireAfterSeconds
-Einstellung zu „application.properties“ hinzu:
MicrosoftAppId=
MicrosoftAppPassword=
server.port=3978
ExpireAfterSeconds=30
DialogBot.java
Fügen Sie dann expireAfterSeconds
-, lastAccessedTimeProperty
- und dialogStateProperty
-Felder zur Botklasse hinzu und initialisieren Sie sie im Konstruktor des Bots. Fügen Sie dem Konstruktor auch einen Configuration
-Parameter hinzu, um den ExpireAfterSeconds
-Wert abzurufen.
Anstatt den Eigenschafts-Accessor für den Dialogstatus inline in der onMessageActivity
-Methode zu erstellen, erstellen und speichern Sie ihn zur Initialisierungszeit. Der Bot benötigt den Statuseigenschaftsaccessor nicht nur zum Ausführen des Dialogfelds, sondern auch zum Löschen des Dialogzustands.
protected final int expireAfterSeconds;
protected final StatePropertyAccessor<LocalTime> lastAccessedTimeProperty;
protected final StatePropertyAccessor<DialogState> dialogStateProperty;
// Existing fields omitted...
public DialogBot(
Configuration configuration,
ConversationState withConversationState,
UserState withUserState,
Dialog withDialog
) {
dialog = withDialog;
conversationState = withConversationState;
userState = withUserState;
expireAfterSeconds = configuration.getProperty("ExpireAfterSeconds") != null ?
Integer.parseInt(configuration.getProperty("ExpireAfterSeconds")) :
30;
lastAccessedTimeProperty = conversationState.createProperty("LastAccessedTimeProperty");
dialogStateProperty = conversationState.createProperty("DialogStateProperty");
}
Fügen Sie schließlich Code zur onTurn
-Methode des Bots hinzu, um den Dialogzustand zu löschen, wenn die Unterhaltung zu alt ist.
@Override
public CompletableFuture<Void> onTurn(
TurnContext turnContext
) {
LocalTime lastAccess = lastAccessedTimeProperty.get(turnContext).join();
if (lastAccess != null
&& (java.time.temporal.ChronoUnit.SECONDS.between(lastAccess, LocalTime.now()) >= expireAfterSeconds)) {
turnContext.sendActivity("Welcome back! Let's start over from the beginning.").join();
conversationState.clearState(turnContext).join();
}
return lastAccessedTimeProperty.set(turnContext, LocalTime.now()).thenCompose(setResult -> {
return super.onTurn(turnContext)
.thenCompose(result -> conversationState.saveChanges(turnContext))
// Save any state changes that might have occurred during the turn.
.thenCompose(result -> userState.saveChanges(turnContext));
});
}
config.py
Fügen Sie zunächst eine ExpireAfterSeconds
-Einstellung zu „config.py“ hinzu:
PORT = 3978
APP_ID = os.environ.get("MicrosoftAppId", "")
APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "")
EXPIRE_AFTER_SECONDS = os.environ.get("ExpireAfterSeconds", 30)
bots\dialog_bot.py
Fügen Sie als dann Felder zu DialogBot
hinzu und aktualisieren Sie den Konstruktor. Fügen Sie lokale Felder für expire_after_seconds
und last_accessed_time_property
hinzu.
Fügen Sie expire_after_seconds
als Parameter in den Konstruktor ein und erstellen Sie das erforderliche StatePropertyAccessor
:
def __init__(
self,
expire_after_seconds: int,
conversation_state: ConversationState,
user_state: UserState,
dialog: Dialog,
):
# Existing code omitted...
self.expire_after_seconds = expire_after_seconds
self.dialog_state_property = conversation_state.create_property("DialogState")
self.last_accessed_time_property = conversation_state.create_property("LastAccessedTime")
self.conversation_state = conversation_state
self.user_state = user_state
self.dialog = dialog
Ändern Sie on_message_activity
, sodass es dialog_state_property
verwendet:
async def on_message_activity(self, turn_context: TurnContext):
await DialogHelper.run_dialog(
self.dialog,
turn_context,
self.dialog_state_property,
)
Fügen Sie der on_turn
-Methode des Bots Code hinzu:
async def on_turn(self, turn_context: TurnContext):
# Retrieve the property value, and compare it to the current time.
now_seconds = int(time.time())
last_access = int(
await self.last_accessed_time_property.get(turn_context, now_seconds)
)
if now_seconds != last_access and (
now_seconds - last_access >= self.expire_after_seconds
):
# Notify the user that the conversation is being restarted.
await turn_context.send_activity(
"Welcome back! Let's start over from the beginning."
)
# Clear state.
await self.conversation_state.clear_state(turn_context)
await self.conversation_state.save_changes(turn_context, True)
await super().on_turn(turn_context)
# Set LastAccessedTime to the current time.
await self.last_accessed_time_property.set(turn_context, now_seconds)
# Save any state changes that might have occurred during the turn.
await self.conversation_state.save_changes(turn_context)
await self.user_state.save_changes(turn_context)
app.py
Aktualisieren Sie schließlich app.py
, um den EXPIRE_AFTER_SECONDS
-Parameter an DialogBot
zu senden:
BOT = DialogBot(CONFIG.EXPIRE_AFTER_SECONDS, CONVERSATION_STATE, USER_STATE, DIALOG)
Cosmos DB bietet ein Gültigkeitsdauer-Feature (Time to Live, TTL), das es Ihnen ermöglicht, Objekte nach einer bestimmten Zeitspanne automatisch aus einem Container zu löschen. Dies kann innerhalb des Azure-Portal oder während der Containererstellung (mit den sprachspezifischen Cosmos DB SDKs) konfiguriert werden.
Das Bot Framework SDK macht keine TTL-Konfigurationseinstellung verfügbar. Containerinitialisierung kann jedoch überschrieben werden und das Cosmos DB SDK kann verwendet werden, um TTL vor der Bot-Framework-Speicherinitialisierung zu konfigurieren.
Beginnen Sie mit einer neuen Kopie des Beispiels Multi-Turn-Prompt und fügen Sie das Microsoft.Bot.Builder.Azure
-NuGet-Paket dem Projekt hinzu.
appsettings.json
Aktualisieren Sie „appsettings.json“, um Cosmos-DB-Speicheroptionen einzuschließen:
{
"MicrosoftAppId": "",
"MicrosoftAppPassword": "",
"CosmosDbTimeToLive": 30,
"CosmosDbEndpoint": "<endpoint-for-your-cosmosdb-instance>",
"CosmosDbAuthKey": "<your-cosmosdb-auth-key>",
"CosmosDbDatabaseId": "<your-database-id>",
"CosmosDbUserStateContainerId": "<no-ttl-container-id>",
"CosmosDbConversationStateContainerId": "<ttl-container-id>"
}
Beachten Sie die beiden ContainerIds, eine für UserState
und eine für ConversationState
. Die Standard-TTL wird für den ConversationState
-Container festgelegt, aber nicht für UserState
.
CosmosDbStorageInitializerHostedService.cs
Erstellen Sie als dann eine CosmosDbStorageInitializerHostedService
-Klasse, die den Container mit dem konfigurierten Gültigkeitsdauer-Objekt erstellt.
// Add required using statements...
public class CosmosDbStorageInitializerHostedService : IHostedService
{
readonly CosmosDbPartitionedStorageOptions _storageOptions;
readonly int _cosmosDbTimeToLive;
public CosmosDbStorageInitializerHostedService(IConfiguration config)
{
_storageOptions = new CosmosDbPartitionedStorageOptions()
{
CosmosDbEndpoint = config["CosmosDbEndpoint"],
AuthKey = config["CosmosDbAuthKey"],
DatabaseId = config["CosmosDbDatabaseId"],
ContainerId = config["CosmosDbConversationStateContainerId"]
};
_cosmosDbTimeToLive = config.GetValue<int>("CosmosDbTimeToLive");
}
public async Task StartAsync(CancellationToken cancellationToken)
{
using (var client = new CosmosClient(
_storageOptions.CosmosDbEndpoint,
_storageOptions.AuthKey,
_storageOptions.CosmosClientOptions ?? new CosmosClientOptions()))
{
// Create the contaier with the provided TTL
var containerResponse = await client
.GetDatabase(_storageOptions.DatabaseId)
.DefineContainer(_storageOptions.ContainerId, "/id")
.WithDefaultTimeToLive(_cosmosDbTimeToLive)
.WithIndexingPolicy().WithAutomaticIndexing(false).Attach()
.CreateIfNotExistsAsync(_storageOptions.ContainerThroughput)
.ConfigureAwait(false);
}
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
Startup.cs
Aktualisieren Sie schließlich Startup.cs
, um den Speicherinitialisierer und Cosmos DB für den Zustand zu verwenden:
// Existing code omitted...
// commented out MemoryStorage, since we are using CosmosDbPartitionedStorage instead
// services.AddSingleton<IStorage, MemoryStorage>();
// Add the Initializer as a HostedService (so it's called during the app service startup)
services.AddHostedService<CosmosDbStorageInitializerHostedService>();
// Create the storage options for User state
var userStorageOptions = new CosmosDbPartitionedStorageOptions()
{
CosmosDbEndpoint = Configuration["CosmosDbEndpoint"],
AuthKey = Configuration["CosmosDbAuthKey"],
DatabaseId = Configuration["CosmosDbDatabaseId"],
ContainerId = Configuration["CosmosDbUserStateContainerId"]
};
// Create the User state. (Used in this bot's Dialog implementation.)
services.AddSingleton(new UserState(new CosmosDbPartitionedStorage(userStorageOptions)));
// Create the storage options for Conversation state
var conversationStorageOptions = new CosmosDbPartitionedStorageOptions()
{
CosmosDbEndpoint = Configuration["CosmosDbEndpoint"],
AuthKey = Configuration["CosmosDbAuthKey"],
DatabaseId = Configuration["CosmosDbDatabaseId"],
ContainerId = Configuration["CosmosDbConversationStateContainerId"]
};
// Create the Conversation state. (Used by the Dialog system itself.)
services.AddSingleton(new ConversationState(new CosmosDbPartitionedStorage(conversationStorageOptions)));
// Existing code omitted...
Beginnen Sie mit einer neuen Kopie des Beispiels Multi-Turn-Prompt.
.env
Aktualisieren Sie „.env“, um Cosmos-DB-Speicheroptionen einzuschließen:
MicrosoftAppId=
MicrosoftAppPassword=
CosmosDbTimeToLive=30
CosmosDbEndpoint=<endpoint-for-your-cosmosdb-instance>
CosmosDbAuthKey=<your-cosmosdb-auth-key>
CosmosDbDatabaseId=<your-database-id>
CosmosDbUserStateContainerId=<no-ttl-container-id>
CosmosDbConversationStateContainerId=<ttl-container-id>
Beachten Sie die beiden ContainerIds, eine für UserState
und eine für ConversationState
. Die Standard-TTL wird für den ConversationState
-Container festgelegt, aber nicht UserState
.
project.json
Fügen Sie als Nächstes das botbuilder-azure
-npm-Paket zu „project.json“ hinzu.
"dependencies": {
"botbuilder": "~4.9.2",
"botbuilder-dialogs": "~4.9.2",
"botbuilder-azure": "~4.9.2",
"dotenv": "^8.2.0",
"path": "^0.12.7",
"restify": "~8.5.1"
},
index.js
Fügen Sie die erforderlichen Anweisungen zu „index.js“ hinzu:
const { CosmosDbPartitionedStorage } = require('botbuilder-azure');
const { CosmosClient } = require('@azure/cosmos');
Ersetzen Sie MemoryStorage
-, ConversationState
- und UserState
-Kreation durch:
// const memoryStorage = new MemoryStorage();
// Storage options for Conversation State
const conversationStorageOptions = {
cosmosDbEndpoint: process.env.CosmosDbEndpoint,
authKey: process.env.CosmosDbAuthKey,
databaseId: process.env.CosmosDbDatabaseId,
containerId: process.env.CosmosDbConversationStateContainerId
};
// Create a cosmosClient, and set defaultTtl (with other properties)
var cosmosClient = new CosmosClient({
endpoint: conversationStorageOptions.cosmosDbEndpoint,
key: conversationStorageOptions.authKey,
...conversationStorageOptions.cosmosClientOptions,
});
// Create the container with the provided TTL.
Promise.resolve(cosmosClient
.database(conversationStorageOptions.databaseId)
.containers.createIfNotExists({
id: conversationStorageOptions.containerId,
partitionKey: {
paths: ['/id']
},
defaultTtl: parseInt(process.env.CosmosDbTimeToLive, 10)
}));
// Storage options for User State
const userStorageOptions = {
cosmosDbEndpoint: process.env.CosmosDbEndpoint,
authKey: process.env.CosmosDbAuthKey,
databaseId: process.env.CosmosDbDatabaseId,
containerId: process.env.CosmosDbUserStateContainerId
};
// Create state instances.
const conversationState = new ConversationState(new CosmosDbPartitionedStorage(conversationStorageOptions));
const userState = new UserState(new CosmosDbPartitionedStorage(userStorageOptions));
Führen Sie schließlich „npm install“ aus, bevor Sie Ihren Bot starten.
npm install
Beginnen Sie mit einer neuen Kopie des Beispiels Multi-Turn-Prompt und fügen Sie der Datei „pom.xml“ die folgenden Abhängigkeiten hinzu:
<dependency>
<groupId>com.microsoft.bot</groupId>
<artifactId>bot-azure</artifactId>
<version>4.13.0</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-cosmos</artifactId>
</dependency>
application.properties
Aktualisieren Sie „application.properties“, um Cosmos-DB-Speicheroptionen einzuschließen:
MicrosoftAppId=
MicrosoftAppPassword=
server.port=3978
CosmosDbTimeToLive = 30
CosmosDbEndpoint = <endpoint-for-your-cosmosdb-instance>
CosmosDbAuthKey = <your-cosmosdb-auth-key>
CosmosDbDatabaseId = <your-database-id>
CosmosDbUserStateContainerId = <no-ttl-container-id>
CosmosDbConversationStateContainerId = <ttl-container-id>
Beachten Sie die beiden ContainerIds, eine für UserState
und eine für ConversationState
. Die Standard-TTL wird für den ConversationState
-Container festgelegt, aber nicht für UserState
.
CosmosDbStorageInitializer.java
Erstellen Sie als dann eine CosmosDbStorageInitializer
-Klasse, die den Container mit dem konfigurierten Gültigkeitsdauer-Objekt erstellt.
package com.microsoft.bot.sample.multiturnprompt;
import com.azure.cosmos.CosmosAsyncClient;
import com.azure.cosmos.CosmosClientBuilder;
import com.azure.cosmos.models.CosmosContainerProperties;
import com.microsoft.bot.azure.CosmosDbPartitionedStorageOptions;
import com.microsoft.bot.integration.Configuration;
public class CosmosDbStorageInitializer {
final CosmosDbPartitionedStorageOptions storageOptions;
final int cosmosDbTimeToLive;
public CosmosDbStorageInitializer(Configuration configuration) {
storageOptions = new CosmosDbPartitionedStorageOptions();
storageOptions.setCosmosDbEndpoint(configuration.getProperty("CosmosDbEndpoint"));
storageOptions.setAuthKey(configuration.getProperty("CosmosDbAuthKey"));
storageOptions.setDatabaseId(configuration.getProperty("CosmosDbDatabaseId"));
storageOptions.setContainerId(configuration.getProperty("CosmosDbConversationStateContainerId"));
cosmosDbTimeToLive = configuration.getProperty("CosmosDbTimeToLive") != null
? Integer.parseInt(configuration.getProperty("CosmosDbTimeToLive"))
: 30;
}
public void initialize() {
CosmosAsyncClient client = new CosmosClientBuilder().endpoint(storageOptions.getCosmosDbEndpoint())
.key(storageOptions.getAuthKey()).buildAsyncClient();
client.createDatabaseIfNotExists(storageOptions.getDatabaseId()).block();
CosmosContainerProperties cosmosContainerProperties = new CosmosContainerProperties(
storageOptions.getContainerId(), "/id");
cosmosContainerProperties.setDefaultTimeToLiveInSeconds(cosmosDbTimeToLive);
client.getDatabase(storageOptions.getDatabaseId()).createContainerIfNotExists(cosmosContainerProperties)
.block();
client.close();
}
}
Application.java
Aktualisieren Sie schließlich Application.java
, um den Speicherinitialisierer und Cosmos DB für den Zustand zu verwenden:
// Existing code omitted...
@Override
public ConversationState getConversationState(Storage storage) {
Configuration configuration = getConfiguration();
CosmosDbStorageInitializer initializer = new CosmosDbStorageInitializer(configuration);
initializer.initialize();
CosmosDbPartitionedStorageOptions storageOptions = new CosmosDbPartitionedStorageOptions();
storageOptions.setCosmosDbEndpoint(configuration.getProperty("CosmosDbEndpoint"));
storageOptions.setAuthKey(configuration.getProperty("CosmosDbAuthKey"));
storageOptions.setDatabaseId(configuration.getProperty("CosmosDbDatabaseId"));
storageOptions.setContainerId(configuration.getProperty("CosmosDbConversationStateContainerId"));
return new ConversationState(new CosmosDbPartitionedStorage(storageOptions));
}
/**
* Returns a UserState object. Default scope of Singleton.
*
* @param storage The Storage object to use.
* @return A UserState object.
*/
@Override
public UserState getUserState(Storage storage) {
Configuration configuration = getConfiguration();
CosmosDbPartitionedStorageOptions storageOptions = new CosmosDbPartitionedStorageOptions();
storageOptions.setCosmosDbEndpoint(configuration.getProperty("CosmosDbEndpoint"));
storageOptions.setAuthKey(configuration.getProperty("CosmosDbAuthKey"));
storageOptions.setDatabaseId(configuration.getProperty("CosmosDbDatabaseId"));
storageOptions.setContainerId(configuration.getProperty("CosmosDbUserStateContainerId"));
return new UserState(new CosmosDbPartitionedStorage(storageOptions));
}
Beginnen Sie mit einer neuen Kopie des Beispiels Multi-Turn-Prompt.
config.py
Aktualisieren Sie config.py
, um Cosmos-DB-Speicheroptionen einzuschließen:
PORT = 3978
APP_ID = os.environ.get("MicrosoftAppId", "")
APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "")
COSMOSDB_TTL = os.environ.get("CosmosDbTimeToLive", 30)
COSMOSDB_ENDPOINT = os.environ.get("CosmosDbEndpoint", "<endpoint-for-your-cosmosdb-instance>")
COSMOSDB_AUTH_KEY = os.environ.get("CosmosDbAuthKey", "<your-cosmosdb-auth-key>")
COSMOSDB_DATABASE_ID = os.environ.get("CosmosDbDatabaseId", "<your-database-id>")
COSMOSDB_USER_STATE_CONTAINER_ID = os.environ.get("CosmosDbUserStateContainerId", "<no-ttl-container-id>")
COSMOSDB_CONVERSATION_STATE_CONTAINER_ID = os.environ.get("CosmosDbConversationStateContainerId", "<ttl-container-id>")
Beachten Sie die beiden ContainerIds, eine für UserState
und eine für ConversationState
. Die Standard-TTL wird für den ConversationState
-Container festgelegt, aber nicht UserState
.
requirements.txt
Fügen Sie als Nächstes das botbuilder-azure
-Paket zu „requirements.txt“ hinzu.
botbuilder-integration-aiohttp>=4.10.0
botbuilder-dialogs>=4.10.0
botbuilder-ai>=4.10.0
botbuilder-azure>=4.10.0
Führen Sie dann „pip install“ aus:
pip install -r requirements.txt
app.py
client = cosmos_client.CosmosClient(
CONFIG.COSMOSDB_ENDPOINT, {"masterKey": CONFIG.COSMOSDB_AUTH_KEY},
)
containers = list(client.QueryContainers("dbs/" + CONFIG.COSMOSDB_DATABASE_ID, {
"query": "SELECT * FROM r WHERE r.id=@id",
"parameters": [
{"name": "@id", "value": CONFIG.COSMOSDB_CONVERSATION_STATE_CONTAINER_ID}
],
}))
if len(containers) < 1:
new_container = client.CreateContainer(
"dbs/" + CONFIG.COSMOSDB_DATABASE_ID,
{
"defaultTtl": CONFIG.COSMOSDB_TTL,
"id": CONFIG.COSMOSDB_CONVERSATION_STATE_CONTAINER_ID,
"partitionKey": {"paths": ["/id"], "kind": "Hash",},
},
)
Cosmos DB löscht jetzt automatisch Unterhaltungszustands-Datensätze nach 30 Sekunden Inaktivität.