This commit is contained in:
Arie 2020-03-24 17:19:18 +02:00
Родитель f15b59508d
Коммит 81baf01b33
17 изменённых файлов: 803 добавлений и 1242 удалений

Просмотреть файл

@ -1,26 +1,59 @@
# Virtual Healthcare Blueprint
## Creating Healthcare Bot Deployment
## Prerequisites
* Azure Subscription
* Powershell
* Powershell Azure modules
### Requirements
Clone this repository to your local drive
## Running the script
* Connect-AzAccount
* Connect-AzureAD
* Run Script
```powershell
git clone https://github.com/microsoft/VirtualHealthcareBlueprint
cd VirtualHealthcareBlueprint
```
# Contributing
[Install the Azure PowerShell module](https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-3.3.0)
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
### Connect to Azure Subscription
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
```PowerShell
Login-AzAccount
$account = Set-AzContext -Subscription <Your Subscription Name>
```
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
### Create Healthcare Bot and supporting Resources
```PowerShell
$rg = New-AzResourceGroup -Name <service Name> -Location eastus
```
Set Healthcare Bot name
```PowerShell
$botServiceName = "<healthcare bot service>"
```
Load the marketplace script
```powershell
. .\scripts\marketplace.ps1
```
Create the Healthcare Bot Azure Marketplace SaaS Application
```powershell
$saasSubscriptionId = New-HbsSaaSApplication -name $botServiceName -planId free
```
You can also see all your existing SaaS applications by running this command.
```Powershell
Get-HbsSaaSApplication
```
Deploy Healthcare Bot resources for the Marketplace SaaS application you just created or already had before.
```powershell
.\scripts\azuredeploy-healthcarebot.ps1 -ResourceGroup $rg.ResourceGroupName `
-saasSubscriptionId $saasSubscriptionId -serviceName $botServiceName `
-botLocation US -matchingParameters $matchingOutput.Outputs
```
This command can take few minutes to complete

Просмотреть файл

@ -0,0 +1,102 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"serviceName": {
"type": "string"
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"saasSubscriptionId": {
"type": "string"
},
"luisSku": {
"type": "string",
"defaultValue": "F0",
"allowedValues": [
"F0"
]
},
"luisAuthLocation": {
"type": "string",
"defaultValue": "westus"
},
"luisPredictionLocation":{
"type":"string",
"defaultValue":"[resourceGroup().location]"
},
"resourceTags": {
"type": "object",
"defaultValue": {
"Environment": "Dev",
"Project": "Tutorial"
}
}
},
"variables": {
"luisAuthoringName": "[concat(parameters('serviceName'),'-authoring')]",
"luisPredictionName": "[concat(parameters('serviceName'),'-prediction')]",
"insightsName": "[concat(parameters('serviceName'),'-insights')]"
},
"resources": [
{
"type": "microsoft.insights/components",
"apiVersion": "2015-05-01",
"tags": "[parameters('resourceTags')]",
"name": "[variables('insightsName')]",
"location": "[parameters('location')]",
"kind": "web",
"properties": {
"Application_Type": "web"
}
},
{
"type": "Microsoft.CognitiveServices/accounts",
"apiVersion": "2017-04-18",
"tags": "[parameters('resourceTags')]",
"name": "[variables('luisPredictionName')]",
"location": "[parameters('luisPredictionLocation')]",
"sku": {
"name": "[parameters('luisSku')]"
},
"kind": "LUIS",
"properties": {
"statisticsEnabled": false
}
},
{
"apiVersion": "2017-04-18",
"name": "[variables('luisAuthoringName')]",
"tags": "[parameters('resourceTags')]",
"location": "[parameters('luisAuthLocation')]",
"type": "Microsoft.CognitiveServices/accounts",
"kind": "LUIS.Authoring",
"sku": {
"name": "[parameters('luisSku')]"
},
"properties": {
"statisticsEnabled": false
}
}
],
"outputs": {
"serviceUniqueName": {
"type": "string",
"value": "[concat(parameters('serviceName'),'-', substring(uniqueString(parameters('saasSubscriptionId')), 0, 6))]"
},
"instrumentationKey": {
"type": "string",
"value": "[reference(variables('insightsName'), '2015-05-01').instrumentationKey]"
},
"luisAuthotingKey": {
"type": "string",
"value": "[listKeys(variables('luisAuthoringName'),'2017-04-18').key1]"
},
"luisPredictionKey": {
"type": "string",
"value": "[listKeys(variables('luisPredictionName'),'2017-04-18').key1]"
}
}
}

Просмотреть файл

@ -1,375 +0,0 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"serviceName": {
"type":"string"
},
"objectId": {
"type":"string",
"defaultValue":"639a682a-fffa-482f-bff2-568fd64e5d89"
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"luisSku":{
"type": "string",
"defaultValue": "F0",
"allowedValues": [
"F0"
]
},
"luisLocation": {
"type":"string",
"defaultValue":"westus"
},
"ayalonDockerRegistryUrl": {
"type":"string",
"defaultValue":"https://containerpreview.azurecr.io"
},
"ayalonDockerRegistryUser": {
"type":"string",
"defaultValue":"1930648e-be5a-49f8-93dd-11381794b13c"
},
"ayalonDockerRegistryPassword": {
"type":"securestring",
"defaultValue":"3e415e1c-0f8f-4a05-b122-5cd88c962c88"
},
"ayalonDockerImageName": {
"type":"string",
"defaultValue":"DOCKER|containerpreview.azurecr.io/microsoft/cognitive-services-healthcare:latest"
}
},
"variables": {
"uniqueServiceName": "[concat(parameters('serviceName'),'-', substring(uniqueString(resourceGroup().id), 0, 5))]",
"luisAuthoringName": "[concat(variables('uniqueServiceName'),'-authoring')]",
"luisPredictionName": "[concat(variables('uniqueServiceName'),'-prediction')]",
"insightsName": "[concat(variables('uniqueServiceName'),'-insights')]",
"fhirApiName":"[concat(variables('uniqueServiceName'),'-fhirapi')]",
"keyVaultName":"[concat(variables('uniqueServiceName'),'-kv')]",
"mapsServiceName":"[concat(variables('uniqueServiceName'),'-map')]",
"linuxWebAppPlanName":"[concat(variables('uniqueServiceName'),'-plan')]",
"ayalonWebAppName":"[concat(variables('uniqueServiceName'),'-webapp')]",
"textAnalyticsName":"[concat(variables('uniqueServiceName'),'-ta4h')]"
},
"resources": [
{
"type": "microsoft.insights/components",
"apiVersion": "2015-05-01",
"name": "[variables('insightsName')]",
"location": "[parameters('location')]",
"kind": "web",
"properties": {
"Application_Type": "web"
}
},
{
"type": "Microsoft.CognitiveServices/accounts",
"apiVersion": "2017-04-18",
"name": "[variables('luisPredictionName')]",
"location": "[parameters('luisLocation')]",
"sku": {
"name": "[parameters('luisSku')]"
},
"kind": "LUIS",
"properties": {
"statisticsEnabled": false
}
},
{
"apiVersion": "2017-04-18",
"name": "[variables('luisAuthoringName')]",
"location": "[parameters('luisLocation')]",
"type": "Microsoft.CognitiveServices/accounts",
"kind": "LUIS.Authoring",
"sku": {
"name": "[parameters('luisSku')]"
},
"properties": {
"statisticsEnabled": false
}
},
{
"condition":false,
"type": "Microsoft.HealthcareApis/services",
"apiVersion": "2019-09-16",
"name": "[variables('fhirApiName')]",
"location": "[parameters('location')]",
"kind": "fhir-R4",
"properties": {
"accessPolicies": [
{
"objectId": "[parameters('objectId')]"
}
],
"cosmosDbConfiguration": {
"offerThroughput": 400
},
"authenticationConfiguration": {
"authority": "https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47",
"audience": "https://azurehealthcareapis.com",
"smartProxyEnabled": false
},
"corsConfiguration": {
"origins": [],
"headers": [],
"methods": [],
"allowCredentials": false
}
}
},
{
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2016-10-01",
"name": "[variables('keyVaultName')]",
"location": "[parameters('location')]",
"properties": {
"sku": {
"family": "A",
"name": "Standard"
},
"tenantId": "[subscription().tenantId]",
"accessPolicies": [
{
"tenantId": "[subscription().tenantId]",
"objectId": "[parameters('objectId')]",
"permissions": {
"keys": [
],
"secrets": [
"get",
"list"
],
"certificates": [
]
}
}
],
"enabledForDeployment": false,
"enabledForDiskEncryption": false,
"enabledForTemplateDeployment": false
}
},
{
"type": "Microsoft.CognitiveServices/accounts",
"apiVersion": "2017-04-18",
"name": "[variables('textAnalyticsName')]",
"location": "[parameters('location')]",
"sku": {
"name": "F0"
},
"kind": "TextAnalytics",
"properties": {
"customSubDomainName": "[variables('textAnalyticsName')]"
}
},
{
"name": "[variables('mapsServiceName')]",
"type": "Microsoft.Maps/accounts",
"apiVersion": "2018-05-01",
"location": "global",
"tags": {},
"sku": {
"name": "S0"
}
},
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
"name": "[variables('linuxWebAppPlanName')]",
"location":"[parameters('location')]",
"sku": {
"name": "P2v2",
"tier": "PremiumV2",
"size": "P2v2",
"family": "Pv2",
"capacity": 1
},
"kind": "linux",
"properties": {
"perSiteScaling": false,
"maximumElasticWorkerCount": 1,
"isSpot": false,
"reserved": true,
"isXenon": false,
"hyperV": false,
"targetWorkerCount": 0,
"targetWorkerSizeId": 0
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"name": "[variables('ayalonWebAppName')]",
"location": "East US",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('linuxWebAppPlanName'))]"
],
"kind": "app,linux,container",
"properties": {
"enabled": true,
"hostNameSslStates": [
{
"name": "[concat(variables('ayalonWebAppName'), '.azurewebsites.net')]",
"sslState": "Disabled",
"hostType": "Standard"
},
{
"name": "[concat(variables('ayalonWebAppName'), '.scm.azurewebsites.net')]",
"sslState": "Disabled",
"hostType": "Repository"
}
],
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('linuxWebAppPlanName'))]",
"reserved": true,
"isXenon": false,
"hyperV": false,
"scmSiteAlsoStopped": false,
"clientAffinityEnabled": false,
"clientCertEnabled": false,
"hostNamesDisabled": false,
"containerSize": 0,
"dailyMemoryTimeQuota": 0,
"httpsOnly": false,
"redundancyMode": "None",
"siteConfig":{
"appSettings": [
{
"name":"Eula",
"value":"accept"
},
{
"name":"Billing",
"value":"[concat('https://',variables('textAnalyticsName'),'.cognitiveservices.azure.com')]"
},
{
"name":"ApiKey",
"value":"[listKeys(variables('textAnalyticsName'), '2017-04-18').key1]"
},
{
"name": "DOCKER_REGISTRY_SERVER_URL",
"value": "[parameters('ayalonDockerRegistryUrl')]"
},
{
"name": "DOCKER_REGISTRY_SERVER_USERNAME",
"value": "[parameters('ayalonDockerRegistryUser')]"
},
{
"name": "DOCKER_REGISTRY_SERVER_PASSWORD",
"value": "[parameters('ayalonDockerRegistryPassword')]"
}
]
}
}
},
{
"type":"Microsoft.Web/sites/config",
"apiVersion": "2018-11-01",
"name": "[concat(variables('ayalonWebAppName'), '/web')]",
"location": "East US",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('ayalonWebAppName'))]",
"[resourceId('Microsoft.CognitiveServices/accounts', variables('textAnalyticsName'))]"
],
"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": "[parameters('ayalonDockerImageName')]",
"requestTracingEnabled": false,
"remoteDebuggingEnabled": false,
"httpLoggingEnabled": false,
"logsDirectorySizeLimit": 35,
"detailedErrorLoggingEnabled": false,
"publishingUsername": "$ctm-bot",
"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
}
},
{
"type": "Microsoft.Web/sites/hostNameBindings",
"apiVersion": "2018-11-01",
"name": "[concat(variables('ayalonWebAppName'), '/', variables('ayalonWebAppName'), '.azurewebsites.net')]",
"location": "East US",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('ayalonWebAppName'))]"
],
"properties": {
"siteName": "ctm-bot",
"hostNameType": "Verified"
}
}
],
"outputs":{
"serviceUniqueName": {
"type":"string",
"value":"[variables('uniqueServiceName')]"
},
"instrumentationKey": {
"type": "string",
"value": "[reference(variables('insightsName'), '2015-05-01').instrumentationKey]"
},
"luisAuthotingKey": {
"type":"string",
"value":"[listKeys(variables('luisAuthoringName'),'2017-04-18').key1]"
},
"luisPredictionKey": {
"type":"string",
"value":"[listKeys(variables('luisPredictionName'),'2017-04-18').key1]"
},
"mapsKey": {
"type":"string",
"value": "[listKeys(variables('mapsServiceName'),'2018-05-01').primaryKey]"
}
}
}

35
bot-templates/sample.json Normal file
Просмотреть файл

@ -0,0 +1,35 @@
{
"scenarios": [
],
"authenticationProviders": [],
"skills": [],
"configuration": {
"language_understanding": {
"luis_models": {
"order_food": {
"application_id": "{luisApplicationId}",
"subscription_key": "{luisPredictionKey}",
"staging": false,
"verbose": true,
"region": "{luisLocation}",
"enabled": true,
"description": "order_food",
"scope": "Top Level Dialog",
"intents": [
"Order Food"
]
}
},
"intent_handler_map": {
"Order Food": {
"handler": "/scenarios/order_food"
}
}
},
"environment_variables": {
"variables": []
}
},
"localization": {
}
}

Просмотреть файл

@ -1,74 +0,0 @@
{
"scenarios": [
{
"name": "Agent Login",
"scenario_trigger": "agent_login",
"description": "Sets up current logged-in user to be an Agent",
"active": true,
"version": 1,
"code": {
"version": 3,
"steps": [
{
"id": "5bd3856a3903-62d73907d08cb8c9-8d7f",
"type": "beginScenario",
"designer": {
"xLocation": 469,
"yLocation": 96
},
"scenario": "/builtin/handoff/teams/agentlogin"
}
],
"interrupting": false,
"breaking": false,
"returningMessage": ""
}
}
],
"dataConnections": [],
"authenticationProviders": [],
"skills": [],
"localization": {
"system": [],
"custom": []
},
"files": [],
"configuration": {
"handoff": {
"teams": {
"tenantId": "{tenantId}",
"groupObjectId": "{groupObjectId}",
"clientId": "{clientId}",
"clientSecret": "{clientSecret}",
"organizerObjectId": "{organizerObjectId}"
},
"enable": true
},
"language_understanding": {
"custom_regexp_recognizers": {
"login": {
"enabled": true,
"description": "Login as an Agent",
"scope": "Top Level Dialog",
"intent": "login",
"expression": "/^login/"
},
"handoff": {
"enabled": true,
"description": "Handoff to an Agent",
"scope": "Top Level Dialog",
"intent": "handoff",
"expression": "/^handoff/"
}
},
"intent_handler_map": {
"login": {
"handler": "/builtin/handoff/teams/agentlogin"
},
"handoff": {
"handler": "/builtin/handoff"
}
}
}
}
}

371
lu/Booking.json Normal file
Просмотреть файл

@ -0,0 +1,371 @@
{
"luis_schema_version": "3.2.0",
"versionId": "0.2",
"name": "LUIS travel app",
"desc": "",
"culture": "en-us",
"tokenizerVersion": "1.0.0",
"intents": [
{
"name": "BookFlight"
},
{
"name": "None"
},
{
"name": "OrderFood"
},
{
"name": "Weather.GetForecast",
"inherits": {
"domain_name": "Weather",
"model_name": "GetForecast"
}
}
],
"entities": [
{
"name": "Airline",
"roles": [
"role1",
"role2"
]
},
{
"name": "DrinkSize",
"roles": []
},
{
"name": "Location",
"children": [
"LocationFrom",
"LocationTo"
],
"roles": []
},
{
"name": "PassengerCategory",
"children": [
"infant",
"child",
"adult"
],
"roles": []
},
{
"name": "TravelClass",
"children": [
"first",
"economy",
"business"
],
"roles": []
}
],
"composites": [
{
"name": "TicketsOrder",
"children": [
"PassengerCategory",
"TravelClass",
"number"
],
"roles": []
}
],
"closedLists": [
{
"name": "Coastal Cities",
"subLists": [
{
"canonicalForm": "Barcelona",
"list": [
"capital city of catalonia",
"bcn",
"second spanish city"
]
},
{
"canonicalForm": "madrid",
"list": [
"mad"
]
}
],
"roles": []
}
],
"patternAnyEntities": [
{
"name": "patternAny1",
"explicitList": [],
"roles": [
"role3",
"role4"
]
},
{
"name": "patternAny2",
"explicitList": [
"test1",
"test2"
],
"roles": []
}
],
"regex_entities": [
{
"name": "regex1",
"regexPattern": "[^a]+",
"roles": [
"role5",
"role6"
]
},
{
"name": "regex2",
"regexPattern": "[^b]+",
"roles": []
}
],
"prebuiltEntities": [
{
"name": "datetimeV2",
"roles": [
"role7"
]
},
{
"name": "number",
"roles": []
}
],
"model_features": [],
"regex_features": [],
"patterns": [
{
"pattern": "this is a {datetimeV2:role7}",
"intent": "None"
},
{
"pattern": "this is a {regex1:role5}",
"intent": "None"
},
{
"pattern": "this is a {Airline}",
"intent": "None"
}
],
"utterances": [
{
"text": "drive me home",
"intent": "None",
"entities": []
},
{
"text": "go to paris",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 6,
"endPos": 10
}
]
},
{
"text": "will it snow today",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "will it rain this weekend",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "book me a flight to paris",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 20,
"endPos": 24
}
]
},
{
"text": "i want to order lunch",
"intent": "OrderFood",
"entities": []
},
{
"text": "fly to cairo",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 7,
"endPos": 11
}
]
},
{
"text": "flight to seattle",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 10,
"endPos": 16
}
]
},
{
"text": "book me 2 adult business tickets to paris tomorrow on air france",
"intent": "BookFlight",
"entities": [
{
"entity": "TicketsOrder",
"startPos": 8,
"endPos": 23
},
{
"entity": "PassengerCategory",
"startPos": 10,
"endPos": 14
},
{
"entity": "TravelClass",
"startPos": 16,
"endPos": 23
},
{
"entity": "Location::LocationTo",
"startPos": 36,
"endPos": 40
},
{
"entity": "Airline",
"startPos": 54,
"endPos": 63
}
]
},
{
"text": "ticket to paris",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 10,
"endPos": 14
}
]
},
{
"text": "what is the weather in redmond ?",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "soliciting today's weather",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "forecast in celcius",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "will it be raining in ranchi",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "provide me by toronto weather please",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "i need to know the temperature at bangor, me",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "get the forcast for me",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "find out tomorrow's weather",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "book a flight from seattle to hong kong",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 30,
"endPos": 38
},
{
"entity": "Location::LocationFrom",
"startPos": 19,
"endPos": 25
}
]
},
{
"text": "buy a plane ticket to bangor me",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 22,
"endPos": 30
}
]
},
{
"text": "reservation for new york city",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 25,
"endPos": 28
},
{
"entity": "Location",
"startPos": 16,
"endPos": 23
}
]
},
{
"text": "ticket to portland",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 10,
"endPos": 17
}
]
}
],
"settings": [
{
"name": "NormalizeDiacritics",
"value": "false"
},
{
"name": "NormalizePunctuation",
"value": "false"
}
]
}

Просмотреть файл

@ -1,371 +0,0 @@
{
"luis_schema_version": "3.2.0",
"versionId": "0.1",
"name": "LUIS travel app",
"desc": "",
"culture": "en-us",
"tokenizerVersion": "1.0.0",
"intents": [
{
"name": "BookFlight"
},
{
"name": "None"
},
{
"name": "OrderFood"
},
{
"name": "Weather.GetForecast",
"inherits": {
"domain_name": "Weather",
"model_name": "GetForecast"
}
}
],
"entities": [
{
"name": "Airline",
"roles": [
"role1",
"role2"
]
},
{
"name": "DrinkSize",
"roles": []
},
{
"name": "Location",
"children": [
"LocationFrom",
"LocationTo"
],
"roles": []
},
{
"name": "PassengerCategory",
"children": [
"infant",
"child",
"adult"
],
"roles": []
},
{
"name": "TravelClass",
"children": [
"first",
"economy",
"business"
],
"roles": []
}
],
"composites": [
{
"name": "TicketsOrder",
"children": [
"PassengerCategory",
"TravelClass",
"number"
],
"roles": []
}
],
"closedLists": [
{
"name": "Coastal Cities",
"subLists": [
{
"canonicalForm": "Barcelona",
"list": [
"capital city of catalonia",
"bcn",
"second spanish city"
]
},
{
"canonicalForm": "madrid",
"list": [
"mad"
]
}
],
"roles": []
}
],
"patternAnyEntities": [
{
"name": "patternAny1",
"explicitList": [],
"roles": [
"role3",
"role4"
]
},
{
"name": "patternAny2",
"explicitList": [
"test1",
"test2"
],
"roles": []
}
],
"regex_entities": [
{
"name": "regex1",
"regexPattern": "[^a]+",
"roles": [
"role5",
"role6"
]
},
{
"name": "regex2",
"regexPattern": "[^b]+",
"roles": []
}
],
"prebuiltEntities": [
{
"name": "datetimeV2",
"roles": [
"role7"
]
},
{
"name": "number",
"roles": []
}
],
"model_features": [],
"regex_features": [],
"patterns": [
{
"pattern": "this is a {datetimeV2:role7}",
"intent": "None"
},
{
"pattern": "this is a {regex1:role5}",
"intent": "None"
},
{
"pattern": "this is a {Airline}",
"intent": "None"
}
],
"utterances": [
{
"text": "drive me home",
"intent": "None",
"entities": []
},
{
"text": "go to paris",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 6,
"endPos": 10
}
]
},
{
"text": "will it snow today",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "will it rain this weekend",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "book me a flight to paris",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 20,
"endPos": 24
}
]
},
{
"text": "i want to order lunch",
"intent": "OrderFood",
"entities": []
},
{
"text": "fly to cairo",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 7,
"endPos": 11
}
]
},
{
"text": "flight to seattle",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 10,
"endPos": 16
}
]
},
{
"text": "book me 2 adult business tickets to paris tomorrow on air france",
"intent": "BookFlight",
"entities": [
{
"entity": "TicketsOrder",
"startPos": 8,
"endPos": 23
},
{
"entity": "PassengerCategory",
"startPos": 10,
"endPos": 14
},
{
"entity": "TravelClass",
"startPos": 16,
"endPos": 23
},
{
"entity": "Location::LocationTo",
"startPos": 36,
"endPos": 40
},
{
"entity": "Airline",
"startPos": 54,
"endPos": 63
}
]
},
{
"text": "ticket to paris",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 10,
"endPos": 14
}
]
},
{
"text": "what is the weather in redmond ?",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "soliciting today's weather",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "forecast in celcius",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "will it be raining in ranchi",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "provide me by toronto weather please",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "i need to know the temperature at bangor, me",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "get the forcast for me",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "find out tomorrow's weather",
"intent": "Weather.GetForecast",
"entities": []
},
{
"text": "book a flight from seattle to hong kong",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 30,
"endPos": 38
},
{
"entity": "Location::LocationFrom",
"startPos": 19,
"endPos": 25
}
]
},
{
"text": "buy a plane ticket to bangor me",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 22,
"endPos": 30
}
]
},
{
"text": "reservation for new york city",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 25,
"endPos": 28
},
{
"entity": "Location",
"startPos": 16,
"endPos": 23
}
]
},
{
"text": "ticket to portland",
"intent": "BookFlight",
"entities": [
{
"entity": "Location::LocationTo",
"startPos": 10,
"endPos": 17
}
]
}
],
"settings": [
{
"name": "NormalizeDiacritics",
"value": "false"
},
{
"name": "NormalizePunctuation",
"value": "false"
}
]
}

Просмотреть файл

@ -1,72 +0,0 @@
Function ComputePassword {
$aesManaged = New-Object "System.Security.Cryptography.AesManaged"
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
$aesManaged.BlockSize = 128
$aesManaged.KeySize = 256
$aesManaged.GenerateKey()
return [System.Convert]::ToBase64String($aesManaged.Key)
}
Function CreateAppKey($fromDate, $durationInYears, $pw) {
$testKey = GenerateAppKey -fromDate $fromDate -durationInYears $durationInYears -pw $pw
$key = $testKey
return $key
}
Function GenerateAppKey ($fromDate, $durationInYears, $pw) {
$endDate = $fromDate.AddYears($durationInYears)
$keyId = (New-Guid).ToString();
$key = New-Object Microsoft.Open.AzureAD.Model.PasswordCredential($null, $endDate, $keyId, $fromDate, $pw)
return $key
}
Function AddResourcePermission($requiredAccess, $exposedPermissions, $requiredAccesses, $permissionType) {
foreach ($permission in $requiredAccesses.Trim().Split(" ")) {
$reqPermission = $null
$reqPermission = $exposedPermissions | Where-Object {$_.Value -contains $permission}
$resourceAccess = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$resourceAccess.Type = $permissionType
$resourceAccess.Id = $reqPermission.Id
$requiredAccess.ResourceAccess.Add($resourceAccess)
}
}
Function GetRequiredPermissions($requiredApplicationPermissions, $reqsp) {
$sp = $reqsp
$appid = $sp.AppId
$requiredAccess = New-Object Microsoft.Open.AzureAD.Model.RequiredResourceAccess
$requiredAccess.ResourceAppId = $appid
$requiredAccess.ResourceAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.ResourceAccess]
if ($requiredApplicationPermissions) {
AddResourcePermission $requiredAccess -exposedPermissions $sp.AppRoles -requiredAccesses $requiredApplicationPermissions -permissionType "Role"
}
return $requiredAccess
}
function New-HbsADApplication ($displayName, $applicationPermissions) {
$pw = ComputePassword
$fromDate = [System.DateTime]::Now
$appKey = CreateAppKey -fromDate $fromDate -durationInYears 10 -pw $pw
if ($null -ne $applicationPermissions) {
$graphsp = Get-AzureADServicePrincipal -SearchString "Microsoft Graph"
# $graphsp = Get-AzureADServicePrincipal -ObjectId "b19d498e-6687-4156-869a-2e8a95a9d659"
$requiredResourcesAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.RequiredResourceAccess]
$microsoftGraphRequiredPermissions = GetRequiredPermissions -reqsp $graphsp -requiredApplicationPermissions $applicationPermissions
$requiredResourcesAccess.Add($microsoftGraphRequiredPermissions)
}
$aadApplication = New-AzureADApplication -DisplayName $displayName `
-PasswordCredentials $appKey -AvailableToOtherTenants $true `
-RequiredResourceAccess $requiredResourcesAccess
New-AzureADServicePrincipal -AppId $aadApplication.AppId
return @{app = $aadApplication
creds=$appKey}
}
#New-HbsADApplication -displayName "Arie Test 3" -applicationPermissions ("Directory.Read.All", "Group.Read.All","OnlineMeetings.ReadWrite.All")

Просмотреть файл

@ -0,0 +1,130 @@
param(
[Parameter(Mandatory=$true)]
$saasSubscriptionId,
[Parameter(Mandatory=$true)]
[String]
$serviceName,
[Parameter(Mandatory=$true)]
[ValidateSet("US","EU")]
$botLocation,
[Parameter(Mandatory=$true)]
$ResourceGroup
)
. ./scripts/profile.ps1
. ./scripts/luis.ps1
. ./scripts/tenant.ps1
$context = Get-AzContext
$subscriptionId = $context.subscription.id
$luisPath = "./lu"
$restorePath = "./bot-templates"
Try {
Write-Host "Running Template Deployment..."
$output = New-AzResourceGroupDeployment -serviceName $serviceName `
-ResourceGroupName $ResourceGroup `
-saasSubscriptionId $saasSubscriptionId `
-TemplateFile "./arm-templates/azuredeploy-healthcarebot.json"
$output
$luisAuthLocation = $output.Parameters.luisAuthLocation.Value
$tenantId = $output.Outputs["serviceUniqueName"].Value
Write-Host "Creating Healthcare Bot Tenant $tenantId..." -NoNewline
$saasTenant = New-HbsTenant -name $serviceName -tenantId $tenantId `
-saasSubscriptionId $saasSubscriptionId `
-location $botLocation `
-instrumentationKey $output.Outputs["instrumentationKey"].Value
$saasTenant
# Uploads all the LUIS files. Each file is a luis application
$luisApplications = @{}
Get-ChildItem -Path $luisPath | ForEach-Object {
Write-Host "Get LUI Application '"$_.BaseName "'..." -NoNewline
$luisApplication = Get-LuisApplicationByName -appName $_.BaseName -location $luisAuthLocation `
-authKey $output.Outputs["luisAuthotingKey"].Value
if ($null -eq $luisApplication) {
Write-Host "Not found - Importing LUIS Application from " $_.BaseName "..." -NoNewline
$luisJSON = Get-Content -Raw -Path $_.FullName -Encoding UTF8
$luisApplicationId = Import-LuisApplication -appName $_.BaseName -luisJSON $luisJSON -location $luisAuthLocation `
-authKey $output.Outputs["luisAuthotingKey"].Value
Write-Host "Done" -ForegroundColor Green
} else {
$luisApplicationId = $luisApplication.id
Write-Host "Done" -ForegroundColor Green
}
$luisApplications[$_.BaseName] = $luisApplicationId
Write-Host "Assigning LUIS app " $_.BaseName " to LUIS account..." -NoNewline
$assignLuisApp = Set-LuisApplicationAccount -appId $luisApplicationId -subscriptionId $subscriptionId `
-resourceGroup $ResourceGroup -accountName $serviceName"-prediction" `
-location $luisAuthLocation -authKey $output.Outputs["luisAuthotingKey"].Value
Write-Host "Done" -ForegroundColor Green
Write-Host "Training LUIS app " $_.BaseName "..." -NoNewline
$trainResult = Invoke-TrainLuisApplication -appId $luisApplicationId -version "0.2" -location $luisAuthLocation `
-authKey $output.Outputs["luisAuthotingKey"].Value
if ($trainResult.status -ne "UpToDate") {
Write-Host "Waiting to finish training..." -NoNewline
$waitForTraningToFinish = $true
while ($waitForTraningToFinish) {
$trainStatus = Get-LuisApplicationTrainingStatus -appId $luisApplicationId -version "0.2" `
-location $luisAuthLocation `
-authKey $output.Outputs["luisAuthotingKey"].Value
$trainStatus | ForEach-Object {
if ($_.details.status -ne "Success") {
Write-Host "..." -NoNewline
Start-Sleep -Seconds 2
continue
}
}
$waitForTraningToFinish = $false
}
}
Write-Host "Done" -ForegroundColor Green
Write-Host "Publishing LUIS app " $_.BaseName "... " -NoNewline
$publishResult = Publish-LuisApplication -appId $luisApplicationId -version "0.2" -location $luisAuthLocation `
-authKey $output.Outputs["luisAuthotingKey"].Value
Write-Host "Published " -ForegroundColor Green
}
# Restore all the hbs templates
Get-ChildItem -Path $restorePath | ForEach-Object {
Write-Host "Importing template from " $_.BaseName "..." -NoNewline
$restoreJSON = Get-Content -Raw -Path $_.FullName
# Here you need to replace the place holders with real data
$restoreJSON = $restoreJSON.Replace('{luisApplicationId}', $luisApplications["Booking"])
$restoreJSON = $restoreJSON.Replace('{luisPredictionKey}', $output.Outputs["luisPredictionKey"].Value)
$restoreJSON = $restoreJSON.Replace('{luisLocation}', $output.Parameters.luisPredictionLocation.Value)
$saasTenant = Restore-HbsTenant -location $botLocation -tenant $saasTenant `
-data $restoreJSON -saasSubscriptionId $saasSubscriptionId
Write-Host "Done" -ForegroundColor Green
}
$webchatSecret = $saasTenant.webchat_secret
if ($botLocation -eq 'US') {
$portalEndpoint = "https://us.healthbot.microsoft.com/account"
}
else {
$portalEndpoint = "https://eu.healthbot.microsoft.com/account"
}
Select-Object @{n = "portal"; e = {"$portalEndpoint/$tenantId"}},
@{n = "SaaSApplication"; e = {"https://ms.portal.azure.com/#@/resource/providers/Microsoft.SaaS/saasresources/$saasSubscriptionId/overview"}},
@{n = "WebChat"; e ={"https://hatenantstorageprod.blob.core.windows.net/public-websites/webchat/index.html?s=$webchatSecret"}} -InputObject ""
}
Catch {
Write-Host
Write-Error -Exception $_.Exception
Write-Error -Exception $_.ErrorDetails.Message
}

Просмотреть файл

@ -1,95 +0,0 @@
<#
.SYNOPSIS
Created Bot Channel Registration ARM resource
.DESCRIPTION
Long description
.PARAMETER displayName
Parameter description
.PARAMETER botId
Parameter description
.PARAMETER appId
Parameter description
.PARAMETER subscriptionId
Parameter description
.PARAMETER resourceGroup
Parameter description
.PARAMETER planId
Parameter description
.EXAMPLE
An example
.NOTES
General notes
#>
function New-HbsBotRegistration {
param (
$displayName,
$botId,
$appId,
$subscriptionId,
$resourceGroup,
$planId
)
$headers = @{
Authorization = Get-AzBearerToken
}
$sku = "F0"
$endpoint = "https://bot-api-us.healthbot-$env.microsoft.com/bot/dynabot/$botId"
if ($planId -ne "free") {
$sku = "S1"
$endpoint = "https://bot-api-us.healthbot-$env.microsoft.com/bot-premium/dynabot/$botId"
}
$body = @{
location = "global"
sku = @{
name = $sku
}
kind = "bot"
properties = @{
name = $botId
displayName = $displayName
endpoint = $endpoint
msaAppId = $appId
enabledChannels = @("webchat", "directline","msteams")
configuredChannels = @("webchat", "directline","msteams")
}
} | ConvertTo-Json
$result = Invoke-WebRequest `
-Uri "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.BotService/botServices/$botId/?api-version=2017-12-01" `
-Method "put" `
-ContentType "application/json" `
-Headers $headers `
-Body $body
$botRegistration = ConvertFrom-Json $result.Content
return $botRegistration
}
function Get-HbsWebchatSecret {
param (
$resourceId
)
$headers = @{
Authorization = Get-AzBearerToken
}
$result = Invoke-WebRequest -Uri "https://management.azure.com/$resourceId/channels/WebChatChannel/listChannelWithKeys/?api-version=2017-12-01" `
-Method "post" `
-ContentType "application/json" `
-Headers $headers
$botChannel = ConvertFrom-Json $result.Content
return $botChannel.properties.properties.sites[0].key
}

Просмотреть файл

@ -1,77 +0,0 @@
. ./profile.ps1
. ./utils.ps1
. ./marketplace.ps1
. ./luis.ps1
. ./bot.ps1
. ./tenant.ps1
. ./ad.ps1
Write-Host "Running CTM-Blueprint..." -ForegroundColor Green
$context = Get-AzContext
$userId = $context.Account.id
$subscriptionId = $context.subscription.id
$planId = "free"
$offerId = "microsofthealthcarebot"
$luisAuthLocation = "westus"
$env="-dev"
$portalEndpoint = "https://us.healthbot$env.microsoft.com/account"
$hbsLocation = "US"
$luisAppFile = "../lu/LUIS.Triage.json"
$restorePath = "../bot-templates/teams-handoff.json"
$objectId =$(Get-AzureADUser -Filter "UserPrincipalName eq '$userId'").ObjectId
Write-Host ObjectId: $objectId
Try {
$resourceGroup = "CTM-Blueprint"
Write-Host "Running Template Deplpyment"
$output = New-AzResourceGroupDeployment -ResourceGroupName $resourceGroup -TemplateFile "../arm-templates/azuredeploy.json" -objectId $objectId
$output
$tenantId = $output.Outputs["serviceUniqueName"].Value
Write-Host "Creating SaaS Marketplace offering $offerId..." -NoNewline
#$marketplaceApp = New-HbsSaaSApplication -ResourceName $tenantId -planId $planId -offerId $offerId -SubscriptionId $subscriptionId
#$marketplaceApp
#$saasSubscriptionId = Split-Path $marketplaceApp.id -Leaf
$saasSubscriptionId = "1dc0e142-d927-c863-8dda-d33313c03004"
Write-Host "Creating HBS Tenant $tenantId..." -NoNewline
$saasTenant = New-HbsTenant -name $output.Parameters["serviceName"].Value -tenantId $tenantId `
-saasSubscriptionId $saasSubscriptionId `
-planId $planId -offerId $offerId `
-location $hbsLocation `
-instrumentationKey $output.Outputs["instrumentationKey"].Value
$saasTenant
Write-Host "Importing LUIS Application from $luisAppFile..." -NoNewline
$luisJSON = Get-Content -Raw -Path $luisAppFile
$luisApplicationId = Import-LuisApplication -luisJSON $luisJSON -location $luisAuthLocation -authKey $output.Outputs["luisAuthotingKey"].Value
Write-Host "Done" -ForegroundColor Green
Write-Host "Assigning LUIS app to LUIS account..." -NoNewline
$assignLuisApp = Set-LuisApplicationAccount -appId $luisApplicationId -subscriptionId $subscriptionId `
-resourceGroup $resourceGroup -accountName $tenantId"-prediction" -location $luisAuthLocation -authKey $output.Outputs["luisAuthotingKey"].Value
Write-Host "Done" -ForegroundColor Green
Write-Host "Importing template from $restorePath..." -NoNewline
$restoreJSON = Get-Content -Raw -Path $restorePath
$saasTenant = Restore-HbsTenant -location $hbsLocation -tenant $saasTenant -data $restoreJSON -saasSubscriptionId $saasSubscriptionId
Write-Host "Done" -ForegroundColor Green
$saasTenant
Write-Host "Your Healthcare Bot is now ready! You can access various resources below:" -ForegroundColor Green
Write-Host " - Management Portal: " $portalEndpoint/$tenantId -ForegroundColor Green
Write-Host " - Marketplace SaaS Application: https://ms.portal.azure.com/#@/resource/providers/Microsoft.SaaS/saasresources/$saasSubscriptionId/overview" -ForegroundColor Green
Write-Host " - Teams Channel Client: https://teams.microsoft.com/l/chat/0/0?users=28:$appId" -ForegroundColor Green
Write-Host " - WebChat Client: https://hatenantstorageprod.blob.core.windows.net/public-websites/webchat/index.html?s=$webchatSecret" -ForegroundColor Green
}
Catch {
Write-Host
Write-Error -Exception $_.Exception
}

Просмотреть файл

@ -1,10 +1,27 @@
function Import-LuisApplication($luisJSON, $location, $authKey) {
function Get-LuisApplicationByName($appName, $location, $authKey) {
$headers = @{
"Ocp-Apim-Subscription-Key" = $authKey
}
$result = Invoke-WebRequest -Uri "https://$location.api.cognitive.microsoft.com/luis/api/v2.0/apps" `
-Method "get" `
-ContentType "application/json" `
-Headers $headers
$luisApplicationResult = ConvertFrom-Json $result.Content
$app = $luisApplicationResult | Where-Object {$_.name -eq $appName}
return $app
}
function Import-LuisApplication($appName, $luisJSON, $location, $authKey) {
$headers = @{
"Ocp-Apim-Subscription-Key" = $authKey
}
$result = Invoke-WebRequest -Uri "https://$location.api.cognitive.microsoft.com/luis/api/v2.0/apps/import" `
$result = Invoke-WebRequest -Uri "https://$location.api.cognitive.microsoft.com/luis/api/v2.0/apps/import?appName=$appName" `
-Method "post" `
-ContentType "application/json" `
-Headers $headers `
@ -35,3 +52,51 @@ function Set-LuisApplicationAccount($appId, $subscriptionId, $resourceGroup, $ac
$assignResult = ConvertFrom-Json $result.Content
return $assignResult
}
function Invoke-TrainLuisApplication($appId, $version, $location, $authKey) {
$headers = @{
"Ocp-Apim-Subscription-Key" = $authKey
}
$body = @{
} | ConvertTo-Json
$result = Invoke-WebRequest -Uri "https://$location.api.cognitive.microsoft.com/luis/api/v2.0/apps/$appId/versions/$version/train" `
-Method "post" `
-ContentType "application/json" `
-Headers $headers `
-Body $body
$trainResult = ConvertFrom-Json $result.Content
return $trainResult
}
function Get-LuisApplicationTrainingStatus($appId, $version, $location, $authKey) {
$headers = @{
"Ocp-Apim-Subscription-Key" = $authKey
}
$result = Invoke-WebRequest -Uri "https://$location.api.cognitive.microsoft.com/luis/api/v2.0/apps/$appId/versions/$version/train" `
-Method "get" `
-ContentType "application/json" `
-Headers $headers
$trainResult = ConvertFrom-Json $result.Content
return $trainResult
}
function Publish-LuisApplication($appId, $version, $location, $authKey) {
$headers = @{
"Ocp-Apim-Subscription-Key" = $authKey
}
$body = @{
versionId= $version
isStaging = $false
directVersionPublish = $false
} | ConvertTo-Json
$result = Invoke-WebRequest -Uri "https://$location.api.cognitive.microsoft.com/luis/api/v2.0/apps/$appId/publish" `
-Method "post" `
-ContentType "application/json" `
-Headers $headers `
-Body $body
$publishResults = ConvertFrom-Json $result.Content
return $publishResults
}

Просмотреть файл

@ -1,11 +1,25 @@
<#
.SYNOPSIS
Create SaaS Marketplace resource that will be used for charging for the Healthcare Bot Service
#>
. ./scripts/profile.ps1
function New-HbsSaaSApplication() {
param(
$ResourceName,
$SubscriptionId,
$planId,
$offerId
[Parameter(Mandatory=$true)]
[String]
$name,
[Parameter()]
[String]
[ValidateSet('free','s1','s2','s3','s4','s5')]
$planId = "free",
$offerId = "microsofthealthcarebot"
)
$context = Get-AzContext
$subscriptionId = $context.subscription.id
$accessToken = Get-AzBearerToken
$headers = @{
@ -15,13 +29,13 @@ function New-HbsSaaSApplication() {
Properties = @{
PublisherId = "microsoft-hcb"
OfferId = $offerId
SaasResourceName = $ResourceName
SaasResourceName = $name
SKUId = $planId
PaymentChannelType = "SubscriptionDelegated"
Quantity = 1
TermId = "hjdtn7tfnxcy"
PaymentChannelMetadata = @{
AzureSubscriptionId = $SubscriptionId
AzureSubscriptionId = $subscriptionId
}
}
}
@ -31,7 +45,12 @@ function New-HbsSaaSApplication() {
-Body $body -ContentType "application/json"
if ($result.StatusCode -eq 202) {
$location = $result.Headers['location'];
if ($result.Headers['location'] -is [array]) {
$location = $result.Headers['location'][0];
}
else {
$location = $result.Headers['location'];
}
$r = Invoke-WebRequest -Uri $location -Method 'get' -Headers $headers -ContentType "application/json"
if ($null -eq $r) {
return
@ -42,11 +61,26 @@ function New-HbsSaaSApplication() {
$r = Invoke-WebRequest -Uri $location -Method 'get' -Headers $headers -ContentType "application/json"
}
$operationStatus = ConvertFrom-Json $r.Content
Write-Host
if ($operationStatus.properties.status -eq "PendingFulfillmentStart") {
return $operationStatus
$id = Split-Path $operationStatus.id -Leaf
return $id
}
else {
Write-Error "Failed to create" $ResourceName
Write-Error "Failed to create" $name
}
}
}
function Get-HbsSaaSApplication() {
$accessToken = Get-AzBearerToken
$headers = @{
Authorization = $accessToken
}
$result = Invoke-WebRequest -Uri https://management.azure.com/providers/microsoft.saas/saasresources?api-version=2018-03-01-beta `
-Method 'get' -Headers $headers `
-Body $body -ContentType "application/json"
$saasApplications = ConvertFrom-Json $result.Content
return $saasApplications.value
}

Просмотреть файл

@ -1,99 +0,0 @@
. ./profile.ps1
. ./utils.ps1
. ./marketplace.ps1
. ./luis.ps1
. ./bot.ps1
. ./tenant.ps1
. ./ad.ps1
$Name = "CTM-Bot"
$tenantId = Get-HbsUniqueTenantId -Name $Name
$resourceGroup = "CTM-Blueprint"
$context = Get-AzContext
$subscriptionId = $context.subscription.id
$planId = "free"
$offerId = "microsofthealthcarebot"
$location = "US"
$ds_location = "eastus"
$luisAuthLocation = "westus"
$env = "dev"
$luisAppFile = "../lu/LUIS.Triage.json"
$restorePath = "../bot-templates/teams-handoff.json"
$portalEndpoint = "https://us.healthbot-$env.microsoft.com/account"
$createTenantOnly = $false
Try {
if ($createTenantOnly -eq $false) {
Write-Host "Creating/Using ResourceGroup $resourceGroup..." -NoNewline
$rg = New-ResourceGroupIfNeeded -resourceGroup $resourceGroup -location $ds_location
Write-Host "Done $($rg.ResourceGroupName)" -ForegroundColor Green
Write-Host "Creating LUIS Authoring Account $tenantId-authoring..." -NoNewline
$luisAuthoring = New-AzCognitiveServicesAccount -ResourceGroupName $resourceGroup -Name $tenantId-authoring `
-Type LUIS.Authoring -SkuName "F0" -Location $luisAuthLocation -ErrorAction Stop
$luisAuthoringKey = Get-AzCognitiveServicesAccountKey -ResourceGroupName $resourceGroup -Name $tenantId-authoring
Write-Host "Done $($luisAuthoring.AccountName)" -ForegroundColor Green
Write-Host "Creating LUIS Prediction Account $tenantId..." -NoNewline
$luis = New-AzCognitiveServicesAccount -ResourceGroupName $resourceGroup -Name $tenantId `
-Type LUIS -SkuName "S0" -Location $luisAuthLocation -ErrorAction Stop
$luisKey = Get-AzCognitiveServicesAccountKey -ResourceGroupName $resourceGroup -Name $tenantId
Write-Host "Done $($luis.AccountName) Key: $($luisKey.Key1)" -ForegroundColor Green
Write-Host "Creating Application Insights $tenantId..." -NoNewline
$appInsights = New-AzApplicationInsights -ResourceGroupName $resourceGroup -Name $tenantId -Location $ds_location -ErrorAction Stop
Write-Host "Done $($appInsights.Name)" -ForegroundColor Green
}
Write-Host "Creating SaaS Marketplace offering $offerId..." -NoNewline
$marketplaceApp = New-HbsSaaSApplication -ResourceName $Name -planId $planId -offerId $offerId -SubscriptionId $subscriptionId
Write-Host "Done $($marketplaceApp.name)" -ForegroundColor Green
$saasSubscriptionId = Split-Path $marketplaceApp.id -Leaf
Write-Host "Creating HBS Tenant $tenantId..." -NoNewline
$saasTenant = New-HbsTenant -name $Name -tenantId $tenantId `
-saasSubscriptionId $saasSubscriptionId `
-planId $planId -offerId $offerId `
-location $location `
-instrumentationKey $appInsights.InstrumentationKey
Write-Host "Done" -ForegroundColor Green
Write-Host "Importing LUIS Application from $luisAppFile..." -NoNewline
$luisJSON = Get-Content -Raw -Path $luisAppFile
$luisApplicationId = Import-LuisApplication -luisJSON $luisJSON -location $luisAuthLocation -authKey $luisAuthoringKey.Key1
Write-Host "Done" -ForegroundColor Green
Write-Host "Assigning LUIS app to LUIS account..." -NoNewline
$assignLuisApp = Set-LuisApplicationAccount -appId $luisApplicationId -subscriptionId $subscriptionId `
-resourceGroup $resourceGroup -accountName $tenantId -location $luisAuthLocation -authKey $luisAuthoringKey.Key1
Write-Host "Done" -ForegroundColor Green
# Write-Host "Creating MS Graph API Service principle $tenantId-graph-sp..." -NoNewline
# $spApp = New-HbsADApplication -displayName $tenantId-graph-sp
# # -applicationPermissions "Directory.Read.All Group.Read.All OnlineMeetings.ReadWrite.All"
# Write-Host "Done" -ForegroundColor Green
Write-Host "Importing template from $restorePath..." -NoNewline
$restoreJSON = Get-Content -Raw -Path $restorePath
# $restoreJSON = $restoreJSON.Replace("{clientId}", $spApp.app.AppId)
# $restoreJSON = $restoreJSON.Replace("{clientSecret}", $spApp.creds.Value)
# $restoreJSON = $restoreJSON.Replace("{tenantId}", (Get-AzureADTenantDetail).ObjectId)
$saasTenant = Restore-HbsTenant -location $location -tenant $saasTenant -data $restoreJSON -saasSubscriptionId $saasSubscriptionId
Write-Host "Done" -ForegroundColor Green
$saasTenant
Write-Host "Your Healthcare Bot is now ready! You can access various resources below:" -ForegroundColor Green
Write-Host " - Management Portal: " $portalEndpoint/$tenantId -ForegroundColor Green
Write-Host " - Marketplace SaaS Application: https://ms.portal.azure.com/#@/resource/providers/Microsoft.SaaS/saasresources/$saasSubscriptionId/overview" -ForegroundColor Green
Write-Host " - Teams Channel Client: https://teams.microsoft.com/l/chat/0/0?users=28:$appId" -ForegroundColor Green
Write-Host " - WebChat Client: https://hatenantstorageprod.blob.core.windows.net/public-websites/webchat/index.html?s=$webchatSecret" -ForegroundColor Green
}
Catch {
Write-Host
Write-Error -Exception $_.Exception
}

Просмотреть файл

@ -1,5 +1,5 @@
#$onboardingEndpoint = "https://admin.healthbot-dev.microsoft.com/api"
$onboardingEndpoint = "http://localhost:8083/api"
$onboardingEndpoint = "https://admin.healthbot.microsoft.com/api"
#$onboardingEndpoint = "http://localhost:8083/api"
function New-HbsTenant {
param (
@ -8,8 +8,6 @@ function New-HbsTenant {
$name,
$tenantId,
$saasSubscriptionId,
$planId,
$offerId,
$location,
$instrumentationKey
)
@ -20,8 +18,6 @@ function New-HbsTenant {
email = (Get-AzContext).Account.Id
usermanagement = "portal"
saasSubscriptionId = $saasSubscriptionId
planId = $planId
offerId = $offerId
location = $location
instrumentationKey = $instrumentationKey
} | ConvertTo-Json
@ -30,6 +26,7 @@ function New-HbsTenant {
Authorization = Get-AzBearerToken
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$result = Invoke-WebRequest -Uri $onboardingEndpoint/saas/tenants/?api-version=2019-07-01 `
-Method "post" `
-ContentType "application/json" `

Просмотреть файл

@ -1,27 +0,0 @@
function Get-RandomCharacters($length, $characters) {
$random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length }
$private:ofs = ""
return [String]$characters[$random]
}
function Get-HbsUniqueTenantId {
param (
$Name
)
$cleanName = ($Name -replace "[^a-zA-Z0-9_-]*", "").ToLower();
$suffix = Get-RandomCharacters -length 7 -characters 'abcdefghiklmnoprstuvwxyz1234567890'
return "$cleanName-$suffix"
}
function New-ResourceGroupIfNeeded {
param (
$resourceGroup,
$location
)
$rg = Get-AzResourceGroup -Name $resourceGroup -ErrorVariable noRg -ErrorAction SilentlyContinue
if ($noRg) {
$rg = New-AzResourceGroup -Name $resourceGroup -Location $location
}
return $rg
}

Просмотреть файл

@ -1,16 +0,0 @@
{
"folders": [
{
"path": "."
},
{
"path": "../HealthBotOnboarding"
},
{
"path": "../HealthBOT"
}
],
"settings": {
"editor.minimap.enabled": false
}
}