Skip to content

Commit

Permalink
Remove .bot file, use appsettings.json file
Browse files Browse the repository at this point in the history
Remove .bot file, use appsettings.json file
  • Loading branch information
hinojosachapel authored Feb 3, 2020
2 parents dc0cd9b + 9b6e4e8 commit 739258e
Show file tree
Hide file tree
Showing 32 changed files with 777 additions and 281 deletions.
336 changes: 311 additions & 25 deletions javascript_nodejs/package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion javascript_nodejs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"dependencies": {
"botbuilder": "^4.7.1",
"botbuilder-ai": "^4.7.1",
"botbuilder-azure": "^4.7.1",
"botbuilder-core": "^4.7.1",
"botbuilder-dialogs": "^4.7.1",
"botframework-config": "^4.7.1",
Expand All @@ -30,7 +31,7 @@
"devDependencies": {
"eslint": "^5.16.0",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.20.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-node": "^8.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
Expand Down
8 changes: 1 addition & 7 deletions javascript_nodejs/src/bot.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2019 Rubén Hinojosa Chapel. All rights reserved.
// Copyright (c) Rubén Hinojosa Chapel. All rights reserved.
// Licensed under the MIT License.

// bot.js is your main bot dialog entry point for handling activity types
Expand All @@ -25,12 +25,6 @@ const DIALOG_STATE_PROPERTY = 'dialogState';
*/
class CorePlusBot extends ActivityHandler {
/**
* Constructs the five pieces necessary for this bot to operate:
* 1. StatePropertyAccessor for conversation state
* 2. StatePropertyAccess for user state
* 3. LUIS clients, one per locale
* 4. QnA Maker clients, one per locale
* 5. DialogSet to handle our MainDialog, that orchestrates the whole bunch of dialogues
*
* @param {ConversationState} conversationState property accessor
* @param {UserState} userState property accessor
Expand Down
26 changes: 26 additions & 0 deletions javascript_nodejs/src/config/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"microsoftAppId": "<YOUR_APP_ID>",
"microsoftAppPassword": "<YOUR_APP_PASSWORD>",
"appInsights": {
"instrumentationKey": ""
},
"LUIS-en-US": {
"appId": "<YOUR_APP_ID>",
"authoringKey": "<YOUR_AUTHORING_KEY>",
"subscriptionKey": "<YOUR_AUTHORING_KEY>",
"endpoint": "https://your-region.api.cognitive.microsoft.com"
},
"QNA-en-US": {
"kbId": "<YOUR_KNOWLEDGE_BASE_ID>",
"subscriptionKey": "<YOUR_SUBSCRIPTION_KEY>",
"endpointKey": "<YOUR_ENDPOINT_KEY>",
"hostname": "https://your-qnamaker-app-name.azurewebsites.net/qnamaker"
},
"cosmosDb": {
"serviceEndpoint": "https://your-cosmosdb-account-name.documents.azure.com:443/",
"authKey": "<YOUR_AUTHORING_KEY>",
"databaseId": "<YOUR_DATABASE_ID>",
"collectionId": "<YOUR_COLLECTION_ID>"
},
"publicResourcesUrl": "http://localhost:3978"
}
35 changes: 0 additions & 35 deletions javascript_nodejs/src/config/development.bot

This file was deleted.

2 changes: 1 addition & 1 deletion javascript_nodejs/src/dialogs/cancel/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 Rubén Hinojosa Chapel. All rights reserved.
// Copyright (c) Rubén Hinojosa Chapel. All rights reserved.
// Licensed under the MIT License.

const { ComponentDialog, ChoicePrompt, WaterfallDialog } = require('botbuilder-dialogs');
Expand Down
2 changes: 1 addition & 1 deletion javascript_nodejs/src/dialogs/chitchat/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 Rubén Hinojosa Chapel. All rights reserved.
// Copyright (c) Rubén Hinojosa Chapel. All rights reserved.
// Licensed under the MIT License.

// Chitchat dialog to handle conversation interruptions.
Expand Down
4 changes: 2 additions & 2 deletions javascript_nodejs/src/dialogs/greeting/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2019 Rubén Hinojosa Chapel. All rights reserved.
// Copyright (c) Rubén Hinojosa Chapel. All rights reserved.
// Licensed under the MIT License.

// defines the greeting dialog
Expand Down Expand Up @@ -207,7 +207,7 @@ class GreetingDialog extends ComponentDialog {

// Display to the user their profile information and end dialog
// Here we use {{Mustache}} patterns: https://github.com/mashpie/i18n-node/blob/master/i18n.js#L543
let greet = localizer.gettext(locale, 'greeting.greetUser1', { "userName": userData.name || '', "userCity": userData.city || '' });
const greet = localizer.gettext(locale, 'greeting.greetUser1', { "userName": userData.name || '', "userCity": userData.city || '' });
await step.context.sendActivity(greet);
await step.context.sendActivity(localizer.gettext(locale, 'greeting.greetUser2'));

Expand Down
2 changes: 1 addition & 1 deletion javascript_nodejs/src/dialogs/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 Rubén Hinojosa Chapel. All rights reserved.
// Copyright (c) Rubén Hinojosa Chapel. All rights reserved.
// Licensed under the MIT License.

module.exports = {
Expand Down
2 changes: 1 addition & 1 deletion javascript_nodejs/src/dialogs/main/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 Rubén Hinojosa Chapel. All rights reserved.
// Copyright (c) Rubén Hinojosa Chapel. All rights reserved.
// Licensed under the MIT License.

const { ComponentDialog, DialogSet, DialogTurnStatus } = require('botbuilder-dialogs');
Expand Down
2 changes: 1 addition & 1 deletion javascript_nodejs/src/dialogs/qna/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 Rubén Hinojosa Chapel. All rights reserved.
// Copyright (c) Rubén Hinojosa Chapel. All rights reserved.
// Licensed under the MIT License.

const { ComponentDialog, ChoicePrompt, WaterfallDialog } = require('botbuilder-dialogs');
Expand Down
2 changes: 1 addition & 1 deletion javascript_nodejs/src/dialogs/shared/userData.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 Rubén Hinojosa Chapel. All rights reserved.
// Copyright (c) Rubén Hinojosa Chapel. All rights reserved.
// Licensed under the MIT License.

/**
Expand Down
2 changes: 1 addition & 1 deletion javascript_nodejs/src/dialogs/shared/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 Rubén Hinojosa Chapel. All rights reserved.
// Copyright (c) Rubén Hinojosa Chapel. All rights reserved.
// Licensed under the MIT License.

const { CardFactory } = require('botbuilder');
Expand Down
2 changes: 1 addition & 1 deletion javascript_nodejs/src/dialogs/welcome/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 Rubén Hinojosa Chapel. All rights reserved.
// Copyright (c) Rubén Hinojosa Chapel. All rights reserved.
// Licensed under the MIT License.

const { CardFactory } = require('botbuilder');
Expand Down
99 changes: 39 additions & 60 deletions javascript_nodejs/src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2019 Rubén Hinojosa Chapel. All rights reserved.
// Copyright (c) Rubén Hinojosa Chapel. All rights reserved.
// Licensed under the MIT License.

// index.js is used to setup and configure your bot
Expand All @@ -12,23 +12,14 @@ const localizer = require('i18n');
// Import required bot services. See https://aka.ms/bot-services to learn more about the different parts of a bot.
const { BotFrameworkAdapter, MemoryStorage, ConversationState, UserState } = require('botbuilder');
const { LuisRecognizer, QnAMaker } = require('botbuilder-ai');

// Import required bot configuration.
const { BotConfiguration } = require('botframework-config');
const { CosmosDbStorage } = require('botbuilder-azure');

// This bot's main dialog.
const { MainDialog } = require('./dialogs/main');
const { CorePlusBot } = require('./bot');

// Read botFilePath and botFileSecret from .env file.
// Note: Ensure you have a .env file and include botFilePath and botFileSecret.
const ENV_FILE = path.join(__dirname, 'config/.env');
require('dotenv').config({ path: ENV_FILE });

// Get the .bot file path. Here we use one file per NODE_ENV. In Azure you should create 'config/production.bot' file.
// See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration.
const NODE_ENV = (process.env.NODE_ENV || 'development');
const BOT_FILE = path.join(__dirname, 'config/' + NODE_ENV + '.bot');
const DEV_ENV = 'local';
const NODE_ENV = (process.env.NODE_ENV || DEV_ENV);

// Name of the QnA Maker service in the .bot file without the locale key.
const QNA_CONFIGURATION = 'QNA-';
Expand All @@ -42,31 +33,23 @@ const QNA_MAKER_OPTIONS = {
top: 1
};

// See https://aka.ms/bot-file-encryption to learn about Bot Secrets.
// If you encrypt your .bot file, the botFileSecret key in the .env file should hold the secret key created with the MSBot tool.
// Note that the .env file is listed in the .gitignore file, so it won't be checked into your source control.
// More info at: http://martink.me/articles/managing-secrets-with-bot-files-in-bot-framework-v4

let botConfig;
try {
// Read bot configuration from .bot file.
botConfig = BotConfiguration.loadSync(BOT_FILE, process.env.botFileSecret);
} catch (err) {
console.error(`\nError reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment.`);
console.error(`\n - The botFileSecret is available under appsettings for your Azure Bot Service bot.`);
console.error(`\n - If you are running this bot locally, consider adding a .env file with botFilePath and botFileSecret.`);
console.error(`\n - See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration.\n\n`);
process.exit();
let appsettingsPath;
if (NODE_ENV === DEV_ENV) {
// Avoid uploading sensitive information like appsettings.json file to your source code repository.
// Here we store that file inside a Git ignored folder for development purposes.
appsettingsPath = path.join(__dirname, 'config/private/appsettings.json');
} else {
appsettingsPath = path.join(__dirname, 'config/appsettings.json');
}

// Get bot endpoint configuration by service name
const endpointConfig = botConfig.findServiceByNameOrId('endpoint');
const appsettings = require(appsettingsPath);
process.env.publicResourcesUrl = appsettings.publicResourcesUrl;

// Create adapter.
// See https://aka.ms/about-bot-adapter to learn more about adapters and how bots work.
const adapter = new BotFrameworkAdapter({
appId: endpointConfig.appId || process.env.microsoftAppID,
appPassword: endpointConfig.appPassword || process.env.microsoftAppPassword
appId: appsettings.microsoftAppId || process.env.microsoftAppID,
appPassword: appsettings.microsoftAppPassword || process.env.microsoftAppPassword
});

// Catch-all for errors.
Expand All @@ -86,26 +69,21 @@ adapter.onTurnError = async (context, error) => {
// A bot requires a state store to persist the dialog and user state between messages.
let conversationState, userState;

// For local development, in-memory storage is used.
// CAUTION: The Memory Storage used here is for local bot debugging only. When the bot
// is restarted, anything stored in memory will be gone.
const memoryStorage = new MemoryStorage();
conversationState = new ConversationState(memoryStorage);
userState = new UserState(memoryStorage);

// CAUTION: You must ensure your product environment has the NODE_ENV set
// to use the Azure Blob storage or Azure Cosmos DB providers.

// Add botbuilder-azure when using any Azure services.
// const { BlobStorage } = require('botbuilder-azure');
// // Get service configuration
// const blobStorageConfig = botConfig.findServiceByNameOrId(STORAGE_CONFIGURATION_ID);
// const blobStorage = new BlobStorage({
// containerName: (blobStorageConfig.container || DEFAULT_BOT_CONTAINER),
// storageAccountOrConnectionString: blobStorageConfig.connectionString,
// });
// conversationState = new ConversationState(blobStorage);
// userState = new UserState(blobStorage);
let storage;

if (NODE_ENV === DEV_ENV) {
// Use in-memory storage when process.env.NODE_ENV === 'local',
// use Azure Blob storage or Azure Cosmos DB otherwise.
// For local development, in-memory storage is used.
// CAUTION: The Memory Storage used here is for local bot debugging only. When the bot
// is restarted, anything stored in memory will be gone.
storage = new MemoryStorage();
} else {
storage = new CosmosDbStorage(appsettings.cosmosDb);
}

conversationState = new ConversationState(storage);
userState = new UserState(storage);

// Configure localizer
localizer.configure({
Expand All @@ -126,25 +104,25 @@ const availableLocales = localizer.getLocales();

// Add LUIS and QnAMaker recognizers for each locale
availableLocales.forEach((locale) => {
// Add LUIS recognizers
const luisConfig = botConfig.findServiceByNameOrId(LUIS_CONFIGURATION + locale);
// Add the LUIS recognizer.
let luisConfig = appsettings[LUIS_CONFIGURATION + locale];

if (!luisConfig || !luisConfig.appId) {
throw new Error('Missing LUIS configuration for locale "' + locale + '".\n\n');
throw new Error('Missing LUIS configuration for locale "' + locale + '" in appsettings.json file.\n');
}

luisRecognizers[locale] = new LuisRecognizer({
applicationId: luisConfig.appId,
// CAUTION: Its better to assign and use a subscription key instead of authoring key here.
endpointKey: luisConfig.subscriptionKey,
endpoint: luisConfig.getEndpoint()
endpoint: luisConfig.endpoint
}, undefined, true);

// Add QnAMaker recognizers
const qnaConfig = botConfig.findServiceByNameOrId(QNA_CONFIGURATION + locale);
// Add the QnA recognizer.
let qnaConfig = appsettings[QNA_CONFIGURATION + locale];

if (!qnaConfig || !qnaConfig.kbId) {
throw new Error(`QnA Maker application information not found in .bot file. Please ensure you have all required QnA Maker applications created and available in the .bot file.\n\n`);
throw new Error(`QnA Maker application information not found in appsettings.json file.\n`);
}

qnaRecognizers[locale] = new QnAMaker({
Expand All @@ -171,7 +149,8 @@ let server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, () => {
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 config/development.bot file in the Emulator`);
console.log('\nTo talk to your bot, open the emulator select "Open Bot"');
console.log('\nGet more info at: https://github.com/microsoft/BotFramework-Emulator/wiki/Getting-Started');
});

// Serve static files
Expand Down
Loading

0 comments on commit 739258e

Please sign in to comment.