114 lines
4.3 KiB
JavaScript
114 lines
4.3 KiB
JavaScript
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT License.
|
|
|
|
const {
|
|
ChoicePrompt,
|
|
DialogSet,
|
|
DialogTurnStatus,
|
|
OAuthPrompt,
|
|
TextPrompt,
|
|
WaterfallDialog
|
|
} = require('botbuilder-dialogs');
|
|
const { LogoutDialog } = require('./logoutDialog');
|
|
const { OAuthHelpers } = require('../OAuthHelpers');
|
|
|
|
const MAIN_WATERFALL_DIALOG = 'mainWaterfallDialog';
|
|
const OAUTH_PROMPT = 'oAuthPrompt';
|
|
const CHOICE_PROMPT = 'choicePrompt';
|
|
const TEXT_PROMPT = 'textPrompt';
|
|
|
|
class MainDialog extends LogoutDialog {
|
|
constructor() {
|
|
super('MainDialog');
|
|
this.addDialog(new ChoicePrompt(CHOICE_PROMPT))
|
|
.addDialog(
|
|
new OAuthPrompt(OAUTH_PROMPT, {
|
|
connectionName: process.env.ConnectionName,
|
|
text: 'Please login',
|
|
title: 'Login',
|
|
timeout: 300000
|
|
})
|
|
)
|
|
.addDialog(new TextPrompt(TEXT_PROMPT))
|
|
.addDialog(
|
|
new WaterfallDialog(MAIN_WATERFALL_DIALOG, [
|
|
this.promptStep.bind(this),
|
|
this.loginStep.bind(this),
|
|
this.commandStep.bind(this),
|
|
this.processStep.bind(this)
|
|
])
|
|
);
|
|
|
|
this.initialDialogId = MAIN_WATERFALL_DIALOG;
|
|
}
|
|
|
|
/**
|
|
* The run method handles the incoming activity (in the form of a TurnContext) and passes it through the dialog system.
|
|
* If no dialog is active, it will start the default dialog.
|
|
* @param {*} turnContext
|
|
* @param {*} accessor
|
|
*/
|
|
async run(turnContext, accessor) {
|
|
const dialogSet = new DialogSet(accessor);
|
|
dialogSet.add(this);
|
|
|
|
const dialogContext = await dialogSet.createContext(turnContext);
|
|
const results = await dialogContext.continueDialog();
|
|
if (results.status === DialogTurnStatus.empty) {
|
|
await dialogContext.beginDialog(this.id);
|
|
}
|
|
}
|
|
|
|
async promptStep(step) {
|
|
return step.beginDialog(OAUTH_PROMPT);
|
|
}
|
|
|
|
async loginStep(step) {
|
|
// 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.
|
|
const tokenResponse = step.result;
|
|
if (tokenResponse) {
|
|
await OAuthHelpers.listMe(step.context, tokenResponse);
|
|
return await step.prompt(TEXT_PROMPT, {
|
|
prompt: "What would you like to do? You can type anything or 'logout' to retry."
|
|
});
|
|
}
|
|
await step.context.sendActivity('Login was not successful please try again.');
|
|
return await step.endDialog();
|
|
}
|
|
|
|
async commandStep(step) {
|
|
step.values.command = step.result;
|
|
|
|
// Call the prompt again because we need the token. The reasons for this are:
|
|
// 1. If the user is already logged in we do not need to store the token locally in the bot and worry
|
|
// about refreshing it. We can always just call the prompt again to get the token.
|
|
// 2. We never know how long it will take a user to respond. By the time the
|
|
// user responds the token may have expired. The user would then be prompted to login again.
|
|
//
|
|
// There is no reason to store the token locally in the bot because we can always just call
|
|
// the OAuth prompt to get the token or get a new token if needed.
|
|
return await step.beginDialog(OAUTH_PROMPT);
|
|
}
|
|
|
|
async processStep(step) {
|
|
if (step.result) {
|
|
// We do not need to store the token in the bot. When we need the token we can
|
|
// send another prompt. If the token is valid the user will not need to log back in.
|
|
// The token will be available in the Result property of the task.
|
|
const tokenResponse = step.result;
|
|
|
|
// If we have the token use the user is authenticated so we may use it to make API calls.
|
|
if (tokenResponse && tokenResponse.token) {
|
|
await OAuthHelpers.listMe(step.context, tokenResponse);
|
|
}
|
|
} else {
|
|
await step.context.sendActivity("We couldn't log you in. Please try again later.");
|
|
}
|
|
|
|
return await step.endDialog();
|
|
}
|
|
}
|
|
|
|
module.exports.MainDialog = MainDialog;
|