Switch from TSLint to ESLint for TypeScript samples (#3969)
* Switch from TSLint to ESLint for TypeScript samples * Update ci-javascript-samples.yml Updating eslint for both file types i.e. .js and .ts * eslint-plugin-import * eslint-plugin-n * Resolving dependencies * jsonwebtoken
This commit is contained in:
Родитель
df21f1a703
Коммит
62a768d02c
|
@ -94,9 +94,5 @@ jobs:
|
|||
|
||||
- name: yarn lint
|
||||
run: |
|
||||
if ${{ endsWith(matrix.files[0], '.js') }}; then
|
||||
yarn eslint ${{ join(matrix.files, ' ') }}
|
||||
else
|
||||
yarn tslint ${{ join(matrix.files, ' ') }}
|
||||
fi
|
||||
yarn eslint ${{ join(matrix.files, ' ') }}
|
||||
working-directory: ${{ matrix.folder }}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
module.exports = {
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"rules": {
|
||||
"semi": [2, "always"],
|
||||
"indent": [2, 4],
|
||||
"no-return-await": 0,
|
||||
"space-before-function-paren": [2, {
|
||||
"named": "never",
|
||||
"anonymous": "never",
|
||||
"asyncArrow": "always"
|
||||
}],
|
||||
"template-curly-spacing": [2, "always"]
|
||||
}
|
||||
};
|
|
@ -7,7 +7,7 @@
|
|||
"main": "./lib/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc --build",
|
||||
"lint": "tslint -c tslint.json 'src/**/*.ts'",
|
||||
"lint": "eslint -c .eslintrc.js --ext .ts src",
|
||||
"postinstall": "npm run build && node ./deploymentScripts/webConfigPrep.js",
|
||||
"start": "tsc --build && node ./lib/index.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
|
@ -24,8 +24,15 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/restify": "8.4.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
||||
"@typescript-eslint/parser": "^7.8.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"nodemon": "~2.0.4",
|
||||
"tslint": "~6.1.2",
|
||||
"typescript": "~4.3.2"
|
||||
"typescript": "~4.9.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import * as restify from 'restify';
|
|||
// See https://aka.ms/bot-services to learn more about the different parts of a bot.
|
||||
import {
|
||||
CloudAdapter,
|
||||
ConfigurationServiceClientCredentialFactory,
|
||||
ConfigurationBotFrameworkAuthentication,
|
||||
ConfigurationBotFrameworkAuthenticationOptions
|
||||
} from 'botbuilder';
|
||||
|
@ -54,5 +53,5 @@ const myBot = new EmptyBot();
|
|||
// Listen for incoming requests.
|
||||
server.post('/api/messages', async (req, res) => {
|
||||
// Route received a request to adapter for processing
|
||||
await adapter.process(req, res, (context) => myBot.run(context))
|
||||
await adapter.process(req, res, (context) => myBot.run(context));
|
||||
});
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"interface-name" : [true, "never-prefix"],
|
||||
"max-line-length": [false],
|
||||
"no-console": [false, "log", "error"],
|
||||
"no-var-requires": false,
|
||||
"quotemark": [true, "single"],
|
||||
"one-variable-per-declaration": false,
|
||||
"curly": [true, "ignore-same-line"],
|
||||
"trailing-comma": [true, {"multiline": "never", "singleline": "never"}]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
module.exports = {
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"rules": {
|
||||
"semi": [2, "always"],
|
||||
"indent": [2, 4],
|
||||
"no-return-await": 0,
|
||||
"space-before-function-paren": [2, {
|
||||
"named": "never",
|
||||
"anonymous": "never",
|
||||
"asyncArrow": "always"
|
||||
}],
|
||||
"template-curly-spacing": [2, "always"]
|
||||
}
|
||||
};
|
|
@ -7,7 +7,7 @@
|
|||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "tsc --build",
|
||||
"lint": "tslint -c tslint.json 'src/**/*.ts'",
|
||||
"lint": "eslint -c .eslintrc.js --ext .ts src",
|
||||
"start": "tsc --build && node ./lib/index.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"watch": "nodemon --watch ./src -e ts --exec \"npm run start\""
|
||||
|
@ -17,8 +17,16 @@
|
|||
"readline": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jsonwebtoken": "^9.0.6",
|
||||
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
||||
"@typescript-eslint/parser": "^7.8.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"nodemon": "~1.19.4",
|
||||
"tslint": "^5.20.0",
|
||||
"typescript": "~4.3.2"
|
||||
"typescript": "~4.9.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import { ActivityTypes, TurnContext } from 'botbuilder';
|
|||
* Simple bot that echoes received messages.
|
||||
*/
|
||||
export class ConsoleEchoBot {
|
||||
|
||||
/**
|
||||
* Driver code for the bot. This bot only responds to "Message"-type
|
||||
* Activities. If the user's message is "quit", the process will exit.
|
||||
|
@ -26,5 +25,5 @@ export class ConsoleEchoBot {
|
|||
await turnContext.sendActivity(`You sent '${ turnContext.activity.text }'`);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ export class ConsoleAdapter extends BotAdapter {
|
|||
this.reference = {
|
||||
bot: { id: 'bot', name: 'Bot' },
|
||||
channelId: 'console',
|
||||
conversation: { id: 'convo1', name: '', isGroup: false },
|
||||
conversation: { id: 'convo1', name: '', isGroup: false },
|
||||
serviceUrl: '',
|
||||
user: { id: 'user', name: 'User1' },
|
||||
...reference
|
||||
|
@ -123,12 +123,12 @@ export class ConsoleAdapter extends BotAdapter {
|
|||
* @param logic A function handler that will be called to perform the bots logic after the the adapters middleware has been run.
|
||||
*/
|
||||
public continueConversation(reference: ConversationReference, logic: (context: TurnContext) => Promise<void>): Promise<void> {
|
||||
// Create context and run middleware pipe
|
||||
const activity: Partial<Activity> = TurnContext.applyConversationReference({}, reference, true);
|
||||
const context: TurnContext = new TurnContext(this, activity);
|
||||
// Create context and run middleware pipe
|
||||
const activity: Partial<Activity> = TurnContext.applyConversationReference({}, reference, true);
|
||||
const context: TurnContext = new TurnContext(this, activity);
|
||||
|
||||
return this.runMiddleware(context, logic)
|
||||
.catch((err: Error) => { this.printError(err.toString()); });
|
||||
return this.runMiddleware(context, logic)
|
||||
.catch((err: Error) => { this.printError(err.toString()); });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,25 +143,26 @@ export class ConsoleAdapter extends BotAdapter {
|
|||
*/
|
||||
public async sendActivities(context: TurnContext, activities: Array <Partial<Activity>>): Promise<ResourceResponse[]> {
|
||||
const responses: ResourceResponse[] = [];
|
||||
for(const activity of activities) {
|
||||
for (const activity of activities) {
|
||||
responses.push({} as ResourceResponse);
|
||||
|
||||
switch (activity.type) {
|
||||
case 'delay' as ActivityTypes:
|
||||
await this.sleep(activity.value);
|
||||
break;
|
||||
case ActivityTypes.Message:
|
||||
if (activity.attachments && activity.attachments.length > 0) {
|
||||
const append: string = activity.attachments.length === 1
|
||||
? `(1 attachment)` : `(${activity.attachments.length} attachments)`;
|
||||
this.print(`${activity.text} ${append}`);
|
||||
} else {
|
||||
this.print(activity.text || '');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
this.print(`[${activity.type}]`);
|
||||
break;
|
||||
case 'delay' as ActivityTypes:
|
||||
await this.sleep(activity.value);
|
||||
break;
|
||||
case ActivityTypes.Message:
|
||||
if (activity.attachments && activity.attachments.length > 0) {
|
||||
const append: string = activity.attachments.length === 1
|
||||
? '(1 attachment)'
|
||||
: `(${ activity.attachments.length } attachments)`;
|
||||
this.print(`${ activity.text } ${ append }`);
|
||||
} else {
|
||||
this.print(activity.text || '');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
this.print(`[${ activity.type }]`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return responses;
|
||||
|
@ -172,7 +173,7 @@ export class ConsoleAdapter extends BotAdapter {
|
|||
* will result an error being returned.
|
||||
*/
|
||||
public updateActivity(context: TurnContext, activity: Partial<Activity>): Promise<void> {
|
||||
return Promise.reject(new Error(`ConsoleAdapter.updateActivity(): not supported.`));
|
||||
return Promise.reject(new Error('ConsoleAdapter.updateActivity(): not supported.'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,7 +181,7 @@ export class ConsoleAdapter extends BotAdapter {
|
|||
* will result an error being returned.
|
||||
*/
|
||||
public deleteActivity(context: TurnContext, reference: Partial<ConversationReference>): Promise<void> {
|
||||
return Promise.reject(new Error(`ConsoleAdapter.deleteActivity(): not supported.`));
|
||||
return Promise.reject(new Error('ConsoleAdapter.deleteActivity(): not supported.'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { ConsoleAdapter} from './consoleAdapter';
|
||||
import { ConsoleAdapter } from './consoleAdapter';
|
||||
|
||||
import { ConsoleEchoBot } from './bot';
|
||||
|
||||
|
@ -17,7 +17,7 @@ const echoBot: ConsoleEchoBot = new ConsoleEchoBot();
|
|||
// `adapter.listen` tells the adapter to listen for incoming messages
|
||||
// and events, known as "Activities."
|
||||
// Activities are wrapped in TurnContext objects by the handler function.
|
||||
const closeFn = adapter.listen(async (turnContext: TurnContext) => {
|
||||
adapter.listen(async (turnContext: TurnContext) => {
|
||||
await echoBot.onTurn(turnContext);
|
||||
});
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"interface-name" : [true, "never-prefix"],
|
||||
"max-line-length": [false],
|
||||
"no-console": [false, "log", "error"],
|
||||
"no-var-requires": false,
|
||||
"quotemark": [true, "single"],
|
||||
"one-variable-per-declaration": false,
|
||||
"curly": [true, "ignore-same-line"],
|
||||
"trailing-comma": [true, {"multiline": "never", "singleline": "never"}]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
module.exports = {
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"rules": {
|
||||
"semi": [2, "always"],
|
||||
"indent": [2, 4],
|
||||
"no-return-await": 0,
|
||||
"space-before-function-paren": [2, {
|
||||
"named": "never",
|
||||
"anonymous": "never",
|
||||
"asyncArrow": "always"
|
||||
}],
|
||||
"template-curly-spacing": [2, "always"]
|
||||
}
|
||||
};
|
|
@ -7,7 +7,7 @@
|
|||
"main": "./lib/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc --build",
|
||||
"lint": "tslint -c tslint.json 'src/**/*.ts'",
|
||||
"lint": "eslint -c .eslintrc.js --ext .ts src",
|
||||
"postinstall": "npm run build && node ./deploymentScripts/webConfigPrep.js",
|
||||
"start": "tsc --build && node ./lib/index.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
|
@ -27,8 +27,15 @@
|
|||
"@types/dotenv": "6.1.1",
|
||||
"@types/node": "^16.11.6",
|
||||
"@types/restify": "8.4.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
||||
"@typescript-eslint/parser": "^7.8.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"nodemon": "~2.0.4",
|
||||
"tslint": "~6.1.2",
|
||||
"typescript": "~4.3.2"
|
||||
"typescript": "~4.9.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
|
||||
import * as path from 'path';
|
||||
|
||||
import { config } from 'dotenv';
|
||||
const ENV_FILE = path.join(__dirname, '..', '.env');
|
||||
config({ path: ENV_FILE });
|
||||
|
||||
import * as restify from 'restify';
|
||||
|
||||
import { INodeSocket } from 'botframework-streaming';
|
||||
|
@ -15,7 +11,6 @@ import { INodeSocket } from 'botframework-streaming';
|
|||
// See https://aka.ms/bot-services to learn more about the different parts of a bot.
|
||||
import {
|
||||
CloudAdapter,
|
||||
ConfigurationServiceClientCredentialFactory,
|
||||
ConfigurationBotFrameworkAuthentication,
|
||||
ConfigurationBotFrameworkAuthenticationOptions
|
||||
} from 'botbuilder';
|
||||
|
@ -23,11 +18,15 @@ import {
|
|||
// This bot's main dialog.
|
||||
import { EchoBot } from './bot';
|
||||
|
||||
import { config } from 'dotenv';
|
||||
const ENV_FILE = path.join(__dirname, '..', '.env');
|
||||
config({ path: ENV_FILE });
|
||||
|
||||
// Create HTTP server.
|
||||
const server = restify.createServer();
|
||||
server.use(restify.plugins.bodyParser());
|
||||
server.listen(process.env.port || process.env.PORT || 3978, () => {
|
||||
console.log(`\n${server.name} listening to ${server.url}`);
|
||||
console.log(`\n${ server.name } listening to ${ server.url }`);
|
||||
console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator');
|
||||
console.log('\nTo talk to your bot, open the emulator select "Open Bot"');
|
||||
});
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"interface-name" : [true, "never-prefix"],
|
||||
"max-line-length": [false],
|
||||
"no-console": [false, "log", "error"],
|
||||
"no-var-requires": false,
|
||||
"quotemark": [true, "single"],
|
||||
"one-variable-per-declaration": false,
|
||||
"curly": [true, "ignore-same-line"],
|
||||
"trailing-comma": [true, {"multiline": "never", "singleline": "never"}]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
module.exports = {
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"rules": {
|
||||
"semi": [2, "always"],
|
||||
"indent": [2, 4],
|
||||
"no-return-await": 0,
|
||||
"space-before-function-paren": [2, {
|
||||
"named": "never",
|
||||
"anonymous": "never",
|
||||
"asyncArrow": "always"
|
||||
}],
|
||||
"template-curly-spacing": [2, "always"]
|
||||
}
|
||||
};
|
|
@ -7,7 +7,7 @@
|
|||
"main": "./lib/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc --build",
|
||||
"lint": "tslint -c tslint.json 'src/**/*.ts'",
|
||||
"lint": "eslint -c .eslintrc.js --ext .ts src",
|
||||
"postinstall": "npm run build && node ./deploymentScripts/webConfigPrep.js",
|
||||
"start": "tsc --build && node ./lib/index.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
|
@ -24,8 +24,15 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/restify": "8.4.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
||||
"@typescript-eslint/parser": "^7.8.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"nodemon": "~1.19.4",
|
||||
"tslint": "~5.20.0",
|
||||
"typescript": "~4.3.2"
|
||||
"typescript": "~4.9.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ export class WelcomeBot extends ActivityHandler {
|
|||
// The channel should send the user name in the 'From' object
|
||||
const userName = context.activity.from.name;
|
||||
await context.sendActivity('You are seeing this message because this was your first message ever sent to this bot.');
|
||||
await context.sendActivity(`It is a good practice to welcome the user and provide personal greeting. For example, welcome ${userName}.`);
|
||||
await context.sendActivity(`It is a good practice to welcome the user and provide personal greeting. For example, welcome ${ userName }.`);
|
||||
|
||||
// Set the flag indicating the bot handled the user's first message.
|
||||
await this.welcomedUserProperty.set(context, true);
|
||||
|
@ -43,18 +43,18 @@ export class WelcomeBot extends ActivityHandler {
|
|||
// Consider using LUIS or QnA for Natural Language Processing.
|
||||
const text = context.activity.text.toLowerCase();
|
||||
switch (text) {
|
||||
case 'hello':
|
||||
case 'hi':
|
||||
await context.sendActivity(`You said "${context.activity.text}"`);
|
||||
break;
|
||||
case 'intro':
|
||||
case 'help':
|
||||
await this.sendIntroCard(context);
|
||||
break;
|
||||
default:
|
||||
await context.sendActivity(`This is a simple Welcome Bot sample. You can say 'intro' to
|
||||
see the introduction card. If you are running this bot in the Bot
|
||||
Framework Emulator, press the 'Start Over' button to simulate user joining a bot or a channel`);
|
||||
case 'hello':
|
||||
case 'hi':
|
||||
await context.sendActivity(`You said "${ context.activity.text }"`);
|
||||
break;
|
||||
case 'intro':
|
||||
case 'help':
|
||||
await this.sendIntroCard(context);
|
||||
break;
|
||||
default:
|
||||
await context.sendActivity(`This is a simple Welcome Bot sample. You can say 'intro' to
|
||||
see the introduction card. If you are running this bot in the Bot
|
||||
Framework Emulator, press the 'Start Over' button to simulate user joining a bot or a channel`);
|
||||
}
|
||||
}
|
||||
// Save state changes
|
||||
|
@ -75,7 +75,7 @@ export class WelcomeBot extends ActivityHandler {
|
|||
// bot was added to the conversation, and the opposite indicates this is a user.
|
||||
if (context.activity.membersAdded[idx].id !== context.activity.recipient.id) {
|
||||
await context.sendActivity('Welcome to the \'Welcome User\' Bot. This bot will introduce you to welcoming and greeting users.');
|
||||
await context.sendActivity(`You are seeing this message because the bot received at least one 'ConversationUpdate' ` +
|
||||
await context.sendActivity('You are seeing this message because the bot received at least one \'ConversationUpdate\' ' +
|
||||
'event, indicating you (and possibly others) joined the conversation. If you are using the emulator, ' +
|
||||
'pressing the \'Start Over\' button to trigger this event again. The specifics of the \'ConversationUpdate\' ' +
|
||||
'event depends on the channel. You can read more information at https://aka.ms/about-botframework-welcome-user');
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"interface-name" : [true, "never-prefix"],
|
||||
"max-line-length": [false],
|
||||
"no-console": [false, "log", "error"],
|
||||
"no-var-requires": false,
|
||||
"quotemark": [true, "single"],
|
||||
"one-variable-per-declaration": false,
|
||||
"curly": [true, "ignore-same-line"],
|
||||
"trailing-comma": [true, {"multiline": "never", "singleline": "never"}]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
module.exports = {
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"rules": {
|
||||
"semi": [2, "always"],
|
||||
"indent": [2, 4],
|
||||
"no-return-await": 0,
|
||||
"space-before-function-paren": [2, {
|
||||
"named": "never",
|
||||
"anonymous": "never",
|
||||
"asyncArrow": "always"
|
||||
}],
|
||||
"template-curly-spacing": [2, "always"]
|
||||
}
|
||||
};
|
|
@ -7,7 +7,7 @@
|
|||
"main": "./lib/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc --build",
|
||||
"lint": "tslint -c tslint.json 'src/**/*.ts'",
|
||||
"lint": "eslint -c .eslintrc.js --ext .ts src",
|
||||
"postinstall": "npm run build && node ./deploymentScripts/webConfigPrep.js",
|
||||
"start": "tsc --build && node ./lib/index.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
|
@ -26,8 +26,15 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/restify": "8.4.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
||||
"@typescript-eslint/parser": "^7.8.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"nodemon": "~1.19.4",
|
||||
"tslint": "~5.20.0",
|
||||
"typescript": "~4.3.2"
|
||||
"typescript": "~4.9.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { ActivityHandler, BotState, ConversationState, StatePropertyAccessor, UserState } from 'botbuilder';
|
||||
import { ActivityHandler, BotState, ConversationState, StatePropertyAccessor, UserState } from 'botbuilder';
|
||||
import { Dialog, DialogState } from 'botbuilder-dialogs';
|
||||
import { UserProfileDialog } from '../dialogs/userProfileDialog';
|
||||
export class DialogBot extends ActivityHandler {
|
||||
|
|
|
@ -83,7 +83,7 @@ export class UserProfileDialog extends ComponentDialog {
|
|||
stepContext.options.name = stepContext.result;
|
||||
|
||||
// We can send messages to the user at any point in the WaterfallStep.
|
||||
await stepContext.context.sendActivity(`Thanks ${stepContext.result}.`);
|
||||
await stepContext.context.sendActivity(`Thanks ${ stepContext.result }.`);
|
||||
|
||||
// WaterfallStep always finishes with the end of the Waterfall or with another dialog; here it is a Prompt Dialog.
|
||||
return await stepContext.prompt(CONFIRM_PROMPT, 'Do you want to give your age?', ['yes', 'no']);
|
||||
|
@ -105,7 +105,7 @@ export class UserProfileDialog extends ComponentDialog {
|
|||
private async confirmStep(stepContext: WaterfallStepContext<UserProfile>) {
|
||||
stepContext.options.age = stepContext.result;
|
||||
|
||||
const msg = stepContext.options.age === -1 ? 'No age given.' : `I have your age as ${stepContext.options.age}.`;
|
||||
const msg = stepContext.options.age === -1 ? 'No age given.' : `I have your age as ${ stepContext.options.age }.`;
|
||||
|
||||
// We can send messages to the user at any point in the WaterfallStep.
|
||||
await stepContext.context.sendActivity(msg);
|
||||
|
@ -123,9 +123,9 @@ export class UserProfileDialog extends ComponentDialog {
|
|||
userProfile.name = stepContextOptions.name;
|
||||
userProfile.age = stepContextOptions.age;
|
||||
|
||||
let msg = `I have your mode of transport as ${userProfile.transport} and your name as ${userProfile.name}.`;
|
||||
let msg = `I have your mode of transport as ${ userProfile.transport } and your name as ${ userProfile.name }.`;
|
||||
if (userProfile.age !== -1) {
|
||||
msg += ` And age as ${userProfile.age}.`;
|
||||
msg += ` And age as ${ userProfile.age }.`;
|
||||
}
|
||||
|
||||
await stepContext.context.sendActivity(msg);
|
||||
|
|
|
@ -35,12 +35,12 @@ adapter.onTurnError = async (context, error) => {
|
|||
// This check writes out errors to console log .vs. app insights.
|
||||
// NOTE: In production environment, you should consider logging this to Azure
|
||||
// application insights.
|
||||
console.error(`\n [onTurnError] unhandled error: ${error}`);
|
||||
console.error(`\n [onTurnError] unhandled error: ${ error }`);
|
||||
|
||||
// Send a trace activity, which will be displayed in Bot Framework Emulator
|
||||
await context.sendTraceActivity(
|
||||
'OnTurnError Trace',
|
||||
`${error}`,
|
||||
`${ error }`,
|
||||
'https://www.botframework.com/schemas/error',
|
||||
'TurnError'
|
||||
);
|
||||
|
@ -70,7 +70,7 @@ const server = restify.createServer();
|
|||
server.use(restify.plugins.bodyParser());
|
||||
|
||||
server.listen(process.env.port || process.env.PORT || 3978, () => {
|
||||
console.log(`\n${server.name} listening to ${server.url}.`);
|
||||
console.log(`\n${ server.name } listening to ${ server.url }.`);
|
||||
console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator');
|
||||
console.log('\nTo talk to your bot, open the emulator select "Open Bot"');
|
||||
});
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"interface-name" : [true, "never-prefix"],
|
||||
"max-line-length": [false],
|
||||
"no-console": [false, "log", "error"],
|
||||
"no-var-requires": false,
|
||||
"quotemark": [true, "single"],
|
||||
"one-variable-per-declaration": false,
|
||||
"curly": [true, "ignore-same-line"],
|
||||
"trailing-comma": [true, {"multiline": "never", "singleline": "never"}]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
module.exports = {
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"rules": {
|
||||
"semi": [2, "always"],
|
||||
"indent": [2, 4],
|
||||
"no-return-await": 0,
|
||||
"space-before-function-paren": [2, {
|
||||
"named": "never",
|
||||
"anonymous": "never",
|
||||
"asyncArrow": "always"
|
||||
}],
|
||||
"template-curly-spacing": [2, "always"]
|
||||
}
|
||||
};
|
|
@ -7,7 +7,7 @@
|
|||
"main": "./lib/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc --build",
|
||||
"lint": "tslint -c tslint.json 'src/**/*.ts'",
|
||||
"lint": "eslint -c .eslintrc.js --ext .ts src",
|
||||
"postinstall": "npm run build && node ./deploymentScripts/webConfigPrep.js",
|
||||
"start": "tsc --build && node ./lib/index.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
|
@ -26,8 +26,15 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/restify": "8.4.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
||||
"@typescript-eslint/parser": "^7.8.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"nodemon": "~1.19.4",
|
||||
"tslint": "~5.20.0",
|
||||
"typescript": "~4.3.2"
|
||||
"typescript": "~4.9.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { ActivityHandler, BotState, ConversationState, StatePropertyAccessor, UserState } from 'botbuilder';
|
||||
import { ActivityHandler, BotState, ConversationState, StatePropertyAccessor, UserState } from 'botbuilder';
|
||||
import { Dialog, DialogState } from 'botbuilder-dialogs';
|
||||
import { MainDialog } from '../dialogs/mainDialog';
|
||||
export class DialogBot extends ActivityHandler {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
import AdaptiveCard from '../resources/adaptiveCard.json';
|
||||
|
||||
import { AttachmentLayoutTypes, CardFactory, StatePropertyAccessor, TurnContext, UserState } from 'botbuilder';
|
||||
import { AttachmentLayoutTypes, CardFactory, StatePropertyAccessor, TurnContext } from 'botbuilder';
|
||||
import {
|
||||
ChoicePrompt,
|
||||
ComponentDialog,
|
||||
|
@ -15,7 +15,6 @@ import {
|
|||
const MAIN_WATERFALL_DIALOG = 'mainWaterfallDialog';
|
||||
|
||||
export class MainDialog extends ComponentDialog {
|
||||
|
||||
constructor() {
|
||||
super('MainDialog');
|
||||
|
||||
|
@ -77,49 +76,49 @@ export class MainDialog extends ComponentDialog {
|
|||
console.log('MainDialog.showCardStep');
|
||||
|
||||
switch (stepContext.result.value) {
|
||||
case 'Adaptive Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createAdaptiveCard()] });
|
||||
break;
|
||||
case 'Animation Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createAnimationCard()] });
|
||||
break;
|
||||
case 'Audio Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createAudioCard()] });
|
||||
break;
|
||||
case 'OAuth Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createOAuthCard()] });
|
||||
break;
|
||||
case 'Hero Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createHeroCard()] });
|
||||
break;
|
||||
case 'Receipt Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createReceiptCard()] });
|
||||
break;
|
||||
case 'Signin Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createSignInCard()] });
|
||||
break;
|
||||
case 'Thumbnail Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createThumbnailCard()] });
|
||||
break;
|
||||
case 'Video Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createVideoCard()] });
|
||||
break;
|
||||
default:
|
||||
await stepContext.context.sendActivity({
|
||||
attachmentLayout: AttachmentLayoutTypes.Carousel,
|
||||
attachments: [
|
||||
this.createAdaptiveCard(),
|
||||
this.createAnimationCard(),
|
||||
this.createAudioCard(),
|
||||
this.createOAuthCard(),
|
||||
this.createHeroCard(),
|
||||
this.createReceiptCard(),
|
||||
this.createSignInCard(),
|
||||
this.createThumbnailCard(),
|
||||
this.createVideoCard()
|
||||
]
|
||||
});
|
||||
break;
|
||||
case 'Adaptive Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createAdaptiveCard()] });
|
||||
break;
|
||||
case 'Animation Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createAnimationCard()] });
|
||||
break;
|
||||
case 'Audio Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createAudioCard()] });
|
||||
break;
|
||||
case 'OAuth Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createOAuthCard()] });
|
||||
break;
|
||||
case 'Hero Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createHeroCard()] });
|
||||
break;
|
||||
case 'Receipt Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createReceiptCard()] });
|
||||
break;
|
||||
case 'Signin Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createSignInCard()] });
|
||||
break;
|
||||
case 'Thumbnail Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createThumbnailCard()] });
|
||||
break;
|
||||
case 'Video Card':
|
||||
await stepContext.context.sendActivity({ attachments: [this.createVideoCard()] });
|
||||
break;
|
||||
default:
|
||||
await stepContext.context.sendActivity({
|
||||
attachmentLayout: AttachmentLayoutTypes.Carousel,
|
||||
attachments: [
|
||||
this.createAdaptiveCard(),
|
||||
this.createAnimationCard(),
|
||||
this.createAudioCard(),
|
||||
this.createOAuthCard(),
|
||||
this.createHeroCard(),
|
||||
this.createReceiptCard(),
|
||||
this.createSignInCard(),
|
||||
this.createThumbnailCard(),
|
||||
this.createVideoCard()
|
||||
]
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
// Give the user instructions about what to do next
|
||||
|
|
|
@ -35,12 +35,12 @@ adapter.onTurnError = async (context, error) => {
|
|||
// This check writes out errors to console log .vs. app insights.
|
||||
// NOTE: In production environment, you should consider logging this to Azure
|
||||
// application insights.
|
||||
console.error(`\n [onTurnError] unhandled error: ${error}`);
|
||||
console.error(`\n [onTurnError] unhandled error: ${ error }`);
|
||||
|
||||
// Send a trace activity, which will be displayed in Bot Framework Emulator
|
||||
await context.sendTraceActivity(
|
||||
'OnTurnError Trace',
|
||||
`${error}`,
|
||||
`${ error }`,
|
||||
'https://www.botframework.com/schemas/error',
|
||||
'TurnError'
|
||||
);
|
||||
|
@ -70,7 +70,7 @@ const server = restify.createServer();
|
|||
server.use(restify.plugins.bodyParser());
|
||||
|
||||
server.listen(process.env.port || process.env.PORT || 3978, () => {
|
||||
console.log(`\n${server.name} listening to ${server.url}.`);
|
||||
console.log(`\n${ server.name } listening to ${ server.url }.`);
|
||||
console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator');
|
||||
console.log('\nTo talk to your bot, open the emulator select "Open Bot"');
|
||||
});
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"interface-name" : [true, "never-prefix"],
|
||||
"max-line-length": [false],
|
||||
"no-console": [false, "log", "error"],
|
||||
"no-var-requires": false,
|
||||
"quotemark": [true, "single"],
|
||||
"one-variable-per-declaration": false,
|
||||
"curly": [true, "ignore-same-line"],
|
||||
"trailing-comma": [true, {"multiline": "never", "singleline": "never"}]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-disable */
|
||||
module.exports = {
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"rules": {
|
||||
"semi": [2, "always"],
|
||||
"indent": [2, 4],
|
||||
|
@ -10,7 +11,10 @@ module.exports = {
|
|||
"anonymous": "never",
|
||||
"asyncArrow": "always"
|
||||
}],
|
||||
"template-curly-spacing": [2, "always"]
|
||||
"template-curly-spacing": [2, "always"],
|
||||
"no-useless-constructor": 0,
|
||||
"prefer-const": 0,
|
||||
"array-callback-return": 0
|
||||
},
|
||||
"env": {
|
||||
"commonjs": true,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "tsc --build",
|
||||
"lint": "tslint -c tslint.json 'src/**/*.ts'",
|
||||
"lint": "eslint -c .eslintrc.js --ext .ts src",
|
||||
"postinstall": "npm run build && node ./deploymentScripts/webConfigPrep.js",
|
||||
"start": "tsc --build && node ./lib/index.js",
|
||||
"test": "tsc --build && nyc mocha lib/tests/**/*.test.js",
|
||||
|
@ -51,11 +51,18 @@
|
|||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^16.11.6",
|
||||
"@types/restify": "8.4.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
||||
"@typescript-eslint/parser": "^7.8.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"mocha": "^7.1.2",
|
||||
"nodemon": "~2.0.4",
|
||||
"nyc": "^15.0.1",
|
||||
"ts-node": "^8.10.1",
|
||||
"tslint": "~6.1.2",
|
||||
"typescript": "~4.3.2"
|
||||
"typescript": "~4.9.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,16 +26,18 @@ export class CancelAndHelpDialog extends ComponentDialog {
|
|||
const text = innerDc.context.activity.text.toLowerCase();
|
||||
|
||||
switch (text) {
|
||||
case 'help':
|
||||
case '?':
|
||||
const helpMessageText = 'Show help here';
|
||||
await innerDc.context.sendActivity(helpMessageText, helpMessageText, InputHints.ExpectingInput);
|
||||
return { status: DialogTurnStatus.waiting };
|
||||
case 'cancel':
|
||||
case 'quit':
|
||||
const cancelMessageText = 'Cancelling...';
|
||||
await innerDc.context.sendActivity(cancelMessageText, cancelMessageText, InputHints.IgnoringInput);
|
||||
return await innerDc.cancelAllDialogs();
|
||||
case 'help':
|
||||
case '?':{
|
||||
const helpMessageText = 'Show help here';
|
||||
await innerDc.context.sendActivity(helpMessageText, helpMessageText, InputHints.ExpectingInput);
|
||||
return { status: DialogTurnStatus.waiting };
|
||||
}
|
||||
case 'cancel':
|
||||
case 'quit':{
|
||||
const cancelMessageText = 'Cancelling...';
|
||||
await innerDc.context.sendActivity(cancelMessageText, cancelMessageText, InputHints.IgnoringInput);
|
||||
return await innerDc.cancelAllDialogs();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ const DATETIME_PROMPT = 'datetimePrompt';
|
|||
const WATERFALL_DIALOG = 'waterfallDialog';
|
||||
|
||||
export class DateResolverDialog extends CancelAndHelpDialog {
|
||||
|
||||
private static async dateTimePromptValidator(promptContext: PromptValidatorContext<DateTimeResolution>): Promise<boolean> {
|
||||
if (promptContext.recognized.succeeded) {
|
||||
// This value will be a TIMEX. And we are only interested in a Date so grab the first result and drop the Time part.
|
||||
|
|
|
@ -13,7 +13,7 @@ export class FlightBookingRecognizer {
|
|||
// Set the recognizer options depending on which endpoint version you want to use e.g LuisRecognizerOptionsV2 or LuisRecognizerOptionsV3.
|
||||
// More details can be found in https://docs.microsoft.com/en-gb/azure/cognitive-services/luis/luis-migration-api-v3
|
||||
const recognizerOptions: LuisRecognizerOptionsV3 = {
|
||||
apiVersion : 'v3'
|
||||
apiVersion: 'v3'
|
||||
};
|
||||
|
||||
this.recognizer = new LuisRecognizer(config, recognizerOptions);
|
||||
|
|
|
@ -74,7 +74,7 @@ export class MainDialog extends ComponentDialog {
|
|||
return await stepContext.next();
|
||||
}
|
||||
const weekLaterDate = moment().add(7, 'days').format('MMMM D, YYYY');
|
||||
const messageText = (stepContext.options as any).restartMsg ? (stepContext.options as any).restartMsg : `What can I help you with today?\nSay something like "Book a flight from Paris to Berlin on ${weekLaterDate}"`;
|
||||
const messageText = (stepContext.options as any).restartMsg ? (stepContext.options as any).restartMsg : `What can I help you with today?\nSay something like "Book a flight from Paris to Berlin on ${ weekLaterDate }"`;
|
||||
const promptMessage = MessageFactory.text(messageText, messageText, InputHints.ExpectingInput);
|
||||
return await stepContext.prompt('TextPrompt', { prompt: promptMessage });
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ export class MainDialog extends ComponentDialog {
|
|||
// Call LUIS and gather any potential booking details. (Note the TurnContext has the response to the prompt)
|
||||
const luisResult = await this.luisRecognizer.executeLuisQuery(stepContext.context);
|
||||
switch (LuisRecognizer.topIntent(luisResult)) {
|
||||
case 'BookFlight':
|
||||
case 'BookFlight':{
|
||||
// Extract the values for the composite entities from the LUIS result.
|
||||
const fromEntities = this.luisRecognizer.getFromEntities(luisResult);
|
||||
const toEntities = this.luisRecognizer.getToEntities(luisResult);
|
||||
|
@ -110,18 +110,19 @@ export class MainDialog extends ComponentDialog {
|
|||
|
||||
// Run the BookingDialog passing in whatever details we have from the LUIS call, it will fill out the remainder.
|
||||
return await stepContext.beginDialog('bookingDialog', bookingDetails);
|
||||
|
||||
case 'GetWeather':
|
||||
}
|
||||
case 'GetWeather':{
|
||||
// We haven't implemented the GetWeatherDialog so we just display a TODO message.
|
||||
const getWeatherMessageText = 'TODO: get weather flow here';
|
||||
await stepContext.context.sendActivity(getWeatherMessageText, getWeatherMessageText, InputHints.IgnoringInput);
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
default:{
|
||||
// Catch all for unhandled intents
|
||||
const didntUnderstandMessageText = `Sorry, I didn't get that. Please try asking in a different way (intent was ${ LuisRecognizer.topIntent(luisResult) })`;
|
||||
await stepContext.context.sendActivity(didntUnderstandMessageText, didntUnderstandMessageText, InputHints.IgnoringInput);
|
||||
}
|
||||
}
|
||||
|
||||
return await stepContext.next();
|
||||
}
|
||||
|
|
|
@ -3,11 +3,6 @@
|
|||
|
||||
import * as path from 'path';
|
||||
|
||||
import { config } from 'dotenv';
|
||||
// Note: Ensure you have a .env file and include LuisAppId, LuisAPIKey and LuisAPIHostName.
|
||||
const ENV_FILE = path.join(__dirname, '..', '.env');
|
||||
config({ path: ENV_FILE });
|
||||
|
||||
import * as restify from 'restify';
|
||||
|
||||
import { INodeSocket } from 'botframework-streaming';
|
||||
|
@ -31,11 +26,16 @@ import { MainDialog } from './dialogs/mainDialog';
|
|||
|
||||
// The bot's booking dialog
|
||||
import { BookingDialog } from './dialogs/bookingDialog';
|
||||
const BOOKING_DIALOG = 'bookingDialog';
|
||||
|
||||
// The helper-class recognizer that calls LUIS
|
||||
import { FlightBookingRecognizer } from './dialogs/flightBookingRecognizer';
|
||||
|
||||
import { config } from 'dotenv';
|
||||
// Note: Ensure you have a .env file and include LuisAppId, LuisAPIKey and LuisAPIHostName.
|
||||
const ENV_FILE = path.join(__dirname, '..', '.env');
|
||||
config({ path: ENV_FILE });
|
||||
const BOOKING_DIALOG = 'bookingDialog';
|
||||
|
||||
const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication(process.env as ConfigurationBotFrameworkAuthenticationOptions);
|
||||
|
||||
// Create adapter.
|
||||
|
@ -80,11 +80,10 @@ conversationState = new ConversationState(memoryStorage);
|
|||
userState = new UserState(memoryStorage);
|
||||
|
||||
// If configured, pass in the FlightBookingRecognizer. (Defining it externally allows it to be mocked for tests)
|
||||
let luisRecognizer;
|
||||
const { LuisAppId, LuisAPIKey, LuisAPIHostName } = process.env;
|
||||
const luisConfig: LuisApplication = { applicationId: LuisAppId, endpointKey: LuisAPIKey, endpoint: `https://${ LuisAPIHostName }` };
|
||||
|
||||
luisRecognizer = new FlightBookingRecognizer(luisConfig);
|
||||
const luisRecognizer = new FlightBookingRecognizer(luisConfig);
|
||||
|
||||
// Create the main dialog.
|
||||
const bookingDialog = new BookingDialog(BOOKING_DIALOG);
|
||||
|
|
|
@ -86,15 +86,15 @@ describe('MainDialog', () => {
|
|||
|
||||
const reply = await client.sendActivity('hi');
|
||||
const weekLaterDate = moment().add(7, 'days').format('MMMM D, YYYY');
|
||||
assert.strictEqual(reply.text, `What can I help you with today?\nSay something like "Book a flight from Paris to Berlin on ${weekLaterDate}"`, 'Did not show prompt');
|
||||
assert.strictEqual(reply.text, `What can I help you with today?\nSay something like "Book a flight from Paris to Berlin on ${ weekLaterDate }"`, 'Did not show prompt');
|
||||
});
|
||||
|
||||
describe('Invokes tasks based on LUIS intent', () => {
|
||||
// Create array with test case data.
|
||||
const testCases = [
|
||||
{ utterance: 'I want to book a flight', intent: 'BookFlight', invokedDialogResponse: 'bookingDialog mock invoked', taskConfirmationMessage: 'I have you booked to Seattle from New York' },
|
||||
{ utterance: `What's the weather like?`, intent: 'GetWeather', invokedDialogResponse: 'TODO: get weather flow here', taskConfirmationMessage: undefined },
|
||||
{ utterance: 'bananas', intent: 'None', invokedDialogResponse: `Sorry, I didn't get that. Please try asking in a different way (intent was None)`, taskConfirmationMessage: undefined }
|
||||
{ utterance: 'What\'s the weather like?', intent: 'GetWeather', invokedDialogResponse: 'TODO: get weather flow here', taskConfirmationMessage: undefined },
|
||||
{ utterance: 'bananas', intent: 'None', invokedDialogResponse: 'Sorry, I didn\'t get that. Please try asking in a different way (intent was None)', taskConfirmationMessage: undefined }
|
||||
];
|
||||
|
||||
testCases.map((testData) => {
|
||||
|
@ -110,7 +110,7 @@ describe('MainDialog', () => {
|
|||
console.log(`Test Case: ${ testData.intent }`);
|
||||
let reply = await client.sendActivity('Hi');
|
||||
const weekLaterDate = moment().add(7, 'days').format('MMMM D, YYYY');
|
||||
assert.strictEqual(reply.text, `What can I help you with today?\nSay something like "Book a flight from Paris to Berlin on ${weekLaterDate}"`);
|
||||
assert.strictEqual(reply.text, `What can I help you with today?\nSay something like "Book a flight from Paris to Berlin on ${ weekLaterDate }"`);
|
||||
|
||||
reply = await client.sendActivity(testData.utterance);
|
||||
assert.strictEqual(reply.text, testData.invokedDialogResponse);
|
||||
|
@ -150,7 +150,7 @@ describe('MainDialog', () => {
|
|||
console.log(`Test Case: ${ mockLuisResult.text }`);
|
||||
let reply = await client.sendActivity('Hi');
|
||||
const weekLaterDate = moment().add(7, 'days').format('MMMM D, YYYY');
|
||||
assert.strictEqual(reply.text, `What can I help you with today?\nSay something like "Book a flight from Paris to Berlin on ${weekLaterDate}"`);
|
||||
assert.strictEqual(reply.text, `What can I help you with today?\nSay something like "Book a flight from Paris to Berlin on ${ weekLaterDate }"`);
|
||||
|
||||
reply = await client.sendActivity(mockLuisResult.text);
|
||||
assert.strictEqual(reply.text, testData.expectedMessage);
|
||||
|
|
|
@ -89,17 +89,17 @@ module.exports = [
|
|||
expectedResult: {
|
||||
destination: 'Seattle',
|
||||
origin: 'Bahamas',
|
||||
travelDate: bookingDialogToday
|
||||
travelDate: bookingDialogToday
|
||||
},
|
||||
expectedStatus: 'complete',
|
||||
initialData: {
|
||||
destination: 'Seattle',
|
||||
origin: 'Bahamas',
|
||||
travelDate: bookingDialogToday
|
||||
travelDate: bookingDialogToday
|
||||
},
|
||||
name: 'All booking details given for today',
|
||||
steps: [
|
||||
['hi', `Please confirm, I have you traveling to: Seattle from: Bahamas on: ${ bookingDialogToday }. Is this correct? (1) Yes or (2) No`],
|
||||
['hi', `Please confirm, I have you traveling to: Seattle from: Bahamas on: ${ bookingDialogToday }. Is this correct? (1) Yes or (2) No`],
|
||||
['yes', null]
|
||||
]
|
||||
},
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"interface-name" : [true, "never-prefix"],
|
||||
"max-line-length": [false],
|
||||
"no-console": [false, "log", "error"],
|
||||
"no-var-requires": false,
|
||||
"quotemark": [true, "single"],
|
||||
"one-variable-per-declaration": false,
|
||||
"curly": [true, "ignore-same-line"],
|
||||
"trailing-comma": [true, {"multiline": "never", "singleline": "never"}]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
module.exports = {
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"rules": {
|
||||
"semi": [2, "always"],
|
||||
"indent": [2, 4],
|
||||
"no-return-await": 0,
|
||||
"space-before-function-paren": [2, {
|
||||
"named": "never",
|
||||
"anonymous": "never",
|
||||
"asyncArrow": "always"
|
||||
}],
|
||||
"template-curly-spacing": [2, "always"]
|
||||
}
|
||||
};
|
|
@ -7,7 +7,7 @@
|
|||
"main": "./lib/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc --build",
|
||||
"lint": "tslint -c tslint.json 'src/**/*.ts'",
|
||||
"lint": "eslint -c .eslintrc.js --ext .ts src",
|
||||
"postinstall": "npm run build && node ./deploymentScripts/webConfigPrep.js",
|
||||
"start": "tsc --build && node ./lib/index.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
|
@ -26,8 +26,15 @@
|
|||
"devDependencies": {
|
||||
"@types/dotenv": "6.1.1",
|
||||
"@types/restify": "8.4.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
||||
"@typescript-eslint/parser": "^7.8.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"nodemon": "~1.19.4",
|
||||
"tslint": "~5.20.0",
|
||||
"typescript": "~4.3.2"
|
||||
"typescript": "~4.9.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,11 +25,11 @@ export class EchoBot extends ActivityHandler {
|
|||
|
||||
this.onMembersAdded(async (context, next) => {
|
||||
const membersAdded = context.activity.membersAdded;
|
||||
const welcomeText = 'Hello and welcome!';
|
||||
for (const member of membersAdded) {
|
||||
if (member.id !== context.activity.recipient.id) {
|
||||
const welcomeMessage = 'Welcome to the Proactive Bot sample. Navigate to http://localhost:3978/api/notify to proactively message everyone who has previously messaged this bot.';
|
||||
await context.sendActivity(welcomeMessage); }
|
||||
await context.sendActivity(welcomeMessage);
|
||||
}
|
||||
}
|
||||
// By calling next() you ensure that the next BotHandler is run.
|
||||
await next();
|
||||
|
|
|
@ -24,7 +24,7 @@ config({ path: ENV_FILE });
|
|||
// Create HTTP server.
|
||||
const server = restify.createServer();
|
||||
server.listen(process.env.port || process.env.PORT || 3978, () => {
|
||||
console.log(`\n${server.name} listening to ${server.url}`);
|
||||
console.log(`\n${ server.name } listening to ${ server.url }`);
|
||||
console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator');
|
||||
console.log('\nTo talk to your bot, open the emulator select "Open Bot"');
|
||||
});
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"interface-name" : [true, "never-prefix"],
|
||||
"max-line-length": [false],
|
||||
"no-console": [false, "log", "error"],
|
||||
"no-var-requires": false,
|
||||
"quotemark": [true, "single"],
|
||||
"one-variable-per-declaration": false,
|
||||
"curly": [true, "ignore-same-line"],
|
||||
"trailing-comma": [true, {"multiline": "never", "singleline": "never"}]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
Загрузка…
Ссылка в новой задаче