Sample Code (#1136)
This commit is contained in:
Родитель
30ac79513a
Коммит
3041eca54d
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"java.configuration.updateBuildConfiguration": "automatic"
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
|
@ -0,0 +1,103 @@
|
|||
# NLP with Dispatch
|
||||
|
||||
Bot Framework v4 NLP with Dispatch bot sample
|
||||
|
||||
This bot has been created using [Bot Framework](https://dev.botframework.com), it shows how to create a bot that relies on multiple [LUIS.ai](https://www.luis.ai) and [QnAMaker.ai](https://www.qnamaker.ai) models for natural language processing (NLP).
|
||||
|
||||
Use the Dispatch model in cases when:
|
||||
|
||||
- Your bot consists of multiple language modules (LUIS + QnA) and you need assistance in routing user's utterances to these modules in order to integrate the different modules into your bot.
|
||||
- Evaluate quality of intents classification of a single LUIS model.
|
||||
- Create a text classification model from text files.
|
||||
|
||||
This sample is a Spring Boot app and uses the Azure CLI and azure-webapp Maven plugin to deploy to Azure.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Java 1.8+
|
||||
- Install [Maven](https://maven.apache.org/)
|
||||
- An account on [Azure](https://azure.microsoft.com) if you want to deploy to Azure.
|
||||
|
||||
### Use Dispatch with Multiple LUIS and QnA Models
|
||||
|
||||
To learn how to configure Dispatch with multiple LUIS models and QnA Maker services, refer to the steps found [here](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-tutorial-dispatch?view=azure-bot-service-4.0).
|
||||
|
||||
|
||||
## To try this sample locally
|
||||
- From the root of this project folder:
|
||||
- Build the sample using `mvn package`
|
||||
- Run it by using `java -jar .\target\nlp-with-dispatch-sample.jar`
|
||||
|
||||
- Test the bot using Bot Framework Emulator
|
||||
|
||||
[Bot Framework Emulator](https://github.com/microsoft/botframework-emulator) 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.3.0 or greater from [here](https://github.com/Microsoft/BotFramework-Emulator/releases)
|
||||
|
||||
- Connect to the bot using Bot Framework Emulator
|
||||
|
||||
- Launch Bot Framework Emulator
|
||||
- File -> Open Bot
|
||||
- Enter a Bot URL of `http://localhost:3978/api/messages`
|
||||
|
||||
## Deploy the bot to Azure
|
||||
|
||||
As described on [Deploy your bot](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-deploy-az-cli), you will perform the first 4 steps to setup the Azure app, then deploy the code using the azure-webapp Maven plugin.
|
||||
|
||||
### 1. Login to Azure
|
||||
From a command (or PowerShell) prompt in the root of the bot folder, execute:
|
||||
`az login`
|
||||
|
||||
### 2. Set the subscription
|
||||
`az account set --subscription "<azure-subscription>"`
|
||||
|
||||
If you aren't sure which subscription to use for deploying the bot, you can view the list of subscriptions for your account by using `az account list` command.
|
||||
|
||||
### 3. Create an App registration
|
||||
`az ad app create --display-name "<botname>" --password "<appsecret>" --available-to-other-tenants`
|
||||
|
||||
Replace `<botname>` and `<appsecret>` with your own values.
|
||||
|
||||
`<botname>` is the unique name of your bot.
|
||||
`<appsecret>` is a minimum 16 character password for your bot.
|
||||
|
||||
Record the `appid` from the returned JSON
|
||||
|
||||
### 4. Create the Azure resources
|
||||
Replace the values for `<appid>`, `<appsecret>`, `<botname>`, and `<groupname>` in the following commands:
|
||||
|
||||
#### To a new Resource Group
|
||||
`az deployment sub create --name "echoBotDeploy" --location "westus" --template-file ".\deploymentTemplates\template-with-new-rg.json" --parameters appId="<appid>" appSecret="<appsecret>" botId="<botname>" botSku=S1 newAppServicePlanName="echoBotPlan" newWebAppName="echoBot" groupLocation="westus" newAppServicePlanLocation="westus"`
|
||||
|
||||
#### To an existing Resource Group
|
||||
`az deployment group create --resource-group "<groupname>" --template-file ".\deploymentTemplates\template-with-preexisting-rg.json" --parameters appId="<appid>" appSecret="<appsecret>" botId="<botname>" newWebAppName="echoBot" newAppServicePlanName="echoBotPlan" appServicePlanLocation="westus" --name "echoBot"`
|
||||
|
||||
### 5. Update app id and password
|
||||
In src/main/resources/application.properties update
|
||||
- `MicrosoftAppPassword` with the botsecret value
|
||||
- `MicrosoftAppId` with the appid from the first step
|
||||
|
||||
### 6. Deploy the code
|
||||
- Execute `mvn clean package`
|
||||
- Execute `mvn azure-webapp:deploy -Dgroupname="<groupname>" -Dbotname="<botname>"`
|
||||
|
||||
If the deployment is successful, you will be able to test it via "Test in Web Chat" from the Azure Portal using the "Bot Channel Registration" for the bot.
|
||||
|
||||
After the bot is deployed, you only need to execute #6 if you make changes to the bot.
|
||||
|
||||
|
||||
## Further reading
|
||||
|
||||
- [Bot Framework Documentation](https://docs.botframework.com)
|
||||
- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0)
|
||||
- [Using LUIS for Language Understanding](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-howto-v4-luis?view=azure-bot-service-4.0&tabs=js)
|
||||
- [LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/LUIS/)
|
||||
- [Activity processing](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-concept-activity-processing?view=azure-bot-service-4.0)
|
||||
- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0)
|
||||
- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0)
|
||||
- [.NET Core CLI tools](https://docs.microsoft.com/en-us/dotnet/core/tools/?tabs=netcore2x)
|
||||
- [Azure CLI](https://docs.microsoft.com/cli/azure/?view=azure-cli-latest)
|
||||
- [Azure Portal](https://portal.azure.com)
|
||||
- [Language Understanding using LUIS](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/)
|
||||
- [Channels and Bot Connector Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-concepts?view=azure-bot-service-4.0)
|
||||
|
|
@ -0,0 +1,291 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"groupLocation": {
|
||||
"defaultValue": "",
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Specifies the location of the Resource Group."
|
||||
}
|
||||
},
|
||||
"groupName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Specifies the name of the Resource Group."
|
||||
}
|
||||
},
|
||||
"appId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings."
|
||||
}
|
||||
},
|
||||
"appSecret": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings."
|
||||
}
|
||||
},
|
||||
"botId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable."
|
||||
}
|
||||
},
|
||||
"botSku": {
|
||||
"defaultValue": "S1",
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1."
|
||||
}
|
||||
},
|
||||
"newAppServicePlanName": {
|
||||
"defaultValue": "",
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The name of the App Service Plan."
|
||||
}
|
||||
},
|
||||
"newAppServicePlanSku": {
|
||||
"type": "object",
|
||||
"defaultValue": {
|
||||
"name": "P1v2",
|
||||
"tier": "PremiumV2",
|
||||
"size": "P1v2",
|
||||
"family": "Pv2",
|
||||
"capacity": 1
|
||||
},
|
||||
"metadata": {
|
||||
"description": "The SKU of the App Service Plan. Defaults to Standard values."
|
||||
}
|
||||
},
|
||||
"newAppServicePlanLocation": {
|
||||
"defaultValue": "",
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The location of the App Service Plan. Defaults to \"westus\"."
|
||||
}
|
||||
},
|
||||
"newWebAppName": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"appServicePlanName": "[parameters('newAppServicePlanName')]",
|
||||
"resourcesLocation": "[parameters('newAppServicePlanLocation')]",
|
||||
"webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]",
|
||||
"siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]",
|
||||
"botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]",
|
||||
"publishingUsername": "[concat('$', parameters('newWebAppName'))]",
|
||||
"resourceGroupId": "[concat(subscription().id, '/resourceGroups/', parameters('groupName'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"name": "[parameters('groupName')]",
|
||||
"type": "Microsoft.Resources/resourceGroups",
|
||||
"apiVersion": "2018-05-01",
|
||||
"location": "[parameters('groupLocation')]",
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Resources/deployments",
|
||||
"apiVersion": "2018-05-01",
|
||||
"name": "storageDeployment",
|
||||
"resourceGroup": "[parameters('groupName')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"mode": "Incremental",
|
||||
"template": {
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {},
|
||||
"variables": {},
|
||||
"resources": [
|
||||
{
|
||||
"comments": "Create a new Linux App Service Plan if no existing App Service Plan name was passed in.",
|
||||
"type": "Microsoft.Web/serverfarms",
|
||||
"name": "[variables('appServicePlanName')]",
|
||||
"apiVersion": "2018-02-01",
|
||||
"location": "[variables('resourcesLocation')]",
|
||||
"sku": "[parameters('newAppServicePlanSku')]",
|
||||
"kind": "linux",
|
||||
"properties": {
|
||||
"perSiteScaling": false,
|
||||
"maximumElasticWorkerCount": 1,
|
||||
"isSpot": false,
|
||||
"reserved": true,
|
||||
"isXenon": false,
|
||||
"hyperV": false,
|
||||
"targetWorkerCount": 0,
|
||||
"targetWorkerSizeId": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"comments": "Create a Web App using a Linux App Service Plan",
|
||||
"type": "Microsoft.Web/sites",
|
||||
"apiVersion": "2018-11-01",
|
||||
"location": "[variables('resourcesLocation')]",
|
||||
"kind": "app,linux",
|
||||
"dependsOn": [
|
||||
"[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]"
|
||||
],
|
||||
"name": "[variables('webAppName')]",
|
||||
"properties": {
|
||||
"name": "[variables('webAppName')]",
|
||||
"hostNameSslStates": [
|
||||
{
|
||||
"name": "[concat(parameters('newWebAppName'), '.azurewebsites.net')]",
|
||||
"sslState": "Disabled",
|
||||
"hostType": "Standard"
|
||||
},
|
||||
{
|
||||
"name": "[concat(parameters('newWebAppName'), '.scm.azurewebsites.net')]",
|
||||
"sslState": "Disabled",
|
||||
"hostType": "Repository"
|
||||
}
|
||||
],
|
||||
"serverFarmId": "[variables('appServicePlanName')]",
|
||||
"reserved": true,
|
||||
"isXenon": false,
|
||||
"hyperV": false,
|
||||
"scmSiteAlsoStopped": false,
|
||||
"clientAffinityEnabled": true,
|
||||
"clientCertEnabled": false,
|
||||
"hostNamesDisabled": false,
|
||||
"containerSize": 0,
|
||||
"dailyMemoryTimeQuota": 0,
|
||||
"httpsOnly": false,
|
||||
"redundancyMode": "None",
|
||||
"siteConfig": {
|
||||
"appSettings": [
|
||||
{
|
||||
"name": "JAVA_OPTS",
|
||||
"value": "-Dserver.port=80"
|
||||
},
|
||||
{
|
||||
"name": "MicrosoftAppId",
|
||||
"value": "[parameters('appId')]"
|
||||
},
|
||||
{
|
||||
"name": "MicrosoftAppPassword",
|
||||
"value": "[parameters('appSecret')]"
|
||||
}
|
||||
],
|
||||
"cors": {
|
||||
"allowedOrigins": [
|
||||
"https://botservice.hosting.portal.azure.net",
|
||||
"https://hosting.onecloud.azure-test.net/"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Web/sites/config",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[concat(variables('webAppName'), '/web')]",
|
||||
"location": "[variables('resourcesLocation')]",
|
||||
"dependsOn": [
|
||||
"[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/sites/', variables('webAppName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"numberOfWorkers": 1,
|
||||
"defaultDocuments": [
|
||||
"Default.htm",
|
||||
"Default.html",
|
||||
"Default.asp",
|
||||
"index.htm",
|
||||
"index.html",
|
||||
"iisstart.htm",
|
||||
"default.aspx",
|
||||
"index.php",
|
||||
"hostingstart.html"
|
||||
],
|
||||
"netFrameworkVersion": "v4.0",
|
||||
"linuxFxVersion": "JAVA|8-jre8",
|
||||
"requestTracingEnabled": false,
|
||||
"remoteDebuggingEnabled": false,
|
||||
"httpLoggingEnabled": false,
|
||||
"logsDirectorySizeLimit": 35,
|
||||
"detailedErrorLoggingEnabled": false,
|
||||
"publishingUsername": "[variables('publishingUsername')]",
|
||||
"scmType": "None",
|
||||
"use32BitWorkerProcess": true,
|
||||
"webSocketsEnabled": false,
|
||||
"alwaysOn": true,
|
||||
"managedPipelineMode": "Integrated",
|
||||
"virtualApplications": [
|
||||
{
|
||||
"virtualPath": "/",
|
||||
"physicalPath": "site\\wwwroot",
|
||||
"preloadEnabled": true
|
||||
}
|
||||
],
|
||||
"loadBalancing": "LeastRequests",
|
||||
"experiments": {
|
||||
"rampUpRules": []
|
||||
},
|
||||
"autoHealEnabled": false,
|
||||
"localMySqlEnabled": false,
|
||||
"ipSecurityRestrictions": [
|
||||
{
|
||||
"ipAddress": "Any",
|
||||
"action": "Allow",
|
||||
"priority": 1,
|
||||
"name": "Allow all",
|
||||
"description": "Allow all access"
|
||||
}
|
||||
],
|
||||
"scmIpSecurityRestrictions": [
|
||||
{
|
||||
"ipAddress": "Any",
|
||||
"action": "Allow",
|
||||
"priority": 1,
|
||||
"name": "Allow all",
|
||||
"description": "Allow all access"
|
||||
}
|
||||
],
|
||||
"scmIpSecurityRestrictionsUseMain": false,
|
||||
"http20Enabled": false,
|
||||
"minTlsVersion": "1.2",
|
||||
"ftpsState": "AllAllowed",
|
||||
"reservedInstanceCount": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2017-12-01",
|
||||
"type": "Microsoft.BotService/botServices",
|
||||
"name": "[parameters('botId')]",
|
||||
"location": "global",
|
||||
"kind": "bot",
|
||||
"sku": {
|
||||
"name": "[parameters('botSku')]"
|
||||
},
|
||||
"properties": {
|
||||
"name": "[parameters('botId')]",
|
||||
"displayName": "[parameters('botId')]",
|
||||
"endpoint": "[variables('botEndpoint')]",
|
||||
"msaAppId": "[parameters('appId')]",
|
||||
"developerAppInsightsApplicationId": null,
|
||||
"developerAppInsightKey": null,
|
||||
"publishingCredentials": null,
|
||||
"storageResourceId": null
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/sites/', variables('webAppName'))]"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,259 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"appId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings."
|
||||
}
|
||||
},
|
||||
"appSecret": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Defaults to \"\"."
|
||||
}
|
||||
},
|
||||
"botId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable."
|
||||
}
|
||||
},
|
||||
"botSku": {
|
||||
"defaultValue": "S1",
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1."
|
||||
}
|
||||
},
|
||||
"newAppServicePlanName": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "The name of the new App Service Plan."
|
||||
}
|
||||
},
|
||||
"newAppServicePlanSku": {
|
||||
"type": "object",
|
||||
"defaultValue": {
|
||||
"name": "P1v2",
|
||||
"tier": "PremiumV2",
|
||||
"size": "P1v2",
|
||||
"family": "Pv2",
|
||||
"capacity": 1
|
||||
},
|
||||
"metadata": {
|
||||
"description": "The SKU of the App Service Plan. Defaults to Standard values."
|
||||
}
|
||||
},
|
||||
"appServicePlanLocation": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "The location of the App Service Plan."
|
||||
}
|
||||
},
|
||||
"existingAppServicePlan": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "Name of the existing App Service Plan used to create the Web App for the bot."
|
||||
}
|
||||
},
|
||||
"newWebAppName": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"defaultAppServicePlanName": "[if(empty(parameters('existingAppServicePlan')), 'createNewAppServicePlan', parameters('existingAppServicePlan'))]",
|
||||
"useExistingAppServicePlan": "[not(equals(variables('defaultAppServicePlanName'), 'createNewAppServicePlan'))]",
|
||||
"servicePlanName": "[if(variables('useExistingAppServicePlan'), parameters('existingAppServicePlan'), parameters('newAppServicePlanName'))]",
|
||||
"publishingUsername": "[concat('$', parameters('newWebAppName'))]",
|
||||
"resourcesLocation": "[parameters('appServicePlanLocation')]",
|
||||
"webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]",
|
||||
"siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]",
|
||||
"botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"comments": "Create a new Linux App Service Plan if no existing App Service Plan name was passed in.",
|
||||
"type": "Microsoft.Web/serverfarms",
|
||||
"condition": "[not(variables('useExistingAppServicePlan'))]",
|
||||
"name": "[variables('servicePlanName')]",
|
||||
"apiVersion": "2018-02-01",
|
||||
"location": "[variables('resourcesLocation')]",
|
||||
"sku": "[parameters('newAppServicePlanSku')]",
|
||||
"kind": "linux",
|
||||
"properties": {
|
||||
"perSiteScaling": false,
|
||||
"maximumElasticWorkerCount": 1,
|
||||
"isSpot": false,
|
||||
"reserved": true,
|
||||
"isXenon": false,
|
||||
"hyperV": false,
|
||||
"targetWorkerCount": 0,
|
||||
"targetWorkerSizeId": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"comments": "Create a Web App using a Linux App Service Plan",
|
||||
"type": "Microsoft.Web/sites",
|
||||
"apiVersion": "2018-11-01",
|
||||
"location": "[variables('resourcesLocation')]",
|
||||
"kind": "app,linux",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]"
|
||||
],
|
||||
"name": "[variables('webAppName')]",
|
||||
"properties": {
|
||||
"name": "[variables('webAppName')]",
|
||||
"hostNameSslStates": [
|
||||
{
|
||||
"name": "[concat(parameters('newWebAppName'), '.azurewebsites.net')]",
|
||||
"sslState": "Disabled",
|
||||
"hostType": "Standard"
|
||||
},
|
||||
{
|
||||
"name": "[concat(parameters('newWebAppName'), '.scm.azurewebsites.net')]",
|
||||
"sslState": "Disabled",
|
||||
"hostType": "Repository"
|
||||
}
|
||||
],
|
||||
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]",
|
||||
"reserved": true,
|
||||
"isXenon": false,
|
||||
"hyperV": false,
|
||||
"scmSiteAlsoStopped": false,
|
||||
"clientAffinityEnabled": true,
|
||||
"clientCertEnabled": false,
|
||||
"hostNamesDisabled": false,
|
||||
"containerSize": 0,
|
||||
"dailyMemoryTimeQuota": 0,
|
||||
"httpsOnly": false,
|
||||
"redundancyMode": "None",
|
||||
"siteConfig": {
|
||||
"appSettings": [
|
||||
{
|
||||
"name": "JAVA_OPTS",
|
||||
"value": "-Dserver.port=80"
|
||||
},
|
||||
{
|
||||
"name": "MicrosoftAppId",
|
||||
"value": "[parameters('appId')]"
|
||||
},
|
||||
{
|
||||
"name": "MicrosoftAppPassword",
|
||||
"value": "[parameters('appSecret')]"
|
||||
}
|
||||
],
|
||||
"cors": {
|
||||
"allowedOrigins": [
|
||||
"https://botservice.hosting.portal.azure.net",
|
||||
"https://hosting.onecloud.azure-test.net/"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Web/sites/config",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[concat(variables('webAppName'), '/web')]",
|
||||
"location": "[variables('resourcesLocation')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Web/sites/', variables('webAppName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"numberOfWorkers": 1,
|
||||
"defaultDocuments": [
|
||||
"Default.htm",
|
||||
"Default.html",
|
||||
"Default.asp",
|
||||
"index.htm",
|
||||
"index.html",
|
||||
"iisstart.htm",
|
||||
"default.aspx",
|
||||
"index.php",
|
||||
"hostingstart.html"
|
||||
],
|
||||
"netFrameworkVersion": "v4.0",
|
||||
"linuxFxVersion": "JAVA|8-jre8",
|
||||
"requestTracingEnabled": false,
|
||||
"remoteDebuggingEnabled": false,
|
||||
"httpLoggingEnabled": false,
|
||||
"logsDirectorySizeLimit": 35,
|
||||
"detailedErrorLoggingEnabled": false,
|
||||
"publishingUsername": "[variables('publishingUsername')]",
|
||||
"scmType": "None",
|
||||
"use32BitWorkerProcess": true,
|
||||
"webSocketsEnabled": false,
|
||||
"alwaysOn": true,
|
||||
"managedPipelineMode": "Integrated",
|
||||
"virtualApplications": [
|
||||
{
|
||||
"virtualPath": "/",
|
||||
"physicalPath": "site\\wwwroot",
|
||||
"preloadEnabled": true
|
||||
}
|
||||
],
|
||||
"loadBalancing": "LeastRequests",
|
||||
"experiments": {
|
||||
"rampUpRules": []
|
||||
},
|
||||
"autoHealEnabled": false,
|
||||
"localMySqlEnabled": false,
|
||||
"ipSecurityRestrictions": [
|
||||
{
|
||||
"ipAddress": "Any",
|
||||
"action": "Allow",
|
||||
"priority": 1,
|
||||
"name": "Allow all",
|
||||
"description": "Allow all access"
|
||||
}
|
||||
],
|
||||
"scmIpSecurityRestrictions": [
|
||||
{
|
||||
"ipAddress": "Any",
|
||||
"action": "Allow",
|
||||
"priority": 1,
|
||||
"name": "Allow all",
|
||||
"description": "Allow all access"
|
||||
}
|
||||
],
|
||||
"scmIpSecurityRestrictionsUseMain": false,
|
||||
"http20Enabled": false,
|
||||
"minTlsVersion": "1.2",
|
||||
"ftpsState": "AllAllowed",
|
||||
"reservedInstanceCount": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2017-12-01",
|
||||
"type": "Microsoft.BotService/botServices",
|
||||
"name": "[parameters('botId')]",
|
||||
"location": "global",
|
||||
"kind": "bot",
|
||||
"sku": {
|
||||
"name": "[parameters('botSku')]"
|
||||
},
|
||||
"properties": {
|
||||
"name": "[parameters('botId')]",
|
||||
"displayName": "[parameters('botId')]",
|
||||
"endpoint": "[variables('botEndpoint')]",
|
||||
"msaAppId": "[parameters('appId')]",
|
||||
"developerAppInsightsApplicationId": null,
|
||||
"developerAppInsightKey": null,
|
||||
"publishingCredentials": null,
|
||||
"storageResourceId": null
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Web/sites/', variables('webAppName'))]"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,248 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.microsoft.bot.sample</groupId>
|
||||
<artifactId>nlp-with-dispatch</artifactId>
|
||||
<version>sample</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.groupId}:${project.artifactId}</name>
|
||||
<description>This package contains a Java NLP with Dispatch sample using Spring Boot.</description>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>MIT License</name>
|
||||
<url>http://www.opensource.org/licenses/mit-license.php</url>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>Bot Framework Development</name>
|
||||
<email></email>
|
||||
<organization>Microsoft</organization>
|
||||
<organizationUrl>https://dev.botframework.com/</organizationUrl>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<start-class>com.microsoft.bot.sample.nlpwithdispatch.Application</start-class>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.13.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>bot-integration-spring</artifactId>
|
||||
<version>4.6.0-preview9</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>bot-ai-luis-v3</artifactId>
|
||||
<version>4.6.0-preview9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>bot-ai-qna</artifactId>
|
||||
<version>4.6.0-preview9</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>build</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.2.3</version>
|
||||
<configuration>
|
||||
<warSourceDirectory>src/main/webapp</warSourceDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<mainClass>com.microsoft.bot.sample.nlpwithdispatch.Application</mainClass>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.microsoft.azure</groupId>
|
||||
<artifactId>azure-webapp-maven-plugin</artifactId>
|
||||
<version>1.12.0</version>
|
||||
<configuration>
|
||||
<schemaVersion>V2</schemaVersion>
|
||||
<resourceGroup>${groupname}</resourceGroup>
|
||||
<appName>${botname}</appName>
|
||||
<appSettings>
|
||||
<property>
|
||||
<name>JAVA_OPTS</name>
|
||||
<value>-Dserver.port=80</value>
|
||||
</property>
|
||||
</appSettings>
|
||||
<runtime>
|
||||
<os>linux</os>
|
||||
<javaVersion>Java 8</javaVersion>
|
||||
<webContainer>Java SE</webContainer>
|
||||
</runtime>
|
||||
<deployment>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${project.basedir}/target</directory>
|
||||
<includes>
|
||||
<include>*.jar</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</deployment>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>publish</id>
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.2.3</version>
|
||||
<configuration>
|
||||
<warSourceDirectory>src/main/webapp</warSourceDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
<version>1.6.8</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<skipRemoteStaging>true</skipRemoteStaging>
|
||||
<serverId>ossrh</serverId>
|
||||
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
|
||||
<autoReleaseAfterClose>true</autoReleaseAfterClose>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<failOnError>false</failOnError>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.sample.nlpwithdispatch;
|
||||
|
||||
import com.microsoft.bot.builder.Bot;
|
||||
import com.microsoft.bot.integration.AdapterWithErrorHandler;
|
||||
import com.microsoft.bot.integration.BotFrameworkHttpAdapter;
|
||||
import com.microsoft.bot.integration.Configuration;
|
||||
import com.microsoft.bot.integration.spring.BotController;
|
||||
import com.microsoft.bot.integration.spring.BotDependencyConfiguration;
|
||||
import com.microsoft.bot.sample.nlpwithdispatch.bots.DispatchBot;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
//
|
||||
// This is the starting point of the Sprint Boot Bot application.
|
||||
//
|
||||
@SpringBootApplication
|
||||
|
||||
// Use the default BotController to receive incoming Channel messages. A custom
|
||||
// controller could be used by eliminating this import and creating a new
|
||||
// org.springframework.web.bind.annotation.RestController.
|
||||
// The default controller is created by the Spring Boot container using
|
||||
// dependency injection. The default route is /api/messages.
|
||||
@Import({BotController.class})
|
||||
|
||||
/**
|
||||
* This class extends the BotDependencyConfiguration which provides the default
|
||||
* implementations for a Bot application. The Application class should
|
||||
* override methods in order to provide custom implementations.
|
||||
*/
|
||||
public class Application extends BotDependencyConfiguration {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Bot for this application.
|
||||
*
|
||||
* <p>
|
||||
* The @Component annotation could be used on the Bot class instead of this method
|
||||
* with the @Bean annotation.
|
||||
* </p>
|
||||
*
|
||||
* @return The Bot implementation for this application.
|
||||
*/
|
||||
@Bean
|
||||
public Bot getBot(BotServices botServices) {
|
||||
return new DispatchBot(botServices);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BotServices getBotServices(Configuration configuration) {
|
||||
return new BotServicesImpl(configuration);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a custom Adapter that provides error handling.
|
||||
*
|
||||
* @param configuration The Configuration object to use.
|
||||
* @return An error handling BotFrameworkHttpAdapter.
|
||||
*/
|
||||
@Override
|
||||
public BotFrameworkHttpAdapter getBotFrameworkHttpAdaptor(Configuration configuration) {
|
||||
return new AdapterWithErrorHandler(configuration);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.microsoft.bot.sample.nlpwithdispatch;
|
||||
|
||||
import com.microsoft.bot.ai.luis.LuisRecognizer;
|
||||
import com.microsoft.bot.ai.qna.QnAMaker;
|
||||
|
||||
public interface BotServices {
|
||||
|
||||
LuisRecognizer getDispatch();
|
||||
|
||||
QnAMaker getSampleQnA();
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
package com.microsoft.bot.sample.nlpwithdispatch;
|
||||
|
||||
import com.microsoft.bot.ai.luis.LuisApplication;
|
||||
import com.microsoft.bot.ai.luis.LuisRecognizer;
|
||||
import com.microsoft.bot.ai.luis.LuisRecognizerOptionsV3;
|
||||
import com.microsoft.bot.ai.qna.QnAMaker;
|
||||
import com.microsoft.bot.ai.qna.QnAMakerEndpoint;
|
||||
import com.microsoft.bot.integration.Configuration;
|
||||
|
||||
public class BotServicesImpl implements BotServices {
|
||||
|
||||
private LuisRecognizer dispatch;
|
||||
|
||||
private QnAMaker sampleQnA;
|
||||
|
||||
public BotServicesImpl(Configuration configuration) {
|
||||
// Read the setting for cognitive services (LUS, QnA) from the application.properties file.
|
||||
// If includeApiResults instanceof set to true, the full response from the LUS api (LuisResult)
|
||||
// will be made available in the properties collection of the RecognizerResult
|
||||
|
||||
LuisApplication luisApplication = new LuisApplication(
|
||||
configuration.getProperty("LuisAppId"),
|
||||
configuration.getProperty("LuisAPIKey"),
|
||||
String.format("https://%s.api.cognitive.microsoft.com",
|
||||
configuration.getProperty("LuisAPIHostName")));
|
||||
|
||||
// Set the recognizer options depending on which endpoint version you want to use.
|
||||
// More details can be found in https://docs.getmicrosoft().com/en-gb/azure/cognitive-services/luis/luis-migration-api-v3
|
||||
LuisRecognizerOptionsV3 recognizerOptions = new LuisRecognizerOptionsV3(luisApplication);
|
||||
recognizerOptions.setIncludeAPIResults(true);
|
||||
recognizerOptions.setIncludeAllIntents(true);
|
||||
recognizerOptions.setIncludeInstanceData(true);
|
||||
|
||||
dispatch = new LuisRecognizer(recognizerOptions);
|
||||
|
||||
QnAMakerEndpoint qnaMakerEndpoint = new QnAMakerEndpoint();
|
||||
qnaMakerEndpoint.setKnowledgeBaseId(configuration.getProperty("QnAKnowledgebaseId"));
|
||||
qnaMakerEndpoint.setEndpointKey(configuration.getProperty("QnAEndpointKey"));
|
||||
qnaMakerEndpoint.setHost(configuration.getProperty("QnAEndpointHostName"));
|
||||
|
||||
sampleQnA = new QnAMaker(qnaMakerEndpoint, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Dispatch value as a LuisRecognizer.
|
||||
*/
|
||||
public LuisRecognizer getDispatch() {
|
||||
return this.dispatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the SampleQnA value as a QnAMaker.
|
||||
*/
|
||||
public QnAMaker getSampleQnA() {
|
||||
return this.sampleQnA;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
package com.microsoft.bot.sample.nlpwithdispatch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Intent {
|
||||
private String name;
|
||||
private Double score;
|
||||
private List<Intent> childIntents;
|
||||
private String topIntent;
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Double getScore() {
|
||||
return this.score;
|
||||
}
|
||||
|
||||
public void setScore(Double score) {
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
public List<Intent> getChildIntents() {
|
||||
return this.childIntents;
|
||||
}
|
||||
|
||||
public void setChildIntents(List<Intent> childIntents) {
|
||||
this.childIntents = childIntents;
|
||||
}
|
||||
|
||||
public String getTopIntent() {
|
||||
return this.topIntent;
|
||||
}
|
||||
|
||||
public void setTopIntent(String topIntent) {
|
||||
this.topIntent = topIntent;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
package com.microsoft.bot.sample.nlpwithdispatch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PredictionResult {
|
||||
private String topIntent;
|
||||
private List<Intent> intents;
|
||||
|
||||
public String getTopIntent() {
|
||||
return this.topIntent;
|
||||
}
|
||||
|
||||
public void setTopIntent(String topIntent) {
|
||||
this.topIntent = topIntent;
|
||||
}
|
||||
|
||||
public List<Intent> getIntents() {
|
||||
return this.intents;
|
||||
}
|
||||
|
||||
public void setIntents(List<Intent> intents) {
|
||||
this.intents = intents;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,229 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
package com.microsoft.bot.sample.nlpwithdispatch.bots;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.codepoetics.protonpack.collectors.CompletableFutures;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.microsoft.bot.builder.ActivityHandler;
|
||||
import com.microsoft.bot.builder.MessageFactory;
|
||||
import com.microsoft.bot.builder.RecognizerResult;
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
import com.microsoft.bot.builder.RecognizerResult.NamedIntentScore;
|
||||
import com.microsoft.bot.sample.nlpwithdispatch.BotServices;
|
||||
import com.microsoft.bot.sample.nlpwithdispatch.Intent;
|
||||
import com.microsoft.bot.sample.nlpwithdispatch.PredictionResult;
|
||||
import com.microsoft.bot.schema.ChannelAccount;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class DispatchBot extends ActivityHandler {
|
||||
|
||||
private final Logger _logger;
|
||||
private final BotServices _botServices;
|
||||
|
||||
public DispatchBot(BotServices botServices) {
|
||||
_logger = LoggerFactory.getLogger(DispatchBot.class);
|
||||
_botServices = botServices;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Void> onMessageActivity(TurnContext turnContext) {
|
||||
// First, we use the dispatch model to determine which cognitive service (LUS or
|
||||
// QnA) to use.
|
||||
RecognizerResult recognizerResult = _botServices.getDispatch().recognize(turnContext).join();
|
||||
|
||||
// Top intent tell us which cognitive service to use.
|
||||
NamedIntentScore topIntent = recognizerResult.getTopScoringIntent();
|
||||
|
||||
// Next, we call the dispatcher with the top intent.
|
||||
return dispatchToTopIntent(turnContext, topIntent.intent, recognizerResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Void> onMembersAdded(List<ChannelAccount> membersAdded, TurnContext turnContext) {
|
||||
final String WelcomeText = "Type a greeting, or a question about the weather to get started.";
|
||||
|
||||
return membersAdded.stream()
|
||||
.filter(member -> !StringUtils.equals(member.getId(), turnContext.getActivity().getRecipient().getId()))
|
||||
.map(member -> {
|
||||
String msg = String.format("Welcome to Dispatch bot %s. %s", member.getName(), WelcomeText);
|
||||
return turnContext.sendActivity(MessageFactory.text(msg));
|
||||
})
|
||||
.collect(CompletableFutures.toFutureList())
|
||||
.thenApply(resourceResponses -> null);
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> dispatchToTopIntent(
|
||||
TurnContext turnContext,
|
||||
String intent,
|
||||
RecognizerResult recognizerResult
|
||||
) {
|
||||
switch (intent) {
|
||||
case "l_HomeAutomation":
|
||||
return processHomeAutomation(turnContext, recognizerResult);
|
||||
|
||||
case "l_Weather":
|
||||
return processWeather(turnContext, recognizerResult);
|
||||
|
||||
case "q_sample-qna":
|
||||
return processSampleQnA(turnContext);
|
||||
|
||||
default:
|
||||
_logger.info(String.format("Dispatch unrecognized intent: %s.", intent));
|
||||
return turnContext
|
||||
.sendActivity(MessageFactory.text(String.format("Dispatch unrecognized intent: %s.", intent)))
|
||||
.thenApply(result -> null);
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> processHomeAutomation(TurnContext turnContext, RecognizerResult luisResult) {
|
||||
_logger.info("ProcessHomeAutomationAsync");
|
||||
|
||||
// Retrieve LUIS result for Process Automation.
|
||||
PredictionResult predictionResult = mapPredictionResult(luisResult.getProperties().get("luisResult"));
|
||||
|
||||
Intent topIntent = predictionResult.getIntents().get(0);
|
||||
return turnContext
|
||||
.sendActivity(MessageFactory.text(String.format("HomeAutomation top intent %s.", topIntent.getTopIntent())))
|
||||
.thenCompose(sendResult -> {
|
||||
List<String> intents =
|
||||
topIntent.getChildIntents().stream().map(x -> x.getName()).collect(Collectors.toList());
|
||||
return turnContext
|
||||
.sendActivity(
|
||||
MessageFactory
|
||||
.text(String.format("HomeAutomation intents detected:\n\n%s", String.join("\n\n", intents)))
|
||||
)
|
||||
.thenCompose(nextSendResult -> {
|
||||
if (luisResult.getEntities() != null) {
|
||||
List<String> entities = mapEntities(luisResult.getEntities());
|
||||
if (entities.size() > 0) {
|
||||
return turnContext
|
||||
.sendActivity(
|
||||
MessageFactory.text(
|
||||
String.format(
|
||||
"HomeAutomation entities were found in the message:\n\n%s",
|
||||
String.join("\n\n", entities)
|
||||
)
|
||||
)
|
||||
)
|
||||
.thenApply(finalSendResult -> null);
|
||||
}
|
||||
}
|
||||
return CompletableFuture.completedFuture(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private List<String> mapEntities(JsonNode entityNode) {
|
||||
List<String> entities = new ArrayList<String>();
|
||||
for (Iterator<Map.Entry<String, JsonNode>> child = entityNode.fields(); child.hasNext();) {
|
||||
Map.Entry<String, JsonNode> childIntent = child.next();
|
||||
String childName = childIntent.getKey();
|
||||
if (!childName.startsWith("$")) {
|
||||
entities.add(childIntent.getValue().get(0).asText());
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
private PredictionResult mapPredictionResult(JsonNode luisResult) {
|
||||
JsonNode prediction = luisResult.get("prediction");
|
||||
JsonNode intentsObject = prediction.get("intents");
|
||||
if (intentsObject == null) {
|
||||
return null;
|
||||
}
|
||||
PredictionResult result = new PredictionResult();
|
||||
result.setTopIntent(prediction.get("topIntent").asText());
|
||||
List<Intent> intents = new ArrayList<Intent>();
|
||||
for (Iterator<Map.Entry<String, JsonNode>> it = intentsObject.fields(); it.hasNext();) {
|
||||
Map.Entry<String, JsonNode> intent = it.next();
|
||||
double score = intent.getValue().get("score").asDouble();
|
||||
String intentName = intent.getKey().replace(".", "_").replace(" ", "_");
|
||||
Intent newIntent = new Intent();
|
||||
newIntent.setName(intentName);
|
||||
newIntent.setScore(score);
|
||||
JsonNode childNode = intent.getValue().get("childApp");
|
||||
if (childNode != null) {
|
||||
newIntent.setTopIntent(childNode.get("topIntent").asText());
|
||||
List<Intent> childIntents = new ArrayList<Intent>();
|
||||
JsonNode childIntentNodes = childNode.get("intents");
|
||||
for (Iterator<Map.Entry<String, JsonNode>> child = childIntentNodes.fields(); child.hasNext();) {
|
||||
Map.Entry<String, JsonNode> childIntent = child.next();
|
||||
double childScore = childIntent.getValue().get("score").asDouble();
|
||||
String childIntentName = childIntent.getKey();
|
||||
Intent newChildIntent = new Intent();
|
||||
newChildIntent.setName(childIntentName);
|
||||
newChildIntent.setScore(childScore);
|
||||
childIntents.add(newChildIntent);
|
||||
}
|
||||
newIntent.setChildIntents(childIntents);
|
||||
}
|
||||
|
||||
intents.add(newIntent);
|
||||
}
|
||||
result.setIntents(intents);
|
||||
return result;
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> processWeather(TurnContext turnContext, RecognizerResult luisResult) {
|
||||
_logger.info("ProcessWeatherAsync");
|
||||
|
||||
// Retrieve LUIS result for Process Automation.
|
||||
PredictionResult predictionResult = mapPredictionResult(luisResult.getProperties().get("luisResult"));
|
||||
|
||||
Intent topIntent = predictionResult.getIntents().get(0);
|
||||
return turnContext
|
||||
.sendActivity(MessageFactory.text(String.format("ProcessWeather top intent %s.", topIntent.getTopIntent())))
|
||||
.thenCompose(sendResult -> {
|
||||
List<String> intents =
|
||||
topIntent.getChildIntents().stream().map(x -> x.getName()).collect(Collectors.toList());
|
||||
return turnContext
|
||||
.sendActivity(
|
||||
MessageFactory
|
||||
.text(String.format("ProcessWeather Intents detected:\n\n%s", String.join("\n\n", intents)))
|
||||
)
|
||||
.thenCompose(secondResult -> {
|
||||
if (luisResult.getEntities() != null) {
|
||||
List<String> entities = mapEntities(luisResult.getEntities());
|
||||
if (entities.size() > 0) {
|
||||
return turnContext
|
||||
.sendActivity(
|
||||
MessageFactory.text(
|
||||
String.format(
|
||||
"ProcessWeather entities were found in the message:\n\n%s",
|
||||
String.join("\n\n", entities)
|
||||
)
|
||||
)
|
||||
)
|
||||
.thenApply(finalResult -> null);
|
||||
}
|
||||
}
|
||||
return CompletableFuture.completedFuture(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> processSampleQnA(TurnContext turnContext) {
|
||||
_logger.info("ProcessSampleQnAAsync");
|
||||
|
||||
return _botServices.getSampleQnA().getAnswers(turnContext, null).thenCompose(results -> {
|
||||
if (results.length > 0) {
|
||||
return turnContext.sendActivity(MessageFactory.text(results[0].getAnswer())).thenApply(result -> null);
|
||||
} else {
|
||||
return turnContext
|
||||
.sendActivity(MessageFactory.text("Sorry, could not find an answer in the Q and A system."))
|
||||
.thenApply(result -> null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,605 @@
|
|||
{
|
||||
"luis_schema_version": "3.2.0",
|
||||
"versionId": "0.1",
|
||||
"name": "Home Automation",
|
||||
"desc": "Home Automation LUIS application - Bot Builder Samples",
|
||||
"culture": "en-us",
|
||||
"tokenizerVersion": "1.0.0",
|
||||
"intents": [
|
||||
{
|
||||
"name": "HomeAutomation"
|
||||
},
|
||||
{
|
||||
"name": "None"
|
||||
}
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"name": "Device",
|
||||
"roles": []
|
||||
},
|
||||
{
|
||||
"name": "deviceProperty",
|
||||
"roles": []
|
||||
},
|
||||
{
|
||||
"name": "Room",
|
||||
"roles": []
|
||||
}
|
||||
],
|
||||
"composites": [],
|
||||
"closedLists": [
|
||||
{
|
||||
"name": "Operation",
|
||||
"subLists": [
|
||||
{
|
||||
"canonicalForm": "off",
|
||||
"list": [
|
||||
"off",
|
||||
"turn off",
|
||||
"switch off",
|
||||
"lock",
|
||||
"out",
|
||||
"shut down",
|
||||
"stop"
|
||||
]
|
||||
},
|
||||
{
|
||||
"canonicalForm": "on",
|
||||
"list": [
|
||||
"on",
|
||||
"turn on",
|
||||
"switch on",
|
||||
"unlock",
|
||||
"un lock",
|
||||
"boot up",
|
||||
"start"
|
||||
]
|
||||
}
|
||||
],
|
||||
"roles": []
|
||||
}
|
||||
],
|
||||
"patternAnyEntities": [
|
||||
{
|
||||
"name": "Device_PatternAny",
|
||||
"roles": [],
|
||||
"explicitList": []
|
||||
},
|
||||
{
|
||||
"name": "Room_PatternAny",
|
||||
"roles": [],
|
||||
"explicitList": []
|
||||
}
|
||||
],
|
||||
"regex_entities": [],
|
||||
"prebuiltEntities": [
|
||||
{
|
||||
"name": "number",
|
||||
"roles": []
|
||||
}
|
||||
],
|
||||
"model_features": [],
|
||||
"regex_features": [],
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "{Device_PatternAny} in {Room_PatternAny} on [please]",
|
||||
"intent": "HomeAutomation"
|
||||
},
|
||||
{
|
||||
"pattern": "{Device_PatternAny} on [please]",
|
||||
"intent": "HomeAutomation"
|
||||
},
|
||||
{
|
||||
"pattern": "turn off {Device_PatternAny} in {Room_PatternAny}",
|
||||
"intent": "HomeAutomation"
|
||||
},
|
||||
{
|
||||
"pattern": "turn on {Device_PatternAny} in {Room_PatternAny}",
|
||||
"intent": "HomeAutomation"
|
||||
},
|
||||
{
|
||||
"pattern": "turn on {Device_PatternAny}",
|
||||
"intent": "HomeAutomation"
|
||||
},
|
||||
{
|
||||
"pattern": "{Device_PatternAny} in {Room_PatternAny} off [please]",
|
||||
"intent": "HomeAutomation"
|
||||
},
|
||||
{
|
||||
"pattern": "{Device_PatternAny} off [please]",
|
||||
"intent": "HomeAutomation"
|
||||
}
|
||||
],
|
||||
"utterances": [
|
||||
{
|
||||
"text": "breezeway on please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 0,
|
||||
"endPos": 8
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "change temperature to seventy two degrees",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "deviceProperty",
|
||||
"startPos": 7,
|
||||
"endPos": 17
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "coffee bar on please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 0,
|
||||
"endPos": 9
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "decrease temperature for me please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "deviceProperty",
|
||||
"startPos": 9,
|
||||
"endPos": 19
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "dim kitchen lights to 25 .",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 4,
|
||||
"endPos": 10
|
||||
},
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 12,
|
||||
"endPos": 17
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "fish pond off please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 0,
|
||||
"endPos": 8
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "fish pond on please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 0,
|
||||
"endPos": 8
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "illuminate please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 0,
|
||||
"endPos": 9
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "living room lamp on please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 0,
|
||||
"endPos": 10
|
||||
},
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 12,
|
||||
"endPos": 15
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "living room lamps off please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 0,
|
||||
"endPos": 10
|
||||
},
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 12,
|
||||
"endPos": 16
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "lock the doors for me please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 9,
|
||||
"endPos": 13
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "lower your volume",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "deviceProperty",
|
||||
"startPos": 11,
|
||||
"endPos": 16
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "make camera 1 off please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 5,
|
||||
"endPos": 12
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "make some coffee",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 10,
|
||||
"endPos": 15
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "play dvd",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 5,
|
||||
"endPos": 7
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "set lights out in bedroom",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 4,
|
||||
"endPos": 9
|
||||
},
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 18,
|
||||
"endPos": 24
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "set lights to bright",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 4,
|
||||
"endPos": 9
|
||||
},
|
||||
{
|
||||
"entity": "deviceProperty",
|
||||
"startPos": 14,
|
||||
"endPos": 19
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "set lights to concentrate",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 4,
|
||||
"endPos": 9
|
||||
},
|
||||
{
|
||||
"entity": "deviceProperty",
|
||||
"startPos": 14,
|
||||
"endPos": 24
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "shut down my work computer",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 18,
|
||||
"endPos": 25
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "snap switch fan fifty percent",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 12,
|
||||
"endPos": 14
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "start master bedroom light.",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 6,
|
||||
"endPos": 19
|
||||
},
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 21,
|
||||
"endPos": 25
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "theater on please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 0,
|
||||
"endPos": 6
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn dimmer off",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 5,
|
||||
"endPos": 10
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn off ac please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 9,
|
||||
"endPos": 10
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn off foyer lights",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 9,
|
||||
"endPos": 13
|
||||
},
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 15,
|
||||
"endPos": 20
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn off living room light",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 9,
|
||||
"endPos": 19
|
||||
},
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 21,
|
||||
"endPos": 25
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn off staircase",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 9,
|
||||
"endPos": 17
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn off venice lamp",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 16,
|
||||
"endPos": 19
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn on bathroom heater",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 8,
|
||||
"endPos": 15
|
||||
},
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 17,
|
||||
"endPos": 22
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn on external speaker",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 8,
|
||||
"endPos": 23
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn on kitchen faucet",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 8,
|
||||
"endPos": 14
|
||||
},
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 16,
|
||||
"endPos": 21
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn on light in bedroom",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 8,
|
||||
"endPos": 12
|
||||
},
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 17,
|
||||
"endPos": 23
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn on my bedroom lights.",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 11,
|
||||
"endPos": 17
|
||||
},
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 19,
|
||||
"endPos": 24
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn on the furnace room lights",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 12,
|
||||
"endPos": 23
|
||||
},
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 25,
|
||||
"endPos": 30
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn on the internet in my bedroom please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Room",
|
||||
"startPos": 27,
|
||||
"endPos": 33
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn on thermostat please",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 8,
|
||||
"endPos": 17
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn the fan to high",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 9,
|
||||
"endPos": 11
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "turn thermostat on 70.",
|
||||
"intent": "HomeAutomation",
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Device",
|
||||
"startPos": 5,
|
||||
"endPos": 14
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"settings": []
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
Question Answer Source Metadata
|
||||
hi Hello! QnAMaker.tsv
|
||||
greetings Hello! QnAMaker.tsv
|
||||
good morning Hello! QnAMaker.tsv
|
||||
good evening Hello! QnAMaker.tsv
|
||||
What are you? I am the LUIS-QnAMaker Dispatch bot! This sample demonstrates using several LUIS applications and QnA Maker knowledge base using dispatch. QnAMaker.tsv
|
||||
What? I am the LUIS-QnAMaker Dispatch bot! This sample demonstrates using several LUIS applications and QnA Maker knowledge base using dispatch. QnAMaker.tsv
|
||||
What do you do? I am the LUIS-QnAMaker Dispatch bot! This sample demonstrates using several LUIS applications and QnA Maker knowledge base using dispatch. QnAMaker.tsv
|
||||
Who are you? I am the LUIS-QnAMaker Dispatch bot! This sample demonstrates using several LUIS applications and QnA Maker knowledge base using dispatch. QnAMaker.tsv
|
||||
What is your name? I am the LUIS-QnAMaker Dispatch bot! This sample demonstrates using several LUIS applications and QnA Maker knowledge base using dispatch. QnAMaker.tsv
|
||||
What should I call you? I am the LUIS-QnAMaker Dispatch bot! This sample demonstrates using several LUIS applications and QnA Maker knowledge base using dispatch. QnAMaker.tsv
|
|
|
@ -0,0 +1,315 @@
|
|||
{
|
||||
"luis_schema_version": "3.2.0",
|
||||
"name": "Weather",
|
||||
"versionId": "0.1",
|
||||
"desc": "Weather LUIS application - Bot Builder Samples",
|
||||
"culture": "en-us",
|
||||
"intents": [
|
||||
{
|
||||
"name": "Get Weather Condition"
|
||||
},
|
||||
{
|
||||
"name": "Get Weather Forecast"
|
||||
},
|
||||
{
|
||||
"name": "None"
|
||||
}
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"name": "Location",
|
||||
"roles": []
|
||||
}
|
||||
],
|
||||
"closedLists": [],
|
||||
"composites": [],
|
||||
"patternAnyEntities": [
|
||||
{
|
||||
"name": "Location_PatternAny",
|
||||
"explicitList": [],
|
||||
"roles": []
|
||||
}
|
||||
],
|
||||
"regex_entities": [],
|
||||
"prebuiltEntities": [],
|
||||
"regex_features": [],
|
||||
"model_features": [],
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "weather in {Location_PatternAny}",
|
||||
"intent": "Get Weather Condition"
|
||||
},
|
||||
{
|
||||
"pattern": "how's the weather in {Location_PatternAny}",
|
||||
"intent": "Get Weather Condition"
|
||||
},
|
||||
{
|
||||
"pattern": "current weather in {Location_PatternAny}",
|
||||
"intent": "Get Weather Condition"
|
||||
},
|
||||
{
|
||||
"pattern": "what's the forecast for next week in {Location_PatternAny}",
|
||||
"intent": "Get Weather Forecast"
|
||||
},
|
||||
{
|
||||
"pattern": "show me the forecast for {Location_PatternAny}",
|
||||
"intent": "Get Weather Forecast"
|
||||
},
|
||||
{
|
||||
"pattern": "what's the forecast for {Location_PatternAny}",
|
||||
"intent": "Get Weather Forecast"
|
||||
}
|
||||
],
|
||||
"utterances": [
|
||||
{
|
||||
"text": "current weather ?",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "do florida residents usually need ice scrapers",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 3,
|
||||
"endPos": 9,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "forecast in celcius",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "get florence temperature in september",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 4,
|
||||
"endPos": 11,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "get for me the weather conditions in sonoma county",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 37,
|
||||
"endPos": 49,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "get the daily temperature greenwood indiana",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 26,
|
||||
"endPos": 42,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "get the forcast for me",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "get the weather at saint george utah",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 19,
|
||||
"endPos": 35,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "how much rain does chambersburg get a year",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 19,
|
||||
"endPos": 30,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "i want to know the temperature at death valley",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 34,
|
||||
"endPos": 45,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "provide me by toronto weather please",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 14,
|
||||
"endPos": 20,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "show average rainfall for boise",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 26,
|
||||
"endPos": 30,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "show me the forecast at alabama",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 24,
|
||||
"endPos": 30,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "soliciting today's weather",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "temperature of delhi in celsius please",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 15,
|
||||
"endPos": 19,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "was last year about this time as wet as it is now in the south ?",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 57,
|
||||
"endPos": 61,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "what is the rain volume in sonoma county ?",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 27,
|
||||
"endPos": 39,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "what is the weather in redmond ?",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 23,
|
||||
"endPos": 29,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "what is the weather today at 10 day durham ?",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 36,
|
||||
"endPos": 41,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "what to wear in march in california",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 25,
|
||||
"endPos": 34,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "what will the weather be tomorrow in new york ?",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 37,
|
||||
"endPos": 44,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "what's the weather going to be like in hawaii ?",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 39,
|
||||
"endPos": 44,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "what's the weather like in minneapolis",
|
||||
"intent": "Get Weather Condition",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 27,
|
||||
"endPos": 37,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "will it be raining in ranchi",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": [
|
||||
{
|
||||
"startPos": 22,
|
||||
"endPos": 27,
|
||||
"entity": "Location"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "will it rain this weekend",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "will it snow today",
|
||||
"intent": "Get Weather Forecast",
|
||||
"entities": []
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
MicrosoftAppId=
|
||||
MicrosoftAppPassword=
|
||||
server.port=3978
|
||||
|
||||
QnAKnowledgebaseId=
|
||||
QnAEndpointKey=
|
||||
QnAEndpointHostName=
|
||||
|
||||
LuisAppId =
|
||||
LuisAPIKey=
|
||||
LuisAPIHostName=
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"configuration": {
|
||||
"name": "Default",
|
||||
"appenders": {
|
||||
"Console": {
|
||||
"name": "Console-Appender",
|
||||
"target": "SYSTEM_OUT",
|
||||
"PatternLayout": {"pattern": "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"}
|
||||
}
|
||||
},
|
||||
"loggers": {
|
||||
"root": {
|
||||
"level": "debug",
|
||||
"appender-ref": {"ref": "Console-Appender","level": "debug"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
Manifest-Version: 1.0
|
||||
Class-Path:
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<servlet>
|
||||
<servlet-name>dispatcher</servlet-name>
|
||||
<servlet-class>
|
||||
org.springframework.web.servlet.DispatcherServlet
|
||||
</servlet-class>
|
||||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
|
@ -0,0 +1,418 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>EchoBot</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
font-family: Segoe UI;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
header {
|
||||
background-image: url("data:image/svg+xml,%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 4638.9 651.6' style='enable-background:new 0 0 4638.9 651.6;' xml:space='preserve'%3E%3Cstyle type='text/css'%3E .st0%7Bfill:%2355A0E0;%7D .st1%7Bfill:none;%7D .st2%7Bfill:%230058A8;%7D .st3%7Bfill:%23328BD8;%7D .st4%7Bfill:%23B6DCF1;%7D .st5%7Bopacity:0.2;fill:url(%23SVGID_1_);enable-background:new ;%7D%0A%3C/style%3E%3Crect y='1.1' class='st0' width='4640' height='646.3'/%3E%3Cpath class='st1' d='M3987.8,323.6L4310.3,1.1h-65.6l-460.1,460.1c-17.5,17.5-46.1,17.5-63.6,0L3260.9,1.1H0v646.3h3660.3 L3889,418.7c17.5-17.5,46.1-17.5,63.6,0l228.7,228.7h66.6l-260.2-260.2C3970.3,369.8,3970.3,341.1,3987.8,323.6z'/%3E%3Cpath class='st2' d='M3784.6,461.2L4244.7,1.1h-983.9l460.1,460.1C3738.4,478.7,3767.1,478.7,3784.6,461.2z'/%3E%3Cpath class='st3' d='M4640,1.1h-329.8l-322.5,322.5c-17.5,17.5-17.5,46.1,0,63.6l260.2,260.2H4640L4640,1.1L4640,1.1z'/%3E%3Cpath class='st4' d='M3889,418.8l-228.7,228.7h521.1l-228.7-228.7C3935.2,401.3,3906.5,401.3,3889,418.8z'/%3E%3ClinearGradient id='SVGID_1_' gradientUnits='userSpaceOnUse' x1='3713.7576' y1='438.1175' x2='3911.4084' y2='14.2535' gradientTransform='matrix(1 0 0 -1 0 641.3969)'%3E%3Cstop offset='0' style='stop-color:%23FFFFFF;stop-opacity:0.5'/%3E%3Cstop offset='1' style='stop-color:%23FFFFFF'/%3E%3C/linearGradient%3E%3Cpath class='st5' d='M3952.7,124.5c-17.5-17.5-46.1-17.5-63.6,0l-523,523h1109.6L3952.7,124.5z'/%3E%3C/svg%3E%0A");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100%;
|
||||
background-position: right;
|
||||
background-color: #55A0E0;
|
||||
width: 100%;
|
||||
font-size: 44px;
|
||||
height: 120px;
|
||||
color: white;
|
||||
padding: 30px 0 40px 0px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
background-image: url("data:image/svg+xml;utf8,%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%20150.2%20125%22%20style%3D%22enable-background%3Anew%200%200%20150.2%20125%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cstyle%20type%3D%22text/css%22%3E%0A%09.st0%7Bfill%3Anone%3B%7D%0A%09.st1%7Bfill%3A%23FFFFFF%3B%7D%0A%3C/style%3E%0A%3Crect%20x%3D%220.5%22%20class%3D%22st0%22%20width%3D%22149.7%22%20height%3D%22125%22/%3E%0A%3Cg%3E%0A%09%3Cpath%20class%3D%22st1%22%20d%3D%22M59%2C102.9L21.8%2C66c-3.5-3.5-3.5-9.1%2C0-12.5l37-36.5l2.9%2C3l-37%2C36.4c-1.8%2C1.8-1.8%2C4.7%2C0%2C6.6l37.2%2C37L59%2C102.9z%22%0A%09%09/%3E%0A%3C/g%3E%0A%3Cg%3E%0A%09%3Cpath%20class%3D%22st1%22%20d%3D%22M92.5%2C102.9l-3-3l37.2-37c0.9-0.9%2C1.4-2%2C1.4-3.3c0-1.2-0.5-2.4-1.4-3.3L89.5%2C20l2.9-3l37.2%2C36.4%0A%09%09c1.7%2C1.7%2C2.6%2C3.9%2C2.6%2C6.3s-0.9%2C4.6-2.6%2C6.3L92.5%2C102.9z%22/%3E%0A%3C/g%3E%0A%3Cg%3E%0A%09%3Cpath%20class%3D%22st1%22%20d%3D%22M90.1%2C68.4c-4.5%2C0-8-3.5-8-8.1c0-4.5%2C3.5-8.1%2C8-8.1c4.4%2C0%2C8%2C3.7%2C8%2C8.1C98.1%2C64.7%2C94.4%2C68.4%2C90.1%2C68.4z%0A%09%09%20M90.1%2C56.5c-2.2%2C0-3.8%2C1.7-3.8%2C3.9c0%2C2.2%2C1.7%2C3.9%2C3.8%2C3.9c1.9%2C0%2C3.8-1.6%2C3.8-3.9S91.9%2C56.5%2C90.1%2C56.5z%22/%3E%0A%3C/g%3E%0A%3Cg%3E%0A%09%3Cpath%20class%3D%22st1%22%20d%3D%22M61.4%2C68.4c-4.5%2C0-8-3.5-8-8.1c0-4.5%2C3.5-8.1%2C8-8.1c4.4%2C0%2C8%2C3.7%2C8%2C8.1C69.5%2C64.7%2C65.8%2C68.4%2C61.4%2C68.4z%0A%09%09%20M61.4%2C56.5c-2.2%2C0-3.8%2C1.7-3.8%2C3.9c0%2C2.2%2C1.7%2C3.9%2C3.8%2C3.9c1.9%2C0%2C3.8-1.6%2C3.8-3.9S63.3%2C56.5%2C61.4%2C56.5z%22/%3E%0A%3C/g%3E%0A%3C/svg%3E%0A");
|
||||
background-repeat: no-repeat;
|
||||
float: left;
|
||||
height: 140px;
|
||||
width: 140px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.header-text {
|
||||
padding-left: 1%;
|
||||
color: #FFFFFF;
|
||||
font-family: "Segoe UI";
|
||||
font-size: 72px;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.35px;
|
||||
line-height: 96px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.header-inner-container {
|
||||
min-width: 480px;
|
||||
max-width: 1366px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.header-inner-container::after {
|
||||
content: "";
|
||||
clear: both;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.main-content-area {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.content-title {
|
||||
color: #000000;
|
||||
font-family: "Segoe UI";
|
||||
font-size: 46px;
|
||||
font-weight: 300;
|
||||
line-height: 62px;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
color: #808080;
|
||||
font-size: 24px;
|
||||
font-family: "Segoe UI";
|
||||
font-size: 24px;
|
||||
font-weight: 200;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.main-text-p1{
|
||||
padding-top: 48px;
|
||||
padding-bottom: 28px;
|
||||
}
|
||||
|
||||
.endpoint {
|
||||
height: 32px;
|
||||
width: 571px;
|
||||
color: #808080;
|
||||
font-family: "Segoe UI";
|
||||
font-size: 24px;
|
||||
font-weight: 200;
|
||||
line-height: 32px;
|
||||
padding-top: 28px;
|
||||
}
|
||||
|
||||
.how-to-build-section {
|
||||
padding-top: 20px;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.how-to-build-section>h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.35px;
|
||||
line-height: 22px;
|
||||
margin: 0 0 24px 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.step-container {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.step-container dl {
|
||||
border-left: 1px solid #A0A0A0;
|
||||
display: block;
|
||||
padding: 0 24px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.step-container dl>dt::before {
|
||||
background-color: white;
|
||||
border: 1px solid #A0A0A0;
|
||||
border-radius: 100%;
|
||||
content: '';
|
||||
left: 47px;
|
||||
height: 11px;
|
||||
position: absolute;
|
||||
width: 11px;
|
||||
}
|
||||
|
||||
.step-container dl>.test-bullet::before {
|
||||
background-color: blue;
|
||||
}
|
||||
|
||||
.step-container dl>dt {
|
||||
display: block;
|
||||
font-size: inherit;
|
||||
font-weight: bold;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.step-container dl>dd {
|
||||
font-size: inherit;
|
||||
line-height: 20px;
|
||||
margin-left: 0;
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
|
||||
.step-container:last-child dl {
|
||||
border-left: 1px solid transparent;
|
||||
}
|
||||
|
||||
.ctaLink {
|
||||
background-color: transparent;
|
||||
border: 1px solid transparent;
|
||||
color: #006AB1;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
padding: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.ctaLink:focus {
|
||||
outline: 1px solid #00bcf2;
|
||||
}
|
||||
|
||||
.ctaLink:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.step-icon {
|
||||
display: flex;
|
||||
height: 38px;
|
||||
margin-right: 15px;
|
||||
width: 38px;
|
||||
}
|
||||
|
||||
.step-icon>div {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.ms-logo-container {
|
||||
min-width: 580px;
|
||||
max-width: 980px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transition: bottom 400ms;
|
||||
}
|
||||
|
||||
.ms-logo {
|
||||
float: right;
|
||||
background-image: url("data:image/svg+xml;utf8,%0A%3Csvg%20version%3D%221.1%22%20id%3D%22MS-symbol%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%20400%20120%22%20style%3D%22enable-background%3Anew%200%200%20400%20120%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cstyle%20type%3D%22text/css%22%3E%0A%09.st0%7Bfill%3Anone%3B%7D%0A%09.st1%7Bfill%3A%23737474%3B%7D%0A%09.st2%7Bfill%3A%23D63F26%3B%7D%0A%09.st3%7Bfill%3A%23167D3E%3B%7D%0A%09.st4%7Bfill%3A%232E76BC%3B%7D%0A%09.st5%7Bfill%3A%23FDB813%3B%7D%0A%3C/style%3E%0A%3Crect%20x%3D%220.6%22%20class%3D%22st0%22%20width%3D%22398.7%22%20height%3D%22119%22/%3E%0A%3Cpath%20class%3D%22st1%22%20d%3D%22M171.3%2C38.4v43.2h-7.5V47.7h-0.1l-13.4%2C33.9h-5l-13.7-33.9h-0.1v33.9h-6.9V38.4h10.8l12.4%2C32h0.2l13.1-32H171.3%0A%09z%20M177.6%2C41.7c0-1.2%2C0.4-2.2%2C1.3-3c0.9-0.8%2C1.9-1.2%2C3.1-1.2c1.3%2C0%2C2.4%2C0.4%2C3.2%2C1.3c0.8%2C0.8%2C1.3%2C1.8%2C1.3%2C3c0%2C1.2-0.4%2C2.2-1.3%2C3%0A%09c-0.9%2C0.8-1.9%2C1.2-3.2%2C1.2s-2.3-0.4-3.1-1.2C178%2C43.8%2C177.6%2C42.8%2C177.6%2C41.7z%20M185.7%2C50.6v31h-7.3v-31H185.7z%20M207.8%2C76.3%0A%09c1.1%2C0%2C2.3-0.3%2C3.6-0.8c1.3-0.5%2C2.5-1.2%2C3.6-2v6.8c-1.2%2C0.7-2.5%2C1.2-4%2C1.5c-1.5%2C0.3-3.1%2C0.5-4.9%2C0.5c-4.6%2C0-8.3-1.4-11.1-4.3%0A%09c-2.9-2.9-4.3-6.6-4.3-11c0-5%2C1.5-9.1%2C4.4-12.3c2.9-3.2%2C7-4.8%2C12.4-4.8c1.4%2C0%2C2.7%2C0.2%2C4.1%2C0.5c1.4%2C0.4%2C2.5%2C0.8%2C3.3%2C1.2v7%0A%09c-1.1-0.8-2.3-1.5-3.4-1.9c-1.2-0.5-2.4-0.7-3.6-0.7c-2.9%2C0-5.2%2C0.9-7%2C2.8c-1.8%2C1.9-2.7%2C4.4-2.7%2C7.6c0%2C3.1%2C0.8%2C5.6%2C2.5%2C7.3%0A%09C202.6%2C75.4%2C204.9%2C76.3%2C207.8%2C76.3z%20M235.7%2C50.1c0.6%2C0%2C1.1%2C0%2C1.6%2C0.1s0.9%2C0.2%2C1.2%2C0.3v7.4c-0.4-0.3-0.9-0.5-1.7-0.8%0A%09c-0.7-0.3-1.6-0.4-2.7-0.4c-1.8%2C0-3.3%2C0.8-4.5%2C2.3c-1.2%2C1.5-1.9%2C3.8-1.9%2C7v15.6h-7.3v-31h7.3v4.9h0.1c0.7-1.7%2C1.7-3%2C3-4%0A%09C232.2%2C50.6%2C233.8%2C50.1%2C235.7%2C50.1z%20M238.9%2C66.6c0-5.1%2C1.4-9.2%2C4.3-12.2c2.9-3%2C6.9-4.5%2C12.1-4.5c4.8%2C0%2C8.6%2C1.4%2C11.3%2C4.3%0A%09c2.7%2C2.9%2C4.1%2C6.8%2C4.1%2C11.7c0%2C5-1.4%2C9-4.3%2C12c-2.9%2C3-6.8%2C4.5-11.8%2C4.5c-4.8%2C0-8.6-1.4-11.4-4.2C240.3%2C75.3%2C238.9%2C71.4%2C238.9%2C66.6z%0A%09%20M246.5%2C66.3c0%2C3.2%2C0.7%2C5.7%2C2.2%2C7.4c1.5%2C1.7%2C3.6%2C2.6%2C6.3%2C2.6c2.7%2C0%2C4.7-0.9%2C6.1-2.6c1.4-1.7%2C2.1-4.2%2C2.1-7.6c0-3.3-0.7-5.8-2.2-7.5%0A%09c-1.4-1.7-3.4-2.5-6-2.5c-2.7%2C0-4.7%2C0.9-6.2%2C2.7C247.2%2C60.5%2C246.5%2C63%2C246.5%2C66.3z%20M281.5%2C58.8c0%2C1%2C0.3%2C1.9%2C1%2C2.5%0A%09c0.7%2C0.6%2C2.1%2C1.3%2C4.4%2C2.2c2.9%2C1.2%2C5%2C2.5%2C6.1%2C3.9c1.2%2C1.5%2C1.8%2C3.2%2C1.8%2C5.3c0%2C2.9-1.1%2C5.3-3.4%2C7c-2.2%2C1.8-5.3%2C2.7-9.1%2C2.7%0A%09c-1.3%2C0-2.7-0.2-4.3-0.5c-1.6-0.3-2.9-0.7-4-1.2v-7.2c1.3%2C0.9%2C2.8%2C1.7%2C4.3%2C2.2c1.5%2C0.5%2C2.9%2C0.8%2C4.2%2C0.8c1.6%2C0%2C2.9-0.2%2C3.6-0.7%0A%09c0.8-0.5%2C1.2-1.2%2C1.2-2.3c0-1-0.4-1.9-1.2-2.5c-0.8-0.7-2.4-1.5-4.6-2.4c-2.7-1.1-4.6-2.4-5.7-3.8c-1.1-1.4-1.7-3.2-1.7-5.4%0A%09c0-2.8%2C1.1-5.1%2C3.3-6.9c2.2-1.8%2C5.1-2.7%2C8.6-2.7c1.1%2C0%2C2.3%2C0.1%2C3.6%2C0.4c1.3%2C0.2%2C2.5%2C0.6%2C3.4%2C0.9v6.9c-1-0.6-2.1-1.2-3.4-1.7%0A%09c-1.3-0.5-2.6-0.7-3.8-0.7c-1.4%2C0-2.5%2C0.3-3.2%2C0.8C281.9%2C57.1%2C281.5%2C57.8%2C281.5%2C58.8z%20M297.9%2C66.6c0-5.1%2C1.4-9.2%2C4.3-12.2%0A%09c2.9-3%2C6.9-4.5%2C12.1-4.5c4.8%2C0%2C8.6%2C1.4%2C11.3%2C4.3c2.7%2C2.9%2C4.1%2C6.8%2C4.1%2C11.7c0%2C5-1.4%2C9-4.3%2C12c-2.9%2C3-6.8%2C4.5-11.8%2C4.5%0A%09c-4.8%2C0-8.6-1.4-11.4-4.2C299.4%2C75.3%2C297.9%2C71.4%2C297.9%2C66.6z%20M305.5%2C66.3c0%2C3.2%2C0.7%2C5.7%2C2.2%2C7.4c1.5%2C1.7%2C3.6%2C2.6%2C6.3%2C2.6%0A%09c2.7%2C0%2C4.7-0.9%2C6.1-2.6c1.4-1.7%2C2.1-4.2%2C2.1-7.6c0-3.3-0.7-5.8-2.2-7.5c-1.4-1.7-3.4-2.5-6-2.5c-2.7%2C0-4.7%2C0.9-6.2%2C2.7%0A%09C306.3%2C60.5%2C305.5%2C63%2C305.5%2C66.3z%20M353.9%2C56.6h-10.9v25h-7.4v-25h-5.2v-6h5.2v-4.3c0-3.3%2C1.1-5.9%2C3.2-8c2.1-2.1%2C4.8-3.1%2C8.1-3.1%0A%09c0.9%2C0%2C1.7%2C0%2C2.4%2C0.1c0.7%2C0.1%2C1.3%2C0.2%2C1.8%2C0.4V42c-0.2-0.1-0.7-0.3-1.3-0.5c-0.6-0.2-1.3-0.3-2.1-0.3c-1.5%2C0-2.7%2C0.5-3.5%2C1.4%0A%09s-1.2%2C2.4-1.2%2C4.2v3.7h10.9v-7l7.3-2.2v9.2h7.4v6h-7.4v14.5c0%2C1.9%2C0.3%2C3.3%2C1%2C4c0.7%2C0.8%2C1.8%2C1.2%2C3.3%2C1.2c0.4%2C0%2C0.9-0.1%2C1.5-0.3%0A%09c0.6-0.2%2C1.1-0.4%2C1.6-0.7v6c-0.5%2C0.3-1.2%2C0.5-2.3%2C0.7c-1.1%2C0.2-2.1%2C0.3-3.2%2C0.3c-3.1%2C0-5.4-0.8-6.9-2.5c-1.5-1.6-2.3-4.1-2.3-7.4%0A%09V56.6z%22/%3E%0A%3Cg%3E%0A%09%3Crect%20x%3D%2231%22%20y%3D%2224%22%20class%3D%22st2%22%20width%3D%2234.2%22%20height%3D%2234.2%22/%3E%0A%09%3Crect%20x%3D%2268.8%22%20y%3D%2224%22%20class%3D%22st3%22%20width%3D%2234.2%22%20height%3D%2234.2%22/%3E%0A%09%3Crect%20x%3D%2231%22%20y%3D%2261.8%22%20class%3D%22st4%22%20width%3D%2234.2%22%20height%3D%2234.2%22/%3E%0A%09%3Crect%20x%3D%2268.8%22%20y%3D%2261.8%22%20class%3D%22st5%22%20width%3D%2234.2%22%20height%3D%2234.2%22/%3E%0A%3C/g%3E%0A%3C/svg%3E%0A");
|
||||
}
|
||||
|
||||
.ms-logo-container>div {
|
||||
min-height: 60px;
|
||||
width: 150px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 90px 0px 0 20px;
|
||||
min-width: 480px;
|
||||
max-width: 1366px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.column {
|
||||
float: left;
|
||||
width: 45%;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.row:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.download-the-emulator {
|
||||
height: 20px;
|
||||
color: #0063B1;
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
padding-bottom: 70px;
|
||||
}
|
||||
|
||||
.how-to-iframe {
|
||||
max-width: 700px !important;
|
||||
min-width: 650px !important;
|
||||
height: 700px !important;
|
||||
}
|
||||
|
||||
.remove-frame-height {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1300px) {
|
||||
.ms-logo {
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.header-text {
|
||||
font-size: 40x;
|
||||
}
|
||||
|
||||
.column {
|
||||
float: none;
|
||||
padding-top: 30px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ms-logo-container {
|
||||
padding-top: 30px;
|
||||
min-width: 480px;
|
||||
max-width: 650px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 20px 0px 0 20px;
|
||||
min-width: 480px;
|
||||
max-width: 650px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1370px) {
|
||||
header {
|
||||
background-color: #55A0E0;
|
||||
background-size: auto 200px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1230px) {
|
||||
header {
|
||||
background-color: #55A0E0;
|
||||
background-size: auto 200px;
|
||||
}
|
||||
|
||||
.header-text {
|
||||
font-size: 44px;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1000px) {
|
||||
header {
|
||||
background-color: #55A0E0;
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 632px) {
|
||||
.header-text {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 10px 0px 0 10px;
|
||||
max-width: 490px !important;
|
||||
min-width: 410px !important;
|
||||
}
|
||||
|
||||
.endpoint {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.step-container dl>dd {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.column {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
height: 110px;
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
.how-to-iframe {
|
||||
max-width: 480px !important;
|
||||
min-width: 400px !important;
|
||||
height: 650px !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.remove-frame-height {
|
||||
max-height: 10px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
loadFrame();
|
||||
});
|
||||
var loadFrame = function () {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute("id", "iframe");
|
||||
var offLineHTMLContent = "";
|
||||
var frameElement = document.getElementById("how-to-iframe");
|
||||
if (window.navigator.onLine) {
|
||||
iframe.src = 'https://docs.botframework.com/static/abs/pages/f5.htm';
|
||||
iframe.setAttribute("scrolling", "no");
|
||||
iframe.setAttribute("frameborder", "0");
|
||||
iframe.setAttribute("width", "100%");
|
||||
iframe.setAttribute("height", "100%");
|
||||
var frameDiv = document.getElementById("how-to-iframe");
|
||||
frameDiv.appendChild(iframe);
|
||||
} else {
|
||||
frameElement.classList.add("remove-frame-height");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="header-inner-container">
|
||||
<div class="header-icon" style="display: inline-block"></div>
|
||||
<div class="header-text" style="display: inline-block">Spring Boot Bot</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="row">
|
||||
<div class="column" class="main-content-area">
|
||||
<div class="content-title">Your bot is ready!</div>
|
||||
<div class="main-text main-text-p1">You can test your bot in the Bot Framework Emulator<br />
|
||||
by connecting to http://localhost:3978/api/messages.</div>
|
||||
<div class="main-text download-the-emulator"><a class="ctaLink" href="https://aka.ms/bot-framework-F5-download-emulator"
|
||||
target="_blank">Download the Emulator</a></div>
|
||||
<div class="main-text">Visit <a class="ctaLink" href="https://aka.ms/bot-framework-F5-abs-home" target="_blank">Azure
|
||||
Bot Service</a> to register your bot and add it to<br />
|
||||
various channels. The bot's endpoint URL typically looks
|
||||
like this:</div>
|
||||
<div class="endpoint">https://<i>your_bots_hostname</i>/api/messages</div>
|
||||
</div>
|
||||
<div class="column how-to-iframe" id="how-to-iframe"></div>
|
||||
</div>
|
||||
<div class="ms-logo-container">
|
||||
<div class="ms-logo"></div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.sample.nlpwithdispatch;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class ApplicationTest {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
Загрузка…
Ссылка в новой задаче