Com as caixas de diálogo de componentes, você pode criar caixas de diálogo independentes para lidar com cenários específicos, dividindo um grande conjunto de diálogos em partes mais gerenciáveis. Cada uma dessas peças tem seu próprio conjunto de diálogos e evita colisões de nomes com os conjuntos de diálogos fora dele. As caixas de diálogo dos componentes são reutilizáveis, na medida em que podem ser:
Adicionado a outro ComponentDialog ou DialogSet no seu bot.
Exportado como parte de um pacote.
Usado em outros bots.
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.
No exemplo de prompt de várias voltas, usamos uma caixa de diálogo em cascata, alguns prompts e uma caixa de diálogo de componente para criar uma interação que faz uma série de perguntas ao usuário. O código usa uma caixa de diálogo para percorrer estas etapas:
Passos
Tipo de prompt
Pergunte ao utilizador o seu modo de transporte
Prompt de escolha
Peça ao utilizador o seu nome
Prompt de texto
Pergunte ao usuário se ele deseja fornecer sua idade
Confirmar prompt
Se responderam que sim, pergunte a sua idade
Número prompt com validação para aceitar apenas idades maiores que 0 e menores que 150.
Pergunte se a informação recolhida está "ok"
Reutilizar Prompt de confirmação
Por fim, se responderem sim, exiba as informações coletadas; caso contrário, diga ao usuário que suas informações não serão mantidas.
Implementar a caixa de diálogo do componente
No exemplo de prompt de várias voltas, usamos uma caixa de diálogo em cascata, alguns prompts e uma caixa de diálogo de componente para criar uma interação que faz uma série de perguntas ao usuário.
Uma caixa de diálogo de componente encapsula uma ou mais caixas de diálogo. A caixa de diálogo do componente tem um conjunto de diálogos interno e as caixas de diálogo e prompts que você adiciona a esse conjunto de diálogos internos têm suas próprias IDs, visíveis apenas de dentro da caixa de diálogo do componente.
Para usar caixas de diálogo, instale o pacote NuGet Microsoft.Bot.Builder.Dialogs .
Caixas de diálogo\UserProfileDialog.cs
Aqui a UserProfileDialog classe deriva da ComponentDialog classe.
public class UserProfileDialog : ComponentDialog
Dentro do construtor, o AddDialog método adiciona diálogos e prompts para a caixa de diálogo do componente. O primeiro item adicionado com esse método é definido como a caixa de diálogo inicial. Você pode alterar a caixa de diálogo inicial definindo explicitamente a InitialDialogId propriedade. Quando você inicia uma caixa de diálogo de componente, ela inicia sua caixa de diálogo inicial.
public UserProfileDialog(UserState userState)
: base(nameof(UserProfileDialog))
{
_userProfileAccessor = userState.CreateProperty<UserProfile>("UserProfile");
// This array defines how the Waterfall will execute.
var waterfallSteps = new WaterfallStep[]
{
TransportStepAsync,
NameStepAsync,
NameConfirmStepAsync,
AgeStepAsync,
PictureStepAsync,
SummaryStepAsync,
ConfirmStepAsync,
};
// Add named dialogs to the DialogSet. These names are saved in the dialog state.
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), waterfallSteps));
AddDialog(new TextPrompt(nameof(TextPrompt)));
AddDialog(new NumberPrompt<int>(nameof(NumberPrompt<int>), AgePromptValidatorAsync));
AddDialog(new ChoicePrompt(nameof(ChoicePrompt)));
AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));
AddDialog(new AttachmentPrompt(nameof(AttachmentPrompt), PicturePromptValidatorAsync));
// The initial child Dialog to run.
InitialDialogId = nameof(WaterfallDialog);
}
O código a seguir representa a primeira etapa da caixa de diálogo em cascata.
private static async Task<DialogTurnResult> NameStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
stepContext.Values["transport"] = ((FoundChoice)stepContext.Result).Value;
return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("Please enter your name.") }, cancellationToken);
}
Para usar diálogos, seu projeto precisa instalar o pacote npm botbuilder-dialogs .
diálogos/userProfileDialog.js
Aqui a UserProfileDialog aula se estende.ComponentDialog
class UserProfileDialog extends ComponentDialog {
Dentro do construtor, o AddDialog método adiciona diálogos e prompts para a caixa de diálogo do componente. O primeiro item adicionado com esse método é definido como a caixa de diálogo inicial. Você pode alterar a caixa de diálogo inicial definindo explicitamente a InitialDialogId propriedade. Quando você inicia uma caixa de diálogo de componente, ela inicia sua caixa de diálogo inicial.
O código a seguir representa a primeira etapa da caixa de diálogo em cascata.
async transportStep(step) {
// WaterfallStep always finishes with the end of the Waterfall or with another dialog; here it is a Prompt Dialog.
// Running a prompt here means the next WaterfallStep will be run when the user's response is received.
return await step.prompt(CHOICE_PROMPT, {
prompt: 'Please enter your mode of transport.',
choices: ChoiceFactory.toChoices(['Car', 'Bus', 'Bicycle'])
});
}
Aqui a UserProfileDialog classe deriva da ComponentDialog classe.
public class UserProfileDialog extends ComponentDialog {
Dentro do construtor, o addDialog método adiciona diálogos e prompts para a caixa de diálogo do componente. O primeiro item adicionado com esse método é definido como a caixa de diálogo inicial. Você pode alterar a caixa de diálogo inicial chamando o setInitialDialogId método e fornecendo o nome da caixa de diálogo inicial. Quando você inicia uma caixa de diálogo de componente, ela inicia sua caixa de diálogo inicial.
public UserProfileDialog(UserState withUserState) {
super("UserProfileDialog");
userProfileAccessor = withUserState.createProperty("UserProfile");
WaterfallStep[] waterfallSteps = {
UserProfileDialog::transportStep,
UserProfileDialog::nameStep,
this::nameConfirmStep,
this::ageStep,
UserProfileDialog::pictureStep,
this::confirmStep,
this::summaryStep
};
// Add named dialogs to the DialogSet. These names are saved in the dialog state.
addDialog(new WaterfallDialog("WaterfallDialog", Arrays.asList(waterfallSteps)));
addDialog(new TextPrompt("TextPrompt"));
addDialog(new NumberPrompt<Integer>("NumberPrompt", UserProfileDialog::agePromptValidator, Integer.class));
addDialog(new ChoicePrompt("ChoicePrompt"));
addDialog(new ConfirmPrompt("ConfirmPrompt"));
addDialog(new AttachmentPrompt("AttachmentPrompt", UserProfileDialog::picturePromptValidator));
// The initial child Dialog to run.
setInitialDialogId("WaterfallDialog");
}
O código a seguir representa a primeira etapa da caixa de diálogo em cascata.
private static CompletableFuture<DialogTurnResult> nameStep(WaterfallStepContext stepContext) {
stepContext.getValues().put("transport", ((FoundChoice) stepContext.getResult()).getValue());
PromptOptions promptOptions = new PromptOptions();
promptOptions.setPrompt(MessageFactory.text("Please enter your name."));
return stepContext.prompt("TextPrompt", promptOptions);
}
Para usar diálogos, instale os pacotes botbuilder-dialogs e botbuilder-ai PyPI executando pip install botbuilder-dialogs e pip install botbuilder-ai a partir de um terminal.
diálogos/user_profile_dialog.py
Aqui a UserProfileDialog aula se estende.ComponentDialog
class UserProfileDialog(ComponentDialog):
Dentro do construtor, o add_dialog método adiciona diálogos e prompts para a caixa de diálogo do componente. O primeiro item adicionado com esse método é definido como a caixa de diálogo inicial. Você pode alterar a caixa de diálogo inicial definindo explicitamente a initial_dialog_id propriedade. Quando você inicia uma caixa de diálogo de componente, ela inicia sua caixa de diálogo inicial.
O código a seguir representa a primeira etapa da caixa de diálogo em cascata.
async def transport_step(
self, step_context: WaterfallStepContext
) -> DialogTurnResult:
# WaterfallStep always finishes with the end of the Waterfall or with another dialog;
# here it is a Prompt Dialog. Running a prompt here means the next WaterfallStep will
# be run when the users response is received.
return await step_context.prompt(
ChoicePrompt.__name__,
PromptOptions(
prompt=MessageFactory.text("Please enter your mode of transport."),
choices=[Choice("Car"), Choice("Bus"), Choice("Bicycle")],
),
)
Em tempo de execução, a caixa de diálogo do componente mantém sua própria pilha de diálogo. Quando a caixa de diálogo do componente é iniciada:
Uma instância é criada e adicionada à pilha de diálogo externa
Ele cria uma pilha de diálogo interna que adiciona ao seu estado
Ele inicia sua caixa de diálogo inicial e adiciona isso à pilha de diálogo interna.
O contexto pai vê o componente como a caixa de diálogo ativa. No entanto, para o contexto dentro do componente, parece que a caixa de diálogo inicial é a caixa de diálogo ativa.
Chamar a caixa de diálogo do bot
No conjunto de diálogos externo, aquele ao qual você adicionou a caixa de diálogo do componente, a caixa de diálogo do componente tem a ID com a qual você a criou. No conjunto externo, o componente se parece com uma única caixa de diálogo, muito parecido com os prompts.
Para usar uma caixa de diálogo de componente, adicione uma instância dela ao conjunto de diálogos do bot.
No exemplo, isso é feito usando o RunAsync método que é chamado a partir do método do OnMessageActivityAsync bot.
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
Logger.LogInformation("Running dialog with Message Activity.");
// Run the Dialog with the new message Activity.
await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
}
diálogos/userProfileDialog.js
No exemplo, adicionamos um run método à caixa de diálogo de perfil de usuário.
O run método é chamado a partir do método do onMessage bot.
this.onMessage(async (context, next) => {
console.log('Running dialog with Message Activity.');
// Run the Dialog with the new message Activity.
await this.dialog.run(context, this.dialogState);
await next();
});
DialogBot.java
No exemplo, isso é feito usando o run método que é chamado a partir do método do onMessageActivity bot.
@Override
protected CompletableFuture<Void> onMessageActivity(
TurnContext turnContext
) {
LoggerFactory.getLogger(DialogBot.class).info("Running dialog with Message Activity.");
// Run the Dialog with the new message Activity.
return Dialog.run(dialog, turnContext, conversationState.createProperty("DialogState"));
}
ajudantes/dialog_helper.py
No exemplo, adicionamos um run_dialog método à caixa de diálogo de perfil de usuário.
Inicie o emulador, conecte-se ao seu bot e envie mensagens como mostrado abaixo.
Informações adicionais
Como funciona o cancelamento para caixas de diálogo de componentes
Se você chamar cancelar todas as caixas de diálogo do contexto da caixa de diálogo do componente, a caixa de diálogo do componente cancelará todas as caixas de diálogo em sua pilha interna e, em seguida, terminará, retornando o controle para a próxima caixa de diálogo na pilha externa.
Se você chamar cancelar todas as caixas de diálogo do contexto externo, o componente será cancelado, juntamente com o restante das caixas de diálogo no contexto externo.
Próximos passos
Saiba como criar conversas complexas que se ramificam e fazem loop.