From 96d5029285b9fcb6001e76b482857f0acf652e41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Hinojosa=20Chapel?= Date: Sun, 23 Feb 2020 21:44:06 +0100 Subject: [PATCH 1/3] Appsettings load refactoring. Adaptive card templating. --- .gitignore | 1 + javascript_nodejs/README.md | 79 +++++++------------ javascript_nodejs/package-lock.json | 5 ++ javascript_nodejs/package.json | 1 + javascript_nodejs/src/dialogs/shared/utils.js | 8 ++ .../src/dialogs/welcome/index.js | 19 +++-- .../welcome/resources/welcomeCard.json | 10 +-- javascript_nodejs/src/index.js | 20 ++--- javascript_nodejs/src/locales/en-US.json | 74 +++++++++++++++-- javascript_nodejs/web.config | 55 +++++++++++++ typescript_nodejs/README.md | 77 +++++++----------- typescript_nodejs/package-lock.json | 5 ++ typescript_nodejs/package.json | 3 +- typescript_nodejs/src/dialogs/shared/utils.ts | 8 ++ .../welcome/resources/welcomeCard.json | 10 +-- typescript_nodejs/src/index.ts | 27 +++---- typescript_nodejs/web.config | 55 +++++++++++++ 17 files changed, 299 insertions(+), 158 deletions(-) create mode 100644 javascript_nodejs/web.config create mode 100644 typescript_nodejs/web.config diff --git a/.gitignore b/.gitignore index 7e645b2..b23e129 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ build *.env private .DS_Store +appsettings.json diff --git a/javascript_nodejs/README.md b/javascript_nodejs/README.md index 737858d..8bcfd08 100644 --- a/javascript_nodejs/README.md +++ b/javascript_nodejs/README.md @@ -20,50 +20,35 @@ - [Create a QnA Maker service][15] 1. After creating the **QnA Maker** service, create a knowledge base using the `CoreplusKB.tsv` file located in the `cognitiveModels` folder of the project. Use this **.tsv** file to populate your KB. Then train and publish your model, and obtain the values to connect your bot to the knowledge base. -- Update the **.bot** file `development.bot` located in the `javascript_nodejs/src/config` folder with the missing values for LUIS and QnA Maker services. +- Create the **appsettings.json** file in the `javascript_nodejs/src` folder with the missing values for your bot app, LUIS and QnA Maker services. You will need Cosmos DB keys only when deploying to Azure. ```javascript { - "name": "coreplus", - "description": "", - "services": [ - { - "type": "endpoint", - "id": "1", - "name": "endpoint", - "appId": "", - "appPassword": "", - "endpoint": "http://localhost:3978/api/messages" - }, - { - "type": "luis", - "id": "20", - "name": "LUIS-en-US", - "appId": "", - "authoringKey": "", - "subscriptionKey": "", - "version": "0.1", - "region": "" - }, - { - "type": "qna", - "id": "30", - "name": "QNA-en-US", - "kbId": "", - "subscriptionKey": "", - "endpointKey": "", - "hostname": "https://your-qnamaker-app-name.azurewebsites.net/qnamaker" - } - ], - "padlock": "", - "version": "2.0" + "microsoftAppId": "", + "microsoftAppPassword": "", + "appInsights": { + "instrumentationKey": "" + }, + "LUIS-en-US": { + "appId": "", + "authoringKey": "", + "subscriptionKey": "", + "endpoint": "https://your-region.api.cognitive.microsoft.com" + }, + "QNA-en-US": { + "kbId": "", + "subscriptionKey": "", + "endpointKey": "", + "hostname": "https://your-qnamaker-app-name.azurewebsites.net/qnamaker" + }, + "cosmosDb": { + "serviceEndpoint": "https://your-cosmosdb-account-name.documents.azure.com:443/", + "authKey": "", + "databaseId": "", + "collectionId": "" + }, + "publicResourcesUrl": "http://localhost:3978" } ``` - -- From inside the development environment, create the `.env` file located in the `javascript_nodejs/src/config` folder with the following content: - ```bash - botFileSecret="" - publicResourcesUrl="http://localhost:3978" - ``` - Navigate to the `javascript_nodejs` folder and run the following npm commands to install modules and start the bot: ```bash @@ -74,16 +59,12 @@ # Testing the bot using Bot Framework Emulator **v4** [Bot Framework Emulator][5] is a desktop application that allows bot developers to test and debug their bots on localhost or running remotely through a tunnel. -- Install the Bot Framework Emulator version 4.2.0 or greater from [here][6] +- Install the Bot Framework Emulator version 4.5.0 or greater from [here][6] ## Connect to the bot using Bot Framework Emulator **v4** - Launch Bot Framework Emulator -- File -> Open Bot Configuration -- Navigate to `javascript_nodejs/src/config` folder -- Select `development.bot` file - -# About the .bot file -With the 4.3 release of the Bot Framework, Microsoft moved away from using .bot files. The .bot file [has been deprecated](https://docs.microsoft.com/en-us/azure/bot-service/bot-file-basics?view=azure-bot-service-4.0&tabs=js). The new recommended solution for managing resources is to use appsettings.json or .env file instead of the .bot file. So, I'll be updating the project in the near future accordingly. +- File -> Open Bot +- Enter a Bot URL of `http://localhost:3978/api/messages`, and . # Further reading - [CorePlus: a Microsoft Bot Framework v4 template][50] @@ -92,16 +73,13 @@ With the 4.3 release of the Bot Framework, Microsoft moved away from using .bot - [Azure Bot Service Introduction][21] - [Azure Bot Service Documentation][22] - [Deploying Your Bot to Azure][40] -- [msbot CLI][9] - [Azure Portal][10] - [Restify][30] -- [dotenv][31] [1]: https://dev.botframework.com [4]: https://nodejs.org [5]: https://github.com/microsoft/botframework-emulator [6]: https://github.com/Microsoft/BotFramework-Emulator/releases -[9]: https://github.com/Microsoft/botbuilder-tools/tree/master/packages/MSBot [10]: https://portal.azure.com [11]: https://www.luis.ai [12]: https://www.qnamaker.ai @@ -115,7 +93,6 @@ With the 4.3 release of the Bot Framework, Microsoft moved away from using .bot [21]: https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0 [22]: https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0 [30]: https://www.npmjs.com/package/restify -[31]: https://www.npmjs.com/package/dotenv [32]: https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0 [40]: https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-deploy-az-cli?view=azure-bot-service-4.0 [50]: https://www.codeproject.com/Articles/4254785/CorePlus-a-Microsoft-Bot-Framework-v4-template diff --git a/javascript_nodejs/package-lock.json b/javascript_nodejs/package-lock.json index e4912e9..354d400 100644 --- a/javascript_nodejs/package-lock.json +++ b/javascript_nodejs/package-lock.json @@ -292,6 +292,11 @@ } } }, + "adaptivecards-templating": { + "version": "0.1.1-alpha.0", + "resolved": "https://registry.npmjs.org/adaptivecards-templating/-/adaptivecards-templating-0.1.1-alpha.0.tgz", + "integrity": "sha512-rG17v9nKdX60SRDPSFabTU3HynTEvACmlN6Du0hMCf1x/HFzF1Y0fwTrpIfoxf0mVhM4okBupPOLL5f7K+JX+Q==" + }, "ajv": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", diff --git a/javascript_nodejs/package.json b/javascript_nodejs/package.json index 7408590..1cb61fd 100644 --- a/javascript_nodejs/package.json +++ b/javascript_nodejs/package.json @@ -16,6 +16,7 @@ "url": "https://github.com/hinojosachapel/CorePlus" }, "dependencies": { + "adaptivecards-templating": "^0.1.1-alpha.0", "botbuilder": "^4.7.1", "botbuilder-ai": "^4.7.1", "botbuilder-azure": "^4.7.1", diff --git a/javascript_nodejs/src/dialogs/shared/utils.js b/javascript_nodejs/src/dialogs/shared/utils.js index 9c1a2c9..ae2df05 100644 --- a/javascript_nodejs/src/dialogs/shared/utils.js +++ b/javascript_nodejs/src/dialogs/shared/utils.js @@ -2,6 +2,7 @@ // Licensed under the MIT License. const { CardFactory } = require('botbuilder'); +const ACData = require('adaptivecards-templating'); const localizer = require('i18n'); class Utils { @@ -122,6 +123,13 @@ class Utils { static shouldShowTyping() { return this.getRandomInt(0, 100) < 30; } + + static adaptiveCardDataBind(templatePayload, dataContext) { + const template = new ACData.Template(templatePayload); + const context = new ACData.EvaluationContext(); + context.$root = dataContext; + return CardFactory.adaptiveCard(template.expand(context)); + } } /** diff --git a/javascript_nodejs/src/dialogs/welcome/index.js b/javascript_nodejs/src/dialogs/welcome/index.js index 3cdb299..93b0b8f 100644 --- a/javascript_nodejs/src/dialogs/welcome/index.js +++ b/javascript_nodejs/src/dialogs/welcome/index.js @@ -48,18 +48,25 @@ class WelcomeDialog extends ComponentDialog { } getWelcomeCard(locale) { - welcomeCard.body[0].url = process.env.publicResourcesUrl + '/public/welcome_logo.png'; - welcomeCard.body[1].text = localizer.gettext(locale, 'welcome.tittle'); + const welcomeLogoUrl = process.env.publicResourcesUrl + '/public/welcome_logo.png'; + const welcomeTittle = localizer.gettext(locale, 'welcome.tittle'); // Restart command should be localized. const restartCommand = localizer.gettext(locale, 'restartCommand'); - welcomeCard.body[2].text = localizer.gettext(locale, 'welcome.subtittle', restartCommand); + const welcomeSubtittle = localizer.gettext(locale, 'welcome.subtittle', restartCommand); - welcomeCard.actions[0].title = localizer.gettext(locale, 'welcome.privacy'); + const welcomeAction = localizer.gettext(locale, 'welcome.action'); const language = locale.substring(0, 2); - welcomeCard.actions[0].url = process.env.publicResourcesUrl + '/public/privacy_policy_' + language + '.pdf'; + const welcomeActionUrl = process.env.publicResourcesUrl + '/public/privacy_policy_' + language + '.pdf'; + + const card = Utils.adaptiveCardDataBind(welcomeCard, { + welcomeLogoUrl, + welcomeTittle, + welcomeSubtittle, + welcomeAction, + welcomeActionUrl + }); - const card = CardFactory.adaptiveCard(welcomeCard); return { attachments: [card] }; } } diff --git a/javascript_nodejs/src/dialogs/welcome/resources/welcomeCard.json b/javascript_nodejs/src/dialogs/welcome/resources/welcomeCard.json index 819caa8..1be11c0 100644 --- a/javascript_nodejs/src/dialogs/welcome/resources/welcomeCard.json +++ b/javascript_nodejs/src/dialogs/welcome/resources/welcomeCard.json @@ -5,7 +5,7 @@ "body": [ { "type": "Image", - "url": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtB3AwMUeNoq4gUBGe6Ocj8kyh3bXa9ZbV7u1fVKQoyKFHdkqU", + "url": "{welcomeLogoUrl}", "size": "stretch" }, { @@ -13,7 +13,7 @@ "spacing": "medium", "size": "default", "weight": "bolder", - "text": "Welcome to Bot Framework!", + "text": "{welcomeTittle}", "wrap": true, "maxLines": 0 }, @@ -21,7 +21,7 @@ "type": "TextBlock", "size": "default", "isSubtle": true, - "text": "Now that you have successfully run your bot, follow the links in this Adaptive Card to expand your knowledge of Bot Framework.", + "text": "{welcomeSubtittle}", "wrap": true, "maxLines": 0 } @@ -29,8 +29,8 @@ "actions": [ { "type": "Action.OpenUrl", - "title": "text1", - "url": "https://docs.microsoft.com/en-us/azure/bot-service/?view=azure-bot-service-4.0" + "title": "{welcomeAction}", + "url": "{welcomeActionUrl}" } ] } diff --git a/javascript_nodejs/src/index.js b/javascript_nodejs/src/index.js index ba1fd5c..115624d 100644 --- a/javascript_nodejs/src/index.js +++ b/javascript_nodejs/src/index.js @@ -8,13 +8,18 @@ const path = require('path'); const restify = require('restify'); const localizer = require('i18n'); -const { readFileSync } = require('fs'); // 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'); const { CosmosDbStorage } = require('botbuilder-azure'); +// Avoid uploading sensitive information like appsettings.json file to your source code repository. +// .gitignore file contains appsettings.json as an ignored file. +// When creating your bot web app, manually create your server hosted appsettings.json file. +const appsettings = require('./appsettings.json'); +process.env.publicResourcesUrl = appsettings.publicResourcesUrl; + // This bot's main dialog. const { MainDialog } = require('./dialogs/main'); const { CorePlusBot } = require('./bot'); @@ -34,19 +39,6 @@ const QNA_MAKER_OPTIONS = { top: 1 }; -const appsettingsFile = 'appsettings.json'; -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', appsettingsFile); -} else { - appsettingsPath = path.join(__dirname, 'config', appsettingsFile); -} - -const appsettings = JSON.parse(readFileSync(appsettingsPath, 'UTF8')); -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({ diff --git a/javascript_nodejs/src/locales/en-US.json b/javascript_nodejs/src/locales/en-US.json index 38a8730..d746b6f 100644 --- a/javascript_nodejs/src/locales/en-US.json +++ b/javascript_nodejs/src/locales/en-US.json @@ -3,7 +3,8 @@ "tittle": "👋 Hello, welcome to Bot Framework!", "subtittle": "If you want to start over, just write \"**%s**\" at any time. Stuck and don't know what to say? Type \"**help**\" and I'll tell you some hints. You may also ask me questions about the trained subject in QnA Maker.", "privacy": "See my privacy policy", - "readyPrompt": "How can I help you?" + "readyPrompt": "How can I help you?", + "action": "welcome.action" }, "greeting": { "namePrompt": "What is your name?", @@ -59,13 +60,70 @@ "noThumb": "No 👎" }, "synonyms": { - "yes": ["yes", "y", "yeah", "yay", "👍", "awesome", "great", "cool", "sounds good", "works for me", "bingo", "go ahead", - "yup", "yes to that", "you're right", "that was right", "that was correct", "that's accurate", "accurate", "ok", - "yep", "that's right", "that's true", "correct", "that's right", "that's true", "sure", "good", "confirm", "thumbs up"], - "no": ["no", "n", "nope", "👎", "ko", "uh-uh", "nix", "nixie", "nixy", "nixey", "nay", "nah", "no way", - "negative", "out of the question", "for foul nor fair", "not", "thumbs down", "pigs might fly", "fat chance", - "catch me", "go fish", "certainly not", "by no means", "of course not", "hardly"], - "cancel": ["cancel", "abort"] + "yes": [ + "yes", + "y", + "yeah", + "yay", + "👍", + "awesome", + "great", + "cool", + "sounds good", + "works for me", + "bingo", + "go ahead", + "yup", + "yes to that", + "you're right", + "that was right", + "that was correct", + "that's accurate", + "accurate", + "ok", + "yep", + "that's right", + "that's true", + "correct", + "that's right", + "that's true", + "sure", + "good", + "confirm", + "thumbs up" + ], + "no": [ + "no", + "n", + "nope", + "👎", + "ko", + "uh-uh", + "nix", + "nixie", + "nixy", + "nixey", + "nay", + "nah", + "no way", + "negative", + "out of the question", + "for foul nor fair", + "not", + "thumbs down", + "pigs might fly", + "fat chance", + "catch me", + "go fish", + "certainly not", + "by no means", + "of course not", + "hardly" + ], + "cancel": [ + "cancel", + "abort" + ] }, "readyPrompt": "What can I do for you? \r (Choose one or type your own question)", "profanity": "That hurt my feelings. 😓 If you are stuck, just type \"**help**\" and I'll tell you some hints.", diff --git a/javascript_nodejs/web.config b/javascript_nodejs/web.config new file mode 100644 index 0000000..d324133 --- /dev/null +++ b/javascript_nodejs/web.config @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/typescript_nodejs/README.md b/typescript_nodejs/README.md index 2725781..9a50f22 100644 --- a/typescript_nodejs/README.md +++ b/typescript_nodejs/README.md @@ -21,50 +21,35 @@ - [Create a QnA Maker service][15] 1. After creating the **QnA Maker** service, create a knowledge base using the `CoreplusKB.tsv` file located in the `cognitiveModels` folder of the project. Use this **.tsv** file to populate your KB. Then train and publish your model, and obtain the values to connect your bot to the knowledge base. -- Update the **.bot** file `development.bot` located in the `typescript_nodejs/src/config` folder with the missing values for LUIS and QnA Maker services. +- Create the **appsettings.json** file in the `typescript_nodejs/src` folder with the missing values for your bot app, LUIS and QnA Maker services. You will need Cosmos DB keys only when deploying to Azure. ```javascript { - "name": "coreplus", - "description": "", - "services": [ - { - "type": "endpoint", - "id": "1", - "name": "endpoint", - "appId": "", - "appPassword": "", - "endpoint": "http://localhost:3978/api/messages" - }, - { - "type": "luis", - "id": "20", - "name": "LUIS-en-US", - "appId": "", - "authoringKey": "", - "subscriptionKey": "", - "version": "0.1", - "region": "" - }, - { - "type": "qna", - "id": "30", - "name": "QNA-en-US", - "kbId": "", - "subscriptionKey": "", - "endpointKey": "", - "hostname": "https://your-qnamaker-app-name.azurewebsites.net/qnamaker" - } - ], - "padlock": "", - "version": "2.0" + "microsoftAppId": "", + "microsoftAppPassword": "", + "appInsights": { + "instrumentationKey": "" + }, + "LUIS-en-US": { + "appId": "", + "authoringKey": "", + "subscriptionKey": "", + "endpoint": "https://your-region.api.cognitive.microsoft.com" + }, + "QNA-en-US": { + "kbId": "", + "subscriptionKey": "", + "endpointKey": "", + "hostname": "https://your-qnamaker-app-name.azurewebsites.net/qnamaker" + }, + "cosmosDb": { + "serviceEndpoint": "https://your-cosmosdb-account-name.documents.azure.com:443/", + "authKey": "", + "databaseId": "", + "collectionId": "" + }, + "publicResourcesUrl": "http://localhost:3978" } ``` - -- From inside the development environment, create the `.env` file located in the `typescript_nodejs/src/config` folder with the following content: - ```bash - botFileSecret="" - publicResourcesUrl="http://localhost:3978" - ``` - Navigate to the `typescript_nodejs` folder and run the following npm commands to install modules, build the bot source code (transpile the TypeScript source code into Node.js code) and start the bot: ```bash @@ -80,12 +65,8 @@ ## Connect to the bot using Bot Framework Emulator **v4** - Launch Bot Framework Emulator -- File -> Open Bot Configuration -- Navigate to `config` folder -- Select `development.bot` file - -# About the .bot file -With the 4.3 release of the Bot Framework, Microsoft moved away from using .bot files. The .bot file [has been deprecated](https://docs.microsoft.com/en-us/azure/bot-service/bot-file-basics?view=azure-bot-service-4.0&tabs=js). The new recommended solution for managing resources is to use appsettings.json or .env file instead of the .bot file. So, I'll be updating the project in the near future accordingly. +- File -> Open Bot +- Enter a Bot URL of `http://localhost:3978/api/messages`, and . # Further reading - [CorePlus: a Microsoft Bot Framework v4 template][50] @@ -95,17 +76,14 @@ With the 4.3 release of the Bot Framework, Microsoft moved away from using .bot - [Azure Bot Service Introduction][21] - [Azure Bot Service Documentation][22] - [Deploying Your Bot to Azure][40] -- [msbot CLI][9] - [Azure Portal][10] - [Restify][30] -- [dotenv][31] [1]: https://dev.botframework.com [3]: https://www.typescriptlang.org [4]: https://nodejs.org [5]: https://github.com/microsoft/botframework-emulator [6]: https://github.com/Microsoft/BotFramework-Emulator/releases -[9]: https://github.com/Microsoft/botbuilder-tools/tree/master/packages/MSBot [10]: https://portal.azure.com [11]: https://www.luis.ai [12]: https://www.qnamaker.ai @@ -119,7 +97,6 @@ With the 4.3 release of the Bot Framework, Microsoft moved away from using .bot [21]: https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0 [22]: https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0 [30]: https://www.npmjs.com/package/restify -[31]: https://www.npmjs.com/package/dotenv [32]: https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0 [40]: https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-deploy-az-cli?view=azure-bot-service-4.0 [50]: https://www.codeproject.com/Articles/4254785/CorePlus-a-Microsoft-Bot-Framework-v4-template diff --git a/typescript_nodejs/package-lock.json b/typescript_nodejs/package-lock.json index 41e2223..27a743c 100644 --- a/typescript_nodejs/package-lock.json +++ b/typescript_nodejs/package-lock.json @@ -327,6 +327,11 @@ } } }, + "adaptivecards-templating": { + "version": "0.1.1-alpha.0", + "resolved": "https://registry.npmjs.org/adaptivecards-templating/-/adaptivecards-templating-0.1.1-alpha.0.tgz", + "integrity": "sha512-rG17v9nKdX60SRDPSFabTU3HynTEvACmlN6Du0hMCf1x/HFzF1Y0fwTrpIfoxf0mVhM4okBupPOLL5f7K+JX+Q==" + }, "ajv": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", diff --git a/typescript_nodejs/package.json b/typescript_nodejs/package.json index 100b26f..1570da5 100644 --- a/typescript_nodejs/package.json +++ b/typescript_nodejs/package.json @@ -9,7 +9,7 @@ "build": "tsc --build && npm run copy:assets", "start": "npm run build && node ./build/index.js", "copy:assets": "npm run config && npm run jsonfiles && npm run public && npm run webchat", - "config": "copyfiles --all --up 1 \"./src/config/*.*\" ./build", + "config": "copyfiles --up 1 \"./src/appsettings.json\" ./build", "jsonfiles": "copyfiles --up 1 \"./src/**/*.json\" ./build && echo 'JSON files copied.'", "public": "copyfiles --up 1 \"./src/public/*.*\" ./build", "webchat": "copyfiles --up 1 \"./src/webchat/*.*\" ./build", @@ -22,6 +22,7 @@ "url": "https://github.com/hinojosachapel/CorePlus" }, "dependencies": { + "adaptivecards-templating": "^0.1.1-alpha.0", "botbuilder": "^4.7.1", "botbuilder-ai": "^4.7.1", "botbuilder-azure": "^4.7.1", diff --git a/typescript_nodejs/src/dialogs/shared/utils.ts b/typescript_nodejs/src/dialogs/shared/utils.ts index e39459e..07cf28a 100644 --- a/typescript_nodejs/src/dialogs/shared/utils.ts +++ b/typescript_nodejs/src/dialogs/shared/utils.ts @@ -2,6 +2,7 @@ // Licensed under the MIT License. import { Activity, CardFactory, CardAction } from 'botbuilder'; +import ACData from 'adaptivecards-templating'; import { TurnContext, Attachment } from 'botbuilder-core'; import { Choice } from 'botbuilder-dialogs'; import * as localizer from './localizer'; @@ -125,4 +126,11 @@ export class Utils { static shouldShowTyping(): boolean { return this.getRandomInt(0, 100) < 30; } + + static adaptiveCardDataBind(templatePayload: any, dataContext: any): Attachment { + const template: ACData.Template = new ACData.Template(templatePayload); + const context: ACData.EvaluationContext = new ACData.EvaluationContext(); + context.$root = dataContext; + return CardFactory.adaptiveCard(template.expand(context)); + } } diff --git a/typescript_nodejs/src/dialogs/welcome/resources/welcomeCard.json b/typescript_nodejs/src/dialogs/welcome/resources/welcomeCard.json index 819caa8..1be11c0 100644 --- a/typescript_nodejs/src/dialogs/welcome/resources/welcomeCard.json +++ b/typescript_nodejs/src/dialogs/welcome/resources/welcomeCard.json @@ -5,7 +5,7 @@ "body": [ { "type": "Image", - "url": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtB3AwMUeNoq4gUBGe6Ocj8kyh3bXa9ZbV7u1fVKQoyKFHdkqU", + "url": "{welcomeLogoUrl}", "size": "stretch" }, { @@ -13,7 +13,7 @@ "spacing": "medium", "size": "default", "weight": "bolder", - "text": "Welcome to Bot Framework!", + "text": "{welcomeTittle}", "wrap": true, "maxLines": 0 }, @@ -21,7 +21,7 @@ "type": "TextBlock", "size": "default", "isSubtle": true, - "text": "Now that you have successfully run your bot, follow the links in this Adaptive Card to expand your knowledge of Bot Framework.", + "text": "{welcomeSubtittle}", "wrap": true, "maxLines": 0 } @@ -29,8 +29,8 @@ "actions": [ { "type": "Action.OpenUrl", - "title": "text1", - "url": "https://docs.microsoft.com/en-us/azure/bot-service/?view=azure-bot-service-4.0" + "title": "{welcomeAction}", + "url": "{welcomeActionUrl}" } ] } diff --git a/typescript_nodejs/src/index.ts b/typescript_nodejs/src/index.ts index 3aa4b4b..b332781 100644 --- a/typescript_nodejs/src/index.ts +++ b/typescript_nodejs/src/index.ts @@ -5,10 +5,9 @@ // index.ts is used to setup and configure your bot // Import required packages -import * as path from 'path'; -import * as restify from 'restify'; -import * as localizer from './dialogs/shared/localizer'; -import { readFileSync } from 'fs'; +import path from 'path'; +import restify from 'restify'; +import localizer from './dialogs/shared/localizer'; import { LuisRecognizerDictionary, QnAMakerDictionary } from './dialogs/shared/types'; // Import required bot services. See https://aka.ms/bot-services to learn more about the different parts of a bot. @@ -16,6 +15,12 @@ import { BotFrameworkAdapter, Storage, MemoryStorage, ConversationState, UserSta import { LuisRecognizer, QnAMaker, QnAMakerOptions } from 'botbuilder-ai'; import { CosmosDbStorage } from 'botbuilder-azure'; +// Avoid uploading sensitive information like appsettings.json file to your source code repository. +// .gitignore file contains appsettings.json as an ignored file. +// When creating your bot web app, manually create your server hosted appsettings.json file. +import appsettings from './appsettings.json'; +process.env.publicResourcesUrl = appsettings.publicResourcesUrl; + // This bot's main dialog. import { MainDialog } from './dialogs/main'; import { CorePlusBot } from './bot'; @@ -35,20 +40,6 @@ const QNA_MAKER_OPTIONS: QnAMakerOptions = { top: 1 }; -const appsettingsFile: string = 'appsettings.json'; -let appsettingsPath: string = ''; -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', appsettingsFile); -} else { - appsettingsPath = path.join(__dirname, 'config', appsettingsFile); -} - -const appsettings = JSON.parse(readFileSync(appsettingsPath, 'UTF8')); - -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: BotFrameworkAdapter = new BotFrameworkAdapter({ diff --git a/typescript_nodejs/web.config b/typescript_nodejs/web.config new file mode 100644 index 0000000..c54848e --- /dev/null +++ b/typescript_nodejs/web.config @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 6de917df08d893786916677a63c20b45ebc18e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Hinojosa=20Chapel?= Date: Sun, 23 Feb 2020 21:46:11 +0100 Subject: [PATCH 2/3] Delete appsettings.json --- typescript_nodejs/src/config/appsettings.json | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 typescript_nodejs/src/config/appsettings.json diff --git a/typescript_nodejs/src/config/appsettings.json b/typescript_nodejs/src/config/appsettings.json deleted file mode 100644 index 15b81ed..0000000 --- a/typescript_nodejs/src/config/appsettings.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "microsoftAppId": "", - "microsoftAppPassword": "", - "appInsights": { - "instrumentationKey": "" - }, - "LUIS-en-US": { - "appId": "", - "authoringKey": "", - "subscriptionKey": "", - "endpoint": "https://your-region.api.cognitive.microsoft.com" - }, - "QNA-en-US": { - "kbId": "", - "subscriptionKey": "", - "endpointKey": "", - "hostname": "https://your-qnamaker-app-name.azurewebsites.net/qnamaker" - }, - "cosmosDb": { - "serviceEndpointURI": "https://your-cosmosdb-account-name.documents.azure.com:443/", - "authKey": "", - "databaseId": "", - "collectionId": "" - }, - "publicResourcesUrl": "http://localhost:3978" -} From d382e76c45dc145987587ebc0aee078d4ff64d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Hinojosa=20Chapel?= Date: Sun, 23 Feb 2020 21:49:39 +0100 Subject: [PATCH 3/3] Delete appsettings.json --- javascript_nodejs/src/config/appsettings.json | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 javascript_nodejs/src/config/appsettings.json diff --git a/javascript_nodejs/src/config/appsettings.json b/javascript_nodejs/src/config/appsettings.json deleted file mode 100644 index 5929946..0000000 --- a/javascript_nodejs/src/config/appsettings.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "microsoftAppId": "", - "microsoftAppPassword": "", - "appInsights": { - "instrumentationKey": "" - }, - "LUIS-en-US": { - "appId": "", - "authoringKey": "", - "subscriptionKey": "", - "endpoint": "https://your-region.api.cognitive.microsoft.com" - }, - "QNA-en-US": { - "kbId": "", - "subscriptionKey": "", - "endpointKey": "", - "hostname": "https://your-qnamaker-app-name.azurewebsites.net/qnamaker" - }, - "cosmosDb": { - "serviceEndpoint": "https://your-cosmosdb-account-name.documents.azure.com:443/", - "authKey": "", - "databaseId": "", - "collectionId": "" - }, - "publicResourcesUrl": "http://localhost:3978" -}