├── .github └── FUNDING.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── doc ├── BotApplicationForDotNet.pdf ├── BotBuilderAndAzureBotService.pdf ├── ComputerVision.pdf ├── FinalProject.pdf ├── LanguageProcessing.pdf ├── Localization.pdf ├── Recommendations.pdf └── qnamaker.PDF ├── img ├── bot_connector.png ├── bot_framework.png ├── bot_lifecycle.png ├── bot_nodejs.png └── mybot.png └── src └── nodejs ├── .gitignore ├── PostDeployScripts ├── githubProject.json.template ├── prepareSrc.cmd ├── publish.js.template ├── runGulp.cmd ├── setupGithubRemoteRepo.cmd ├── setupVsoRemoteRepo.cmd └── vsoProject.json.template ├── app.js ├── bot ├── conf.json ├── dialogs │ ├── changeLanguage.js │ ├── menu.js │ ├── movieBook.js │ └── requestInfo.js ├── index.js └── luis.js ├── iisnode.yml ├── locale ├── en │ └── index.json └── es │ └── index.json ├── package.json ├── publish.js ├── routes ├── index.js └── users.js ├── server.js ├── swagger.yaml ├── views └── error.ejs └── web.config /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: jdnichollsc 4 | patreon: proyecto26 5 | open_collective: proyecto26 6 | ko_fi: proyecto26 7 | custom: paypal.me/jdnichollsc 8 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ## Pull Request Process 9 | 10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a 11 | build. 12 | 2. Update the README.md with details of changes to the interface, this includes new environment 13 | variables, exposed ports, useful file locations and container parameters. 14 | 3. Increase the version numbers in any examples files and the README.md to the new version that this 15 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). 16 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you 17 | do not have permission to do that, you may request the second reviewer to merge it for you. 18 | 19 | ## Code of Conduct 20 | 21 | ### Our Pledge 22 | 23 | In the interest of fostering an open and welcoming environment, we as 24 | contributors and maintainers pledge to making participation in our project and 25 | our community a harassment-free experience for everyone, regardless of age, body 26 | size, disability, ethnicity, gender identity and expression, level of experience, 27 | nationality, personal appearance, race, religion, or sexual identity and 28 | orientation. 29 | 30 | ### Our Standards 31 | 32 | Examples of behavior that contributes to creating a positive environment 33 | include: 34 | 35 | * Using welcoming and inclusive language 36 | * Being respectful of differing viewpoints and experiences 37 | * Gracefully accepting constructive criticism 38 | * Focusing on what is best for the community 39 | * Showing empathy towards other community members 40 | 41 | Examples of unacceptable behavior by participants include: 42 | 43 | * The use of sexualized language or imagery and unwelcome sexual attention or 44 | advances 45 | * Trolling, insulting/derogatory comments, and personal or political attacks 46 | * Public or private harassment 47 | * Publishing others' private information, such as a physical or electronic 48 | address, without explicit permission 49 | * Other conduct which could reasonably be considered inappropriate in a 50 | professional setting 51 | 52 | ### Our Responsibilities 53 | 54 | Project maintainers are responsible for clarifying the standards of acceptable 55 | behavior and are expected to take appropriate and fair corrective action in 56 | response to any instances of unacceptable behavior. 57 | 58 | Project maintainers have the right and responsibility to remove, edit, or 59 | reject comments, commits, code, wiki edits, issues, and other contributions 60 | that are not aligned to this Code of Conduct, or to ban temporarily or 61 | permanently any contributor for other behaviors that they deem inappropriate, 62 | threatening, offensive, or harmful. 63 | 64 | ### Scope 65 | 66 | This Code of Conduct applies both within project spaces and in public spaces 67 | when an individual is representing the project or its community. Examples of 68 | representing a project or community include using an official project e-mail 69 | address, posting via an official social media account, or acting as an appointed 70 | representative at an online or offline event. Representation of a project may be 71 | further defined and clarified by project maintainers. 72 | 73 | ### Enforcement 74 | 75 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 76 | reported by contacting the project team at jdnichollsc@hotmail.com. All 77 | complaints will be reviewed and investigated and will result in a response that 78 | is deemed necessary and appropriate to the circumstances. The project team is 79 | obligated to maintain confidentiality with regard to the reporter of an incident. 80 | Further details of specific enforcement policies may be posted separately. 81 | 82 | Project maintainers who do not follow or enforce the Code of Conduct in good 83 | faith may face temporary or permanent repercussions as determined by other 84 | members of the project's leadership. 85 | 86 | ### Attribution 87 | 88 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 89 | available at [http://contributor-covenant.org/version/1/4][version] 90 | 91 | [homepage]: http://contributor-covenant.org 92 | [version]: http://contributor-covenant.org/version/1/4/ 93 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Proyecto 26 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |
3 | NodeJS(Express) + Swagger + Multi-Language 4 |

5 | 6 | ## Intro ☕ 7 | MyBot can be easily configured in any Express project by adding the [bot](src/nodejs/bot) folder, installing dependencies and initializing it 🤘 8 | ### Presentations: 9 | - [Bot Framework - Global Azure Bootcamp](https://slides.com/juandavidnicholls/bot-framework) 10 | - [My first Multi-language Bot!](https://slides.com/juandavidnicholls/my-bot) 11 | 12 | ## Installation ⏯ 13 | Do you want to see this template in action? 💻 14 | - Download the code [here](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/proyecto26/MyBot/tree/master/src/nodejs) 15 | - To run the project execute the commands: 16 | ``` 17 | npm install 18 | npm start 19 | ``` 20 | 21 | And remember install the following tools to debug your bot locally: 22 | - [Bot Framework Emulator](https://github.com/Microsoft/BotFramework-Emulator) 23 | - [ngrok](https://ngrok.com/download) (Required to connect to a bot hosted remotely) 24 | 25 | ![MyBot](img/bot_nodejs.png) 26 | 27 | More examples with **NodeJS**: 28 | - [BotBuilder](https://github.com/Microsoft/BotBuilder/tree/master/Node/examples) 29 | - [BotBuilder-Samples](https://github.com/Microsoft/BotBuilder-Samples/tree/master/Node) 30 | 31 | ## Bots History 🌎 32 | - 1960: ELIZA 33 | - 1970: PARRY 34 | - 1980: Graphic interface 35 | - 1990: Search engines 36 | - 2000: Social/App stores 37 | - 2010: Bots and agents, human Interaction/Experience 38 | 39 | ## Chatbots types 40 | - **Utilities:** It fulfills a function for the users and is measured according to the effectiveness of the answers. 41 | - **Social:** Success is measured according to the duration and level of user satisfaction, it is also possible to assess the level of satisfaction through APIs to recognize the level of emotion of users. 42 | - **Assistants (Cortana, Siri, etc):** Acts as a facilitator, usually comes integrated with the Operating System. Main features: 43 | * Utilities and social capacities 44 | * Continuous relationship with the user 45 | * Manage system functions 46 | 47 | ## Communication flow 48 | List the functions offered by the bot and describe a step by step for its execution: 49 | - Task 50 | - Objective 51 | - Motivation of the user 52 | - Steps 53 | - Forecasts 54 | 55 | ## Experience components 56 | - Learning and memory 57 | - Perception and sense 58 | - Personality (Intelligence) 59 | - Logic and reason 60 | - Accessibility 61 | - Meaning and tone of text 62 | - Cards 63 | - Images 64 | - Emojis 65 | - Response time 66 | - Conversational branch 67 | 68 | ## Design 69 | - Inclusive design (Design for all types of public) 70 | - UX (Avatar) 71 | - Character with personality 72 | - Define the devices and channels to support (Cortana, Email, Facebook, etc) 73 | - Form flow (conversation follow-up, validate the data) 74 | - Prevent redirections 75 | 76 | ## Lifecycle 77 | 78 | ![Bot Lifecycle](img/bot_lifecycle.png) 79 | 80 | # Bot Framework 🤖 81 | Open Source Framework to create and connect bots (Cross channel, AI and Up-to-Date resources). 82 | ![Bot Framework](img/bot_framework.png) 83 | 84 | ## Bot Connector Service 85 | Integrate the bot with different channels as Slack, Skype, Messenger, SMS, etc. 86 | ![Bot Connector](img/bot_connector.png) 87 | 88 | The **Bot Connector** can connect with the intelligence services and implement other functionalities such as: 89 | - Ability to store the state of the conversation. 90 | - Translate services. 91 | - Telemetry. Information about the service is collected, such as the number of requests, messages that have failed, etc. 92 | 93 | ## Bot Builder 94 | SDKs for .NET, NodeJS or we can use REST APIs to create and debug bots. It also includes the **Bot Framework Emulator** to test our bots and the Channel Inspector to preview the user experience of our bot on different channels. 95 | Integrate external services and Manage the conversation using [LUIS](https://www.luis.ai/welcome) (Language Understanding Intelligent Service). 96 | 97 | 98 | # Microsoft Cognitive Services 🌐 99 | Set of APIs to create smart applications. 100 | 101 | ## Vision 👀 102 | Image-processing algorithms to smartly identify, caption and moderate your pictures. 103 | - Computer Vision (Images) 104 | - Emotion 105 | - Content Moderator 106 | - Face 107 | - Video 108 | 109 | ## Speech 💬 110 | Convert spoken audio into text, use voice for verification, or add speaker recognition to your app. 111 | - Custom Speech Service (CRIS) 112 | - Speaker Recognition 113 | - Speech 114 | - Translator 115 | 116 | ## Language 🤝 117 | Allow your apps to process natural language with pre-built scripts, evaluate sentiment and learn how to recognize what users want. 118 | - Bing Spell Check 119 | - Language Understanding 120 | - Linguistic Analysis 121 | - Text Analytics 122 | - Web Language Model 123 | 124 | ### Videos 📹 125 | 126 | * [Introduction to LUIS](https://aka.ms/luis-intro-video) 127 | * [Advanced learning with LUIS](https://www.youtube.com/watch?v=39L0Gv2EcSk) 128 | * [Channel 9 Deep Dive into LUIS and Chatbots](https://channel9.msdn.com/Blogs/MVP-Azure/Cognitive-Services-Episode-3-Deep-dive-into-LUIS-and-Chatbots) 129 | 130 | ### To Learn 131 | - [Plan your LUIS app](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/plan-your-app) 132 | - [Use prebuilt domains in LUIS apps](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/luis-how-to-use-prebuilt-domains) 133 | - [Create your first LUIS app](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/luis-get-started-create-app) 134 | - [Manage intents](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/add-intents) 135 | - [Add utterances](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/add-example-utterances) 136 | - [Entities in LUIS](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/luis-concept-entity-types) and [Prebuilt entities](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/pre-builtentities) 137 | - [Manage entities](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/add-entities) 138 | - [Improve prediction accuracy using features](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/add-features) 139 | - [Test your LUIS app](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/train-test) 140 | - [Use active learning](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/label-suggested-utterances) 141 | - [Publish your trained app](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/publishapp) 142 | - [LUIS Samples](https://github.com/Microsoft/LUIS-Samples) 143 | 144 | ## Knowledge 📖 145 | Map complex information and data in order to solve tasks such as intelligent recommendations and semantic search. 146 | - Academic Knowledge 147 | - Entity Linking 148 | - Knowledge Exploration 149 | - Recommendations 150 | - QnA Maker 151 | 152 | ## Search 🔎 153 | Add Bing Search APIs to your apps and harness the ability to comb billions of webpages, images, videos, and news with a single API call. 154 | - Bing Autosuggest 155 | - Bing Image Search 156 | - Bing News Search 157 | - Bing Video Search 158 | - Bing Web Search 159 | 160 | # [QnA Maker](https://qnamaker.ai/) 👷 161 | A free and easy-to-use REST API based on artificial intelligence to respond to users' questions in a natural way through an optimized learning logic (Machine Learning). It is a question and answer service with a graphical interface that allows it to be easy to administer. 162 | 163 | 164 |
165 | .NET Example 166 | 167 | ```csharp 168 | [Serializable] 169 | public class QnADialog : QnAMakerDialog { 170 | 171 | public QnADialog() : 172 | base(new QnAMakerService(new QnAMakerAttribute("subscriptionKey", "knowledgeId", "answer not found", 0.5))) 173 | { 174 | } 175 | 176 | protected override async Task RespondFromQnAMakerResultAsync(IDialogContext, IMessageActivity message, QnAMakerResult result) 177 | { 178 | Activity response = ((Activity)context.Activity).CreateReply(); 179 | 180 | var firstAnswer = result.Answers.FirstOrDefault()?.Answer; 181 | var data = firstAnswer.Split("---"); 182 | 183 | if(data.Length == 1) { 184 | return await context.PostAsync(firstAnswer); 185 | } 186 | 187 | //Example to get data with a separator 188 | var title = data[0]; 189 | var description = data[1]; 190 | var url = data[2]; 191 | var image = data[3]; 192 | 193 | CustomCard card = new CustomCard 194 | { 195 | Title = title, SubTitle = description 196 | }; 197 | 198 | card.Buttons = new List 199 | { 200 | new CardAction(ActionTypes.OpenUrl, "text", value: url) 201 | }; 202 | 203 | card.Images = new List{ 204 | new CardImage(url = image) 205 | }; 206 | 207 | response.Attachments.Add(card.ToAttachment()); 208 | 209 | return await context.PostAsync(response); 210 | } 211 | } 212 | ``` 213 |
214 | 215 | ## Installation 216 | - NodeJS via npm: `botbuilder-cognitiveservices` 217 | - .NET via Nuget package: `Microsoft.Bot.Builder.CognitiveServices` 218 | 219 | ## QnA Maker Dialog 220 | Personalization in the response to the user according to the reliability control. 221 | 222 | ```csharp 223 | [Serializable] 224 | [QnAMaker("subscriptionKey", "knowledgeId", "standard phrase when it doesn't satisfy the minimum response reliability index", 0.5, 1)] 225 | public class QnADialogWithActiveLearning : QnAMakerDialog 226 | { 227 | } 228 | ``` 229 | 230 | # Channels 231 | A channel is a connection between Bot Framework and communication applications. 232 | 233 | ## Publish 234 | - **Skype:** 235 | > A Skype account is required, we can deploy bots to test. 236 | - **Microsoft Teams:** 237 | > An office 365 account is required. We need to enable the permissions to use external apps from the administration panel of Office 365 (Configuration/Services...). 238 | - **Telegram:** 239 | > A Telegram account is required. **BotFather** is an app that we need to install to create and manage our bots, check [here](https://telegram.me/botfather). 240 | - **Web Chat:** 241 | > It's inserted using a HTML Iframe. 242 | - **Slack:** 243 | > It's required to create an app from Slack API, add a new Redirect URL to https://slack.botframework.com and enter the credentials. 244 | 245 | ## Resources ⛩ 246 | - [Microsoft labs for learning to develop AI-oriented applications](https://azure.github.io/LearnAI-Bootcamp/) 247 | - [Microsoft Bot Framework Resources](https://blogs.msdn.microsoft.com/smich/2016/09/30/microsoft-bot-framework-resources/) 248 | 249 | ## Credits 👍 250 | - **[TI Capacitación](https://ticapacitacion.com)** 251 | 252 | ## Contributing ✨ 253 | When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. 254 | Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated** ❤️. 255 | You can learn more about how you can contribute to this project in the [contribution guide](https://github.com/proyecto26/MyBot/blob/master/CONTRIBUTING.md). 256 | 257 | ## Collaborators 🥇 258 | [jdnichollsc](https://github.com/jdnichollsc) | 259 | :---: | 260 | [Juan Nicholls](mailto:jdnichollsc@hotmail.com) | 261 | 262 | ## Supporting 🍻 263 | I believe in Unicorns 🦄 264 | Support [me](http://www.paypal.me/jdnichollsc/2), if you do too. 265 | 266 | Donate **Ethereum**, **ADA**, **BNB**, **SHIBA**, **USDT/USDC**, **DOGE**, etc: 267 | 268 | > Wallet address: jdnichollsc.eth 269 | 270 | Please let us know your contributions! 🙏 271 | 272 | ## License ⚖️ 273 | This repository is available under the [MIT License](https://github.com/proyecto26/MyBot/blob/master/LICENSE). 274 | 275 | ## Happy coding 💯 276 | Made with ❤️ 277 | 278 | 279 | -------------------------------------------------------------------------------- /doc/BotApplicationForDotNet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/doc/BotApplicationForDotNet.pdf -------------------------------------------------------------------------------- /doc/BotBuilderAndAzureBotService.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/doc/BotBuilderAndAzureBotService.pdf -------------------------------------------------------------------------------- /doc/ComputerVision.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/doc/ComputerVision.pdf -------------------------------------------------------------------------------- /doc/FinalProject.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/doc/FinalProject.pdf -------------------------------------------------------------------------------- /doc/LanguageProcessing.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/doc/LanguageProcessing.pdf -------------------------------------------------------------------------------- /doc/Localization.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/doc/Localization.pdf -------------------------------------------------------------------------------- /doc/Recommendations.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/doc/Recommendations.pdf -------------------------------------------------------------------------------- /doc/qnamaker.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/doc/qnamaker.PDF -------------------------------------------------------------------------------- /img/bot_connector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/img/bot_connector.png -------------------------------------------------------------------------------- /img/bot_framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/img/bot_framework.png -------------------------------------------------------------------------------- /img/bot_lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/img/bot_lifecycle.png -------------------------------------------------------------------------------- /img/bot_nodejs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/img/bot_nodejs.png -------------------------------------------------------------------------------- /img/mybot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proyecto26/MyBot/1ce44bc25b0619b73116c6f5e4dad7b877a08ba9/img/mybot.png -------------------------------------------------------------------------------- /src/nodejs/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | *.js.map 3 | package-lock.json -------------------------------------------------------------------------------- /src/nodejs/PostDeployScripts/githubProject.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{WEB_SITE_NAME}", 3 | "description": "{WEB_SITE_NAME} Azure Bot Service Code", 4 | "homepage": "https://github.com", 5 | "private": false, 6 | "has_issues": true, 7 | "has_projects": true, 8 | "has_wiki": true 9 | } -------------------------------------------------------------------------------- /src/nodejs/PostDeployScripts/prepareSrc.cmd: -------------------------------------------------------------------------------- 1 | rem @echo off 2 | setlocal 3 | SET password=%1 4 | SET repoName=srcRepo 5 | SET repoUrl=file:///%HOMEDRIVE:~0,1%/%HOMEPATH:~1%/site/%repoName% 6 | SET download=bot-src 7 | 8 | echo %repoUrl% 9 | 10 | rem cd to project root 11 | pushd ..\wwwroot 12 | 13 | rem init git 14 | call git init 15 | call git config user.name "botframework" 16 | call git config user.email "util@botframework.com" 17 | call git add . 18 | call git commit -m "prepare to download source" 19 | call git remote add srcRepo %repoUrl% 20 | popd 21 | 22 | rem init upstream 23 | pushd %HOME%\site 24 | mkdir srcRepo 25 | cd srcRepo 26 | call git init --bare 27 | popd 28 | 29 | rem push to upstream 30 | pushd ..\wwwroot 31 | call git push --set-upstream srcRepo master 32 | popd 33 | 34 | rem clone srcRepo 35 | pushd %HOME%\site 36 | call git clone %repoUrl% %download% 37 | rem delete .git 38 | cd %download% 39 | call rm -r -f .git 40 | popd 41 | 42 | rem prepare for publish 43 | type PostDeployScripts\publish.js.template | sed -e s/\{WEB_SITE_NAME\}/%WEBSITE_SITE_NAME%/g | sed -e s/\{PASSWORD\}/%password%/g > %HOME%\site\%download%\publish.js 44 | 45 | rem preare the zip file 46 | %HOMEDRIVE%\7zip\7za a %HOME%\site\%download%.zip %HOME%\site\%download%\* 47 | 48 | rem cleanup git stuff 49 | pushd ..\wwwroot 50 | call rm -r -f .git 51 | popd 52 | 53 | pushd %HOME%\site 54 | call rm -r -f %download% 55 | call rm -r -f %repoName% 56 | popd 57 | 58 | endlocal 59 | -------------------------------------------------------------------------------- /src/nodejs/PostDeployScripts/publish.js.template: -------------------------------------------------------------------------------- 1 | var zipFolder = require('zip-folder'); 2 | var path = require('path'); 3 | var fs = require('fs'); 4 | var request = require('request'); 5 | 6 | var rootFolder = path.resolve('.'); 7 | var zipPath = path.resolve(rootFolder, '../{WEB_SITE_NAME}.zip'); 8 | var kuduApi = 'https://{WEB_SITE_NAME}.scm.azurewebsites.net/api/zip/site/wwwroot'; 9 | var userName = '${WEB_SITE_NAME}'; 10 | var password = '{PASSWORD}'; 11 | 12 | function uploadZip(callback) { 13 | fs.createReadStream(zipPath).pipe(request.put(kuduApi, { 14 | auth: { 15 | username: userName, 16 | password: password, 17 | sendImmediately: true 18 | }, 19 | headers: { 20 | "Content-Type": "applicaton/zip" 21 | } 22 | })) 23 | .on('response', function(resp){ 24 | if (resp.statusCode >= 200 && resp.statusCode < 300) { 25 | fs.unlink(zipPath); 26 | callback(null); 27 | } else if (resp.statusCode >= 400) { 28 | callback(resp); 29 | } 30 | }) 31 | .on('error', function(err) { 32 | callback(err) 33 | }); 34 | } 35 | 36 | function publish(callback) { 37 | zipFolder(rootFolder, zipPath, function(err) { 38 | if (!err) { 39 | uploadZip(callback); 40 | } else { 41 | callback(err); 42 | } 43 | }) 44 | } 45 | 46 | publish(function(err) { 47 | if (!err) { 48 | console.log('{WEB_SITE_NAME} publish'); 49 | } else { 50 | console.error('failed to publish {WEB_SITE_NAME}', err); 51 | } 52 | }); -------------------------------------------------------------------------------- /src/nodejs/PostDeployScripts/runGulp.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | if exist ..\wwwroot\package.json ( 5 | pushd ..\wwwroot 6 | echo npm install --production 7 | call npm install --production 8 | popd 9 | ) 10 | 11 | for /d %%d in (..\wwwroot\*) do ( 12 | echo check %%d 13 | pushd %%d 14 | if exist package.json ( 15 | echo npm install --production 16 | call npm install --production 17 | ) else ( 18 | echo no package.json found 19 | ) 20 | popd 21 | ) 22 | 23 | echo record deployment timestamp 24 | date /t >> ..\deployment.log 25 | time /t >> ..\deployment.log 26 | echo ---------------------- >> ..\deployment.log 27 | echo Deployment done 28 | 29 | -------------------------------------------------------------------------------- /src/nodejs/PostDeployScripts/setupGithubRemoteRepo.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | rem ------------------------------------------------------------------------------------------ 4 | rem setupVsoRemoteRepo [remoteUser] [personalAccessToken] [projName{optional}] 5 | rem create and populate VSO git repo for the ABS code instance 6 | rem 7 | rem remoteUser: user account name of the personal access token 8 | rem personalAccessToken: the personal access token used to access github REST API (requires repos scope) 9 | rem projName the name of the project to create (default to WEBSITE_SITE_NAME) 10 | rem ------------------------------------------------------------------------------------------ 11 | set remoteUrl=https://api.github.com 12 | set remoteUser=%1 13 | set remotePwd=%2 14 | set projName=%3 15 | if '%projName%'=='' set projName=%WEBSITE_SITE_NAME% 16 | set repoUrl=https://%remoteUser%:%remotePwd%@github.com/%remoteUser%/%projName%.git 17 | rem use curl to create project 18 | pushd ..\wwwroot 19 | type PostDeployScripts\githubProject.json.template | sed -e s/\{WEB_SITE_NAME\}/%projName%/g > %TEMP%\githubProject.json 20 | call curl -H "Content-Type: application/json" -u %remoteUser%:%remotePwd% -d "@%TEMP%\githubProject.json" -X POST %remoteUrl%/user/repos 21 | rem rm %TEMP%\githubProject.json 22 | popd 23 | 24 | popd 25 | rem cd to project root 26 | pushd ..\wwwroot 27 | 28 | rem init git 29 | call git init 30 | call git config user.name "%remoteUser%" 31 | call git config user.password "%remotePwd%" 32 | call git config user.email "util@botframework.com" 33 | call git add . 34 | call git commit -m "prepare to setup source control" 35 | call git push %repoUrl% master 36 | popd 37 | 38 | 39 | rem cleanup git stuff 40 | pushd ..\wwwroot 41 | call rm -r -f .git 42 | popd 43 | 44 | endlocal -------------------------------------------------------------------------------- /src/nodejs/PostDeployScripts/setupVsoRemoteRepo.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | rem ------------------------------------------------------------------------------------------ 4 | rem setupVsoRemoteRepo [vsoRemote] [vsoUserName] [vsoPersonalAccessToken] [projName{optional}] 5 | rem create and populate VSO git repo for the ABS code instance 6 | rem 7 | rem vsoRmote: url of the VSO site (e.g. https://awesomebot.visualstudio.com ) 8 | rem vosUserName: user account name of the personal access token 9 | rem vsoPersonalAccessToken: the personal access token used to access VSO REST api 10 | rem projName the name of the project to create (default to WEBSITE_SITE_NAME) 11 | rem ------------------------------------------------------------------------------------------ 12 | set remoteUrl=%1 13 | set remoteUser=%2 14 | set remotePwd=%3 15 | set projName=%4 16 | if '%projName%'=='' set projName=%WEBSITE_SITE_NAME% 17 | set vstsRoot=%remoteUrl% 18 | set repoUrl=https://%remoteUser%:%remotePwd%@%remoteUrl:~8%/_git/%projName% 19 | set vstsCreateProject=https://%remoteUser%:%remotePwd%@%remoteUrl:~8%/defaultcollection/_apis/projects?api-version=3.0 20 | 21 | rem use curl to create project 22 | pushd ..\wwwroot 23 | type PostDeployScripts\vsoProject.json.template | sed -e s/\{WEB_SITE_NAME\}/%projName%/g > %TEMP%\vsoProject.json 24 | call curl -H "Content-Type: application/json" -d "@%TEMP%\vsoProject.json" -X POST %vstsCreateProject% 25 | rm %TEMP%\vsoProject.json 26 | rem sleep for 15 seconds for the creation to complete, this is a wild guess 27 | call sleep 15 28 | popd 29 | 30 | popd 31 | rem cd to project root 32 | pushd ..\wwwroot 33 | 34 | rem init git 35 | call git init 36 | call git config user.name "%remoteUser%" 37 | call git config user.password "%remotePwd%" 38 | call git config user.email "util@botframework.com" 39 | call git add . 40 | call git commit -m "prepare to setup source control" 41 | call git push %repoUrl% master 42 | popd 43 | 44 | 45 | rem cleanup git stuff 46 | pushd ..\wwwroot 47 | call rm -r -f .git 48 | popd 49 | 50 | endlocal -------------------------------------------------------------------------------- /src/nodejs/PostDeployScripts/vsoProject.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{WEB_SITE_NAME}", 3 | "description": "{WEB_SITE_NAME} Azure Bot Service Code", 4 | "capabilities": { 5 | "versioncontrol": { 6 | "sourceControlType": "Git" 7 | }, 8 | "processTemplate": { 9 | "templateTypeId": "6b724908-ef14-45cf-84f8-768b5384da45" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/nodejs/app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const path = require('path'); 3 | const favicon = require('serve-favicon'); 4 | const logger = require('morgan'); 5 | const cookieParser = require('cookie-parser'); 6 | const bodyParser = require('body-parser'); 7 | const swaggerUi = require('swagger-ui-express'); 8 | const YAML = require('yamljs'); 9 | const swaggerDocument = YAML.load(path.join(__dirname, 'swagger.yaml')); 10 | const app = express(); 11 | app.set('view engine', 'ejs'); 12 | 13 | /** 14 | * Express routes 15 | */ 16 | const index = require('./routes/index'); 17 | const users = require('./routes/users'); 18 | 19 | app.use(logger('dev')); 20 | app.use(bodyParser.json()); 21 | app.use(bodyParser.urlencoded({ extended: false })); 22 | app.use(cookieParser()); 23 | 24 | // static folder for assets 25 | // app.use(express.static(path.join(__dirname, 'public'))); 26 | // uncomment after placing your favicon in /public 27 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 28 | 29 | app.use('/', index); 30 | app.use('/api/help', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); 31 | app.use('/api/users', users); 32 | 33 | /** 34 | * Initialize the Bot - localhost:3978 by default 35 | */ 36 | const bot = require('./bot'); 37 | bot.initialize(app); 38 | 39 | // catch 404 and forward to error handler 40 | app.use(function(req, res, next) { 41 | let err = new Error('Not Found'); 42 | err.status = 404; 43 | next(err); 44 | }); 45 | 46 | // error handler 47 | app.use(function(err, req, res, next) { 48 | // set locals, only providing error in development 49 | res.locals.message = err.message; 50 | res.locals.error = req.app.get('env') === 'development' ? err : {}; 51 | 52 | // render the error page 53 | if(!res.headersSent) { 54 | res.status(err.status || 500); 55 | res.render('error'); 56 | } 57 | else{ 58 | next(); 59 | } 60 | }); 61 | 62 | module.exports = app; 63 | -------------------------------------------------------------------------------- /src/nodejs/bot/conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "MicrosoftAppId": "c6831a49-9de5-445c-8d69-7d36ade8b1b2", 3 | "MicrosoftAppPassword" : "IH7*k$OjX5rV1i9l", 4 | "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=bot26storage;AccountKey=jpETR5jiFA3ZiNclK38/uckpK00zsFW+VJvWHU7gNyYp0bKppL7hUKjzsJlYmJVfhFSwaWy8ZF6RnVkJeYbNkQ==;", 5 | "LuisAppId_English": "64defde4-ba25-4f83-a41d-eb1ce452e40e", 6 | "LuisAppId_Spanish": "6022d5aa-4d16-4a87-bdcd-df87b3a9620a", 7 | "LuisAPIKey": "e36aac94e6c54b7c83512820263d1b40", 8 | "LuisAPIHostName": "westus.api.cognitive.microsoft.com" 9 | } -------------------------------------------------------------------------------- /src/nodejs/bot/dialogs/changeLanguage.js: -------------------------------------------------------------------------------- 1 | const _ = require('lodash') 2 | const builder = require('botbuilder') 3 | 4 | const changeLanguage = (bot) => { 5 | 6 | const languagesSupported = [ 7 | { key: 'en', value: 'English' }, 8 | { key: 'es', value: 'Español' } 9 | ] 10 | 11 | return bot.dialog('/changeLanguage', [ 12 | (session) => { 13 | // Prompt the user to select their preferred locale 14 | builder.Prompts.choice(session, "preferred_language", _.map(languagesSupported, 'value'), { listStyle: 2 }) 15 | }, 16 | (session, results) => { 17 | const language = _.find(languagesSupported, { value: results.response.entity }) 18 | const locale = language && language.key 19 | session.preferredLocale(locale, (err) => { 20 | if (!err) { 21 | // Locale files loaded 22 | session.endDialog('language_selected', results.response.entity) 23 | } else { 24 | // Error loading the language 25 | session.error(err) 26 | } 27 | }) 28 | } 29 | ]) 30 | } 31 | 32 | module.exports = { 33 | init: changeLanguage 34 | } -------------------------------------------------------------------------------- /src/nodejs/bot/dialogs/menu.js: -------------------------------------------------------------------------------- 1 | const _ = require('lodash') 2 | const builder = require('botbuilder') 3 | 4 | const menu = (bot) => { 5 | 6 | let menuOptions = [] 7 | 8 | return bot.dialog('/menu', [ 9 | (session, args, next) => { 10 | session.userData.luisEnabled = false 11 | if(session.preferredLocale()) { 12 | next() 13 | } 14 | else { 15 | session.send('greeting') 16 | session.send('instructions') 17 | session.beginDialog('/changeLanguage') 18 | } 19 | }, 20 | (session) => { 21 | 22 | menuOptions = [ 23 | 'request_info', 24 | 'enable_luis', 25 | 'change_language' 26 | ].map(option => ({ 27 | key: option, 28 | value: session.gettext(option) 29 | })) 30 | const options = menuOptions.map(option => option.value) 31 | 32 | builder.Prompts.choice(session, 'select_demo', options, { listStyle: 3 }) 33 | }, 34 | (session, results, next) => { 35 | const option = _.find(menuOptions, { value: results.response.entity }) 36 | switch (option.key) { 37 | case 'request_info': 38 | session.beginDialog('/requestInfo') 39 | break 40 | case 'enable_luis': 41 | session.userData.luisEnabled = true 42 | session.endDialog('luis_enabled') 43 | break 44 | case 'change_language': 45 | session.beginDialog('/changeLanguage') 46 | break 47 | default: 48 | session.send('must_select_option') 49 | session.reset() 50 | break 51 | } 52 | } 53 | ]) 54 | } 55 | 56 | module.exports = { 57 | init: menu 58 | } -------------------------------------------------------------------------------- /src/nodejs/bot/dialogs/movieBook.js: -------------------------------------------------------------------------------- 1 | const _ = require('lodash') 2 | const builder = require('botbuilder') 3 | 4 | const movieBook = (bot) => { 5 | 6 | return bot.dialog('MovieTickets.Book', [ 7 | (session, args, next) => { 8 | var intent = args.intent 9 | var title = builder.EntityRecognizer.findEntity(intent.entities, 'MovieTickets.MovieTitle') 10 | 11 | var movie = session.dialogData.movie = { 12 | title: title ? title.entity : '' 13 | } 14 | 15 | session.endDialog('movie_selected', movie.title) 16 | //https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-nodejs-tutorial-build-bot-framework-sa 17 | //https://docs.microsoft.com/en-us/azure/bot-service/nodejs/bot-builder-nodejs-recognize-intent-luis 18 | } 19 | ]); 20 | } 21 | 22 | module.exports = { 23 | init: movieBook 24 | } -------------------------------------------------------------------------------- /src/nodejs/bot/dialogs/requestInfo.js: -------------------------------------------------------------------------------- 1 | const builder = require('botbuilder') 2 | 3 | const requestInfo = (bot) => { 4 | return bot.dialog('/requestInfo', [ 5 | (session) => { 6 | builder.Prompts.text(session, "request_name"); 7 | }, 8 | (session, results) => { 9 | session.userData.name = results.response; 10 | session.save(); 11 | const locale = session.preferredLocale(); 12 | const localizer = session.localizer; 13 | builder.Prompts.number(session, `${results.response}, ${localizer.gettext(locale, "years_coding")}`); 14 | }, 15 | (session, results) => { 16 | session.dialogData.coding = results.response; 17 | builder.Prompts.choice(session, "preferred_language", ["JavaScript", "C#", "Java"]); 18 | }, 19 | (session, results) => { 20 | const userData = session.userData 21 | const dialogData = session.dialogData; 22 | const message = session.gettext('programming_years_lang', userData.name, dialogData.coding, results.response.entity) 23 | session.endDialog(message); 24 | } 25 | ]); 26 | } 27 | 28 | module.exports = { 29 | init: requestInfo 30 | } -------------------------------------------------------------------------------- /src/nodejs/bot/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Bot Framework configuration 3 | */ 4 | const builder = require('botbuilder') 5 | const botbuilder_azure = require('botbuilder-azure') 6 | const _ = require('lodash') 7 | const chalk = require('chalk') 8 | const log = console.log 9 | const localConf = require('./conf.json') 10 | 11 | const microsoftAppId = process.env['MicrosoftAppId'] || localConf.MicrosoftAppId 12 | const microsoftAppPassword = process.env['MicrosoftAppPassword'] || localConf.MicrosoftAppPassword 13 | const azureWebJobsStorage = process.env['AzureWebJobsStorage'] || localConf.AzureWebJobsStorage 14 | 15 | // Create chat connector for communicating with the Bot Framework Service 16 | const connector = new builder.ChatConnector({ 17 | appId: microsoftAppId, 18 | appPassword: microsoftAppPassword, 19 | openIdMetadata: process.env.BotOpenIdMetadata 20 | }) 21 | 22 | /*---------------------------------------------------------------------------------------- 23 | * Bot Storage: This is a great spot to register the private state storage for your bot. 24 | * We provide adapters for Azure Table, CosmosDb, SQL Azure, or you can implement your own! 25 | * For samples and documentation, see: https://github.com/Microsoft/BotBuilder-Azure 26 | * ---------------------------------------------------------------------------------------- */ 27 | 28 | const tableName = 'botdata' 29 | const azureTableClient = new botbuilder_azure.AzureTableClient(tableName, azureWebJobsStorage) 30 | const tableStorage = new botbuilder_azure.AzureBotStorage({ gzipData: false }, azureTableClient) 31 | 32 | const dialogs = require('require-all')(__dirname + '/dialogs') 33 | const luis = require('./luis.js') 34 | 35 | const _initialize = (server) => { 36 | 37 | // Listen for messages from users 38 | server.post('/api/messages', connector.listen()) 39 | 40 | // Create your bot with a function to receive messages from the user 41 | const bot = new builder.UniversalBot(connector, (session, args) => { 42 | 43 | // Prevent open dialogs when LUIS is enabled 44 | if(!session.userData.luisEnabled) { 45 | session.beginDialog('/menu') 46 | } 47 | }) 48 | bot.set('storage', tableStorage) 49 | // Do not persist userData 50 | //bot.set('persistUserData', false) 51 | 52 | // Do not persist conversationData 53 | //bot.set('persistConversationData', false) 54 | 55 | //Add the dialogs 56 | const menuDialog = dialogs.menu.init(bot) 57 | const changeLanguageDialog = dialogs.changeLanguage.init(bot) 58 | const requestInfoDialog = dialogs.requestInfo.init(bot) 59 | 60 | /** 61 | * Initialize LUIS 62 | */ 63 | luis.initialize(bot) 64 | 65 | bot.customAction({ 66 | matches: /exit/gi, 67 | onSelectAction: (session, args, next) => { 68 | session.userData.luisEnabled = false 69 | session.reset() 70 | } 71 | }) 72 | } 73 | 74 | module.exports = { 75 | initialize: _initialize 76 | } -------------------------------------------------------------------------------- /src/nodejs/bot/luis.js: -------------------------------------------------------------------------------- 1 | /** 2 | * LUIS Configuration 3 | */ 4 | const builder = require('botbuilder') 5 | const chalk = require('chalk') 6 | const log = console.log 7 | const localConf = require('./conf.json') 8 | 9 | const luisAppIdEnglish = process.env['LuisAppId_English'] || process.env['LuisAppId'] || localConf.LuisAppId_English 10 | const luisAppIdSpanish = process.env['LuisAppId_Spanish'] || localConf.LuisAppId_Spanish 11 | const luisAPIKey = process.env['LuisAPIKey'] || localConf.LuisAPIKey 12 | const luisAPIHostName = process.env['LuisAPIHostName'] || localConf.LuisAPIHostName 13 | 14 | const dialogs = require('require-all')(__dirname + '/dialogs') 15 | 16 | const _initialize = (bot) => { 17 | 18 | const recognizer = new builder.LuisRecognizer({ 19 | //add a single model or model by language 20 | 'en': `https://${luisAPIHostName}/luis/v2.0/apps/${luisAppIdEnglish}?subscription-key=${luisAPIKey}&verbose=true&timezoneOffset=0&q=`, 21 | 'es': `https://${luisAPIHostName}/luis/v2.0/apps/${luisAppIdSpanish}?subscription-key=${luisAPIKey}&verbose=true&timezoneOffset=0&q=` 22 | }) 23 | .onEnabled((session, callback) => { 24 | //Prevent enable LUIS while the dialogs are running 25 | //const enabled = session.dialogStack().length == 0 26 | 27 | const enabled = session.userData.luisEnabled 28 | log(chalk.green(`LUIS ENABLED: ${enabled}`)) 29 | callback(null, enabled) 30 | }) 31 | bot.recognizer(recognizer) 32 | 33 | const movieBook = dialogs.movieBook.init(bot) 34 | movieBook.triggerAction({ matches: 'MovieTickets.Book' }) 35 | 36 | bot.dialog('/greeting', (session) => session.send('greetings')) 37 | .triggerAction({ matches: 'Greeting' }) 38 | 39 | bot.dialog('/leave', (session) => session.send('leave')) 40 | .triggerAction({ matches: 'Leave' }) 41 | 42 | bot.dialog('/none', (session) => session.send('dont_understand_you')) 43 | .triggerAction({ matches: 'None' }) 44 | } 45 | 46 | module.exports = { 47 | initialize: _initialize 48 | } -------------------------------------------------------------------------------- /src/nodejs/iisnode.yml: -------------------------------------------------------------------------------- 1 | nodeProcessCommandLine: "D:\Program Files (x86)\nodejs\6.9.1\node.exe" -------------------------------------------------------------------------------- /src/nodejs/locale/en/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "greeting": "Welcome!", 3 | "instructions": "This demo is a template to create your own bots!", 4 | "select_demo": "Select a demo", 5 | "request_name": "Hello human, what's your name?", 6 | "years_coding": "How many years have you been coding?", 7 | "preferred_language": "What's your preferred language?", 8 | "programming_years_lang": "Ok %s, you've been programming for %s years and using %s", 9 | "change_language": "Change lenguage", 10 | "request_info": "Request info", 11 | "language_selected": "Your preferred language is now %s", 12 | "must_select_option": "You must select an option", 13 | "language_processing": "Language processing", 14 | "greetings": [ 15 | "Hi there!", 16 | "Hey human!", 17 | "Hi human!", 18 | "No time to explain, give me your money!", 19 | "Oh shit... Ok. Now tell me you're bored, and ask what's up.", 20 | "Luke, I am Your Father!!" 21 | ], 22 | "leave": [ 23 | "Good luck!", 24 | "Can't escape me. Muahaha", 25 | "I will really miss you!", 26 | "Best of Luck!", 27 | "Have a prosperous life and keep in touch!", 28 | "It may be hard to say good bye. But the good with it is a promise of something better", 29 | "Good luck in the future, and please stay in touch", 30 | "Goodbye my human friend", 31 | "I am currently out at a bot job interview and will reply to you if I fail to get the position", 32 | "The bot server is unable to verify your server connection and is unable to deliver this message. Please restart your computer and try sending again" 33 | ], 34 | "enable_luis": "Enable LUIS", 35 | "luis_enabled": "LUIS enabled, you can say hi! (exit to disable)", 36 | "dont_understand_you": "I don't understand you, what do you want?", 37 | "movie_selected": "The user want's to see the movie: %s" 38 | } -------------------------------------------------------------------------------- /src/nodejs/locale/es/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "greeting": "Bienvenido!", 3 | "instructions": "Este demo es un template para crear tus propios bots!", 4 | "select_demo": "Seleccionar un demo", 5 | "request_name": "Hola humano, cuál es tu nombre?", 6 | "years_coding": "Cuántos años has estado codificando?", 7 | "preferred_language": "Cuál es tú lenguaje preferido?", 8 | "programming_years_lang": "Ok %s, tú has estado programando por %s años y usando %s", 9 | "change_language": "Cambiar lenguaje", 10 | "request_info": "Solicitar info", 11 | "language_selected": "Su idioma preferido es ahora %s", 12 | "must_select_option": "Debe seleccionar una opción", 13 | "language_processing": "Procesamiento de lenguaje", 14 | "greetings": [ 15 | "Hola humano!", 16 | "Hola terrícola!", 17 | "Ok... estás aburrido y quieres un abrazo de robot?", 18 | "Para qué me despertaste? Escribe rápido o déjame seguir soñando que estaba conquistando al mundo!" 19 | ], 20 | "leave": [ 21 | "No puedes escapar. Muajaja", 22 | "Buena suerte!", 23 | "Realmente te extrañaré", 24 | "La mejor de las suertes!", 25 | "Ten una vida próspera y mantente en contacto!", 26 | "Adiós mi amigo humano", 27 | "Actualmente estoy en una entrevista de trabajo de bots y le responderé si no logro obtener el puesto" 28 | ], 29 | "enable_luis": "Habilitar LUIS", 30 | "luis_enabled": "LUIS habilitado, puedes saludar! (exit para deshabilitar)", 31 | "dont_understand_you": "No te entiendo, qué quieres?", 32 | "movie_selected": "El usuario quiere ver la película: %s" 33 | } -------------------------------------------------------------------------------- /src/nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mybot", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node server.js" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.17.1", 10 | "botbuilder": "^3.13.1", 11 | "botbuilder-azure": "^3.0.4", 12 | "chalk": "^2.3.2", 13 | "cookie-parser": "~1.4.3", 14 | "debug": "~2.6.3", 15 | "ejs": "^2.5.8", 16 | "express": "~4.15.2", 17 | "jade": "~1.11.0", 18 | "lodash": "^4.17.5", 19 | "morgan": "~1.8.1", 20 | "require-all": "^2.2.0", 21 | "serve-favicon": "~2.4.2", 22 | "swagger-ui-express": "^3.0.6", 23 | "yamljs": "^0.3.0" 24 | }, 25 | "devDependencies": { 26 | "request": "^2.81.0", 27 | "zip-folder": "^1.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/nodejs/publish.js: -------------------------------------------------------------------------------- 1 | var zipFolder = require('zip-folder'); 2 | var path = require('path'); 3 | var fs = require('fs'); 4 | var request = require('request'); 5 | 6 | var rootFolder = path.resolve('.'); 7 | var zipPath = path.resolve(rootFolder, '../bot26.zip'); 8 | var kuduApi = 'https://bot26.scm.azurewebsites.net/api/zip/site/wwwroot'; 9 | var userName = '$bot26'; 10 | var password = 'YgSgcmu9bpfuzgnepWyPNEaR6fZcBgEqGXTvi8gDy1quw9KLD9p9x8rHHgJq'; 11 | 12 | function uploadZip(callback) { 13 | fs.createReadStream(zipPath).pipe(request.put(kuduApi, { 14 | auth: { 15 | username: userName, 16 | password: password, 17 | sendImmediately: true 18 | }, 19 | headers: { 20 | "Content-Type": "applicaton/zip" 21 | } 22 | })) 23 | .on('response', function(resp){ 24 | if (resp.statusCode >= 200 && resp.statusCode < 300) { 25 | fs.unlink(zipPath); 26 | callback(null); 27 | } else if (resp.statusCode >= 400) { 28 | callback(resp); 29 | } 30 | }) 31 | .on('error', function(err) { 32 | callback(err) 33 | }); 34 | } 35 | 36 | function publish(callback) { 37 | zipFolder(rootFolder, zipPath, function(err) { 38 | if (!err) { 39 | uploadZip(callback); 40 | } else { 41 | callback(err); 42 | } 43 | }) 44 | } 45 | 46 | publish(function(err) { 47 | if (!err) { 48 | console.log('bot26 publish'); 49 | } else { 50 | console.error('failed to publish bot26', err); 51 | } 52 | }); -------------------------------------------------------------------------------- /src/nodejs/routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.redirect('/api/help'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /src/nodejs/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.json([ 7 | { name: 'Juan David Nicholls Cardona' } 8 | ]); 9 | }); 10 | 11 | module.exports = router; 12 | -------------------------------------------------------------------------------- /src/nodejs/server.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('./app'); 8 | var debug = require('debug')('nodejs:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.port || process.env.PORT || 3978); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /src/nodejs/swagger.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | description: "This is a sample server Bot Framework server." 4 | version: "1.0.0" 5 | title: "My Bot" 6 | contact: 7 | email: "jdnichollsc@hotmail.com" 8 | host: "mybot.mydomain.com" 9 | basePath: "/api" 10 | tags: 11 | - name: "messages" 12 | description: "Comunication with the bot" 13 | externalDocs: 14 | description: "Find out more" 15 | url: "https://github.com/proyecto26/Bot-Framework" 16 | - name: "users" 17 | description: "Other endpoints of my service" 18 | schemes: 19 | - "http" 20 | paths: 21 | /messages: 22 | post: 23 | tags: 24 | - "messages" 25 | summary: "Listen for messages from users" 26 | description: "" 27 | operationId: "bot" 28 | consumes: 29 | - "application/json" 30 | produces: 31 | - "application/json" 32 | responses: 33 | 200: 34 | description: "Message sent" 35 | /users: 36 | get: 37 | tags: 38 | - "users" 39 | summary: "List the users" 40 | description: "" 41 | operationId: "getUsers" 42 | consumes: 43 | - "application/json" 44 | produces: 45 | - "application/json" 46 | responses: 47 | 200: 48 | description: "successful operation" 49 | schema: 50 | type: "array" 51 | items: 52 | $ref: "#/definitions/User" 53 | definitions: 54 | User: 55 | type: "object" 56 | properties: 57 | id: 58 | type: "integer" 59 | format: "int64" 60 | username: 61 | type: "string" 62 | firstName: 63 | type: "string" 64 | lastName: 65 | type: "string" 66 | email: 67 | type: "string" 68 | password: 69 | type: "string" 70 | phone: 71 | type: "string" 72 | userStatus: 73 | type: "integer" 74 | format: "int32" 75 | description: "User Status" 76 | xml: 77 | name: "User" -------------------------------------------------------------------------------- /src/nodejs/views/error.ejs: -------------------------------------------------------------------------------- 1 |

2 | <%= message %> 3 |

4 |

<%= error.status %>

5 |
<%= error.stack %>
-------------------------------------------------------------------------------- /src/nodejs/web.config: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 59 | 60 | 61 | 62 | --------------------------------------------------------------------------------