我正在尝试在我的团队机器人中添加登录选项。我从git-hub example中获取了示例代码,并将其包含在代码中。
我只希望用户在特殊情况下登录,例如当他想预订房间时。
问题出在登录完成之前,机器人已进入下一步并失败。
case LUISIntent.FindRoom:
token = await _authToken.GetAsync(turnContext, () => token);
if (token.IsNullOrWhiteSpace())
{
var resultToken = dc.BeginDialogAsync(nameof(SignInDialog),
cancellationToken: cancellationToken);
if (resultToken.Status != TaskStatus.WaitingForActivation)
{
var tokenResponse = resultToken.Result;
var tokenResult = (TokenResponse)tokenResponse.Result;
token = tokenResult.Token;
await _authToken.SetAsync(turnContext, token, cancellationToken);
}
}
await dc.BeginDialogAsync(nameof(FindRoom), luisResults);
问题是,如何才能以更好的方式集成登录,以及如何停止执行,直到获得登录对话框的返回响应
答案 0 :(得分:1)
如果您希望机器人在返回令牌之前实质上“暂停”,我将按照示例机器人所显示的进行操作。它有一个瀑布对话框,该对话框一直循环直到显示成功的令牌响应为止。
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
{
PromptStepAsync,
LoginStepAsync,
DisplayTokenPhase1Async,
DisplayTokenPhase2Async,
}));
// The initial child Dialog to run.
InitialDialogId = nameof(WaterfallDialog);
}
private async Task<DialogTurnResult> PromptStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken);
}
private async Task<DialogTurnResult> LoginStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
// Get the token from the previous step. Note that we could also have gotten the
// token directly from the prompt itself. There is an example of this in the next method.
var tokenResponse = (TokenResponse)stepContext.Result;
if (tokenResponse != null)
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text("You are now logged in."), cancellationToken);
return await stepContext.PromptAsync(nameof(ConfirmPrompt), new PromptOptions { Prompt = MessageFactory.Text("Would you like to view your token?") }, cancellationToken);
}
await stepContext.Context.SendActivityAsync(MessageFactory.Text("Login was not successful please try again."), cancellationToken);
return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
}
从这两个步骤可以看到,它会提示,然后进行检查。如果检查失败,则会结束对话框,这意味着当再次向漫游器发送消息时,瀑布将重新开始。这一直持续到返回令牌为止,然后转到“您想查看令牌”提示。显然,您不会问客户他们是否想看他们的代币,但是这个想法很可靠。
case LUISIntent.FindRoom:
//TINY WATERFALL HERE
//this waterfall would be added to your dialogs wherever you add them.
//for the sake of brevity, i'm skipping that part
//WATERFALL STEP 1:
private async Task<DialogTurnResults> GETTINGYOURLOGIN(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
token = await _authToken.GetAsync(turnContext, () => token);
return await stepContext.NextAsync(cancellationToken);
}
//WATERFALL STEP 2:
private async Task<DialogTurnResults> CHECKINGYOURLOGIN(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
// Get the token from the previous step.
//this does a quick check to see if it's NOT null, then goes to the next step.
//OTHERWISE, it continues with your login prompt.
//this way, if your user has ALREADY logged in, and for whatever reason goes BACK to the //book room dialog, they don't have to re-login if it's been a short enough time
if (!token.IsNullOrWhiteSpace())
{
await dc.BeginDialogAsync(nameof(FindRoom), luisResults);
}
var resultToken = dc.BeginDialogAsync(nameof(SignInDialog),
cancellationToken: cancellationToken);
if (resultToken.Status != TaskStatus.WaitingForActivation)
{
var tokenResponse = resultToken.Result;
var tokenResult = (TokenResponse)tokenResponse.Result;
token = tokenResult.Token;
await _authToken.SetAsync(turnContext, token, cancellationToken);
}
// Replace on the stack the current instance of the waterfall with a new instance,
// and start from the top.
return await stepContext.ReplaceDialogAsync(nameof(YOURMINIWATERFALLDIALOG), cancellationToken: cancellationToken);
}
这确实很粗糙,但足以让您大致了解我的意思。通过将您说失败的延续放入依赖于令牌的自己的if-check中,可以防止您在没有有效的延续的情况下继续前进,从而失败。