Vba alpha #39

Merged
rodrigorodriguez merged 16 commits from vba-alpha into master 2018-12-06 12:48:06 +00:00
57 changed files with 1731 additions and 1298 deletions

2
.gitignore vendored
View file

@ -13,3 +13,5 @@
/packages/default.gbui/node_modules
/tmp
/work
/packages/default.gbdialog/bot.js
/packages/default.gbdialog/bot.ts

View file

@ -1,7 +1,7 @@
{
"trailingComma": "all",
"trailingComma": "none",
"tabWidth": 2,
"printWidth": 80,
"printWidth": 120,
"arrowParens": "avoid",
"semi": true,
"singleQuote": true

View file

@ -22,13 +22,11 @@ When logging a bug, please be sure to include the following:
We also accept suggestions in the issue tracker.
In general, things we find useful when reviewing suggestions are:
* A description of the problem you're trying to solve
* An overview of the suggested solution
* Examples of how the suggestion would work in various places
# Instructions for Contributing Code
## Contributing bug fixes

7
LOCALIZATION.md Normal file
View file

@ -0,0 +1,7 @@
# Localization in General Bots
## .gbapp
The localization is done by adding a strings.ts file to the root of the .gbapp package.

0
SAMPLES.md Normal file
View file

438
package-lock.json generated
View file

@ -1059,40 +1059,56 @@
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
"dev": true
},
"@octokit/rest": {
"version": "15.17.0",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.17.0.tgz",
"integrity": "sha512-tN16FJOGBPxt9QtPfl8yVbbuik3bQ7EI66zcX2XDh05Wcs8t+7mVEE3SWtCeK/Qm0RTLCeFQgGzuvkbD2J6cEg==",
"@octokit/endpoint": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-3.1.1.tgz",
"integrity": "sha512-KPkoTvKwCTetu/UqonLs1pfwFO5HAqTv/Ksp9y4NAg//ZgUCpvJsT4Hrst85uEzJvkB8+LxKyR4Bfv2X8O4cmQ==",
"dev": true,
"requires": {
"before-after-hook": "^1.1.0",
"btoa-lite": "^1.0.0",
"debug": "^3.1.0",
"http-proxy-agent": "^2.1.0",
"https-proxy-agent": "^2.2.0",
"lodash": "^4.17.4",
"node-fetch": "^2.1.1",
"universal-user-agent": "^2.0.0",
"deepmerge": "3.0.0",
"is-plain-object": "^2.0.4",
"universal-user-agent": "^2.0.1",
"url-template": "^2.0.8"
}
},
"@octokit/request": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-2.2.0.tgz",
"integrity": "sha512-4P9EbwKZ4xfyupVMb3KVuHmM+aO2fye3nufjGKz/qDssvdJj9Rlx44O0FdFvUp4kIzToy3AHLTOulEIDAL+dpg==",
"dev": true,
"requires": {
"@octokit/endpoint": "^3.0.0",
"is-plain-object": "^2.0.4",
"node-fetch": "^2.3.0",
"universal-user-agent": "^2.0.1"
},
"dependencies": {
"debug": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"node-fetch": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.2.1.tgz",
"integrity": "sha512-ObXBpNCD3A/vYQiQtEWl7DuqjAXjfptYFuGHLdPl5U19/6kJuZV+8uMHLrkj3wJrJoyfg4nhgyFixZdaZoAiEQ==",
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz",
"integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==",
"dev": true
}
}
},
"@octokit/rest": {
"version": "16.1.0",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.1.0.tgz",
"integrity": "sha512-/D1XokSycOE+prxxI2r9cxssiLMqcr+BsEUjdruC67puEEjNJjJoRIkuA1b20jOkX5Ue3Rz99Mu9rTnNmjetUA==",
"dev": true,
"requires": {
"@octokit/request": "2.2.0",
"before-after-hook": "^1.2.0",
"btoa-lite": "^1.0.0",
"lodash.get": "^4.4.2",
"lodash.pick": "^4.4.0",
"lodash.set": "^4.3.2",
"lodash.uniq": "^4.5.0",
"octokit-pagination-methods": "^1.1.0",
"universal-user-agent": "^2.0.0",
"url-template": "^2.0.8"
}
},
"@semantic-release/changelog": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-3.0.1.tgz",
@ -1243,12 +1259,12 @@
}
},
"@semantic-release/github": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-5.2.1.tgz",
"integrity": "sha512-EVh5MCMOSl5WfOIum+k7fb7ZaDBcZAepPvtMrJOn8HKa9MERK6PgT76OKro+tReWjT1PnGiaKjofjyRC4BhN6Q==",
"version": "5.2.5",
"resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-5.2.5.tgz",
"integrity": "sha512-myO00q84CyfyzaEZ4OdA7GOMCQKd+juZd5g2Cloh4jV6CyiMyWflZ629RH99wjAVUiwMKnvX2SQ5XPFvO1+FCw==",
"dev": true,
"requires": {
"@octokit/rest": "^15.13.1",
"@octokit/rest": "^16.0.1",
"@semantic-release/error": "^2.2.0",
"aggregate-error": "^1.0.0",
"bottleneck": "^2.0.1",
@ -1277,9 +1293,9 @@
}
},
"mime": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
"integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz",
"integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==",
"dev": true
}
}
@ -1638,9 +1654,9 @@
}
},
"@types/sequelize": {
"version": "4.27.31",
"resolved": "https://registry.npmjs.org/@types/sequelize/-/sequelize-4.27.31.tgz",
"integrity": "sha512-Toqr7ETevM3uewzG3ALHcnFuKOlj1xSsAebQpBDwIdysGSqc5rRPM3EhKVfUc8/aMWTsHnFySGZ7r3JugLDkMg==",
"version": "4.27.32",
"resolved": "https://registry.npmjs.org/@types/sequelize/-/sequelize-4.27.32.tgz",
"integrity": "sha512-M4iFjZLXDdjqnyKaxz9I5XlVFr4/WBvFYyd8oLU5YsKcXGeppMl6nNo9EBsdDgOOirJcyH2JkJEUhbhegZ6MqA==",
"dev": true,
"requires": {
"@types/bluebird": "*",
@ -2966,9 +2982,9 @@
}
},
"bluebird": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz",
"integrity": "sha1-G+CQjgVKdRdUVJwnBInBUF1KsVo="
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz",
"integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw=="
},
"body-parser": {
"version": "1.18.3",
@ -2996,37 +3012,107 @@
}
},
"botbuilder": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.1.5.tgz",
"integrity": "sha512-7OZqUqS3jhse2xq9wdG4jaE1mpPcsgQid+wPE2gv17/KwChHAZ5ZyXEmjoc6LP3Twmsapj6h0R4ni36bcst/xg==",
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.1.7.tgz",
"integrity": "sha512-AlZhvjeqiCpeWGN1TkqBi09l6f0spYIh0Xzc4rJYF8feCFi4k2FEYC1IpiiOAtYhEBeQ9SOGFcUUwPaLmsI3Xg==",
"requires": {
"@types/filenamify": "^2.0.1",
"@types/node": "^9.3.0",
"async-file": "^2.0.2",
"botbuilder-core": "^4.1.5",
"botframework-connector": "^4.1.5",
"botbuilder-core": "^4.1.7",
"botframework-connector": "^4.1.7",
"filenamify": "^2.0.0",
"rimraf": "^2.6.2"
},
"dependencies": {
"@types/jsonwebtoken": {
"version": "7.2.8",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-7.2.8.tgz",
"integrity": "sha512-XENN3YzEB8D6TiUww0O8SRznzy1v+77lH7UmuN54xq/IHIsyWjWOzZuFFTtoiRuaE782uAoRwBe/wwow+vQXZw==",
"requires": {
"@types/node": "*"
}
},
"@types/node": {
"version": "9.6.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.36.tgz",
"integrity": "sha512-Fbw+AdRLL01vv7Rk7bYaNPecqmKoinJHGbpKnDpbUZmUj/0vj3nLqPQ4CNBzr3q2zso6Cq/4jHoCAdH78fvJrw=="
"version": "9.6.40",
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.40.tgz",
"integrity": "sha512-M3HHoXXndsho/sTbQML2BJr7/uwNhMg8P0D4lb+UsM65JQZx268faiz9hKpY4FpocWqpwlLwa8vevw8hLtKjOw=="
},
"base64url": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
"integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A=="
},
"botbuilder-core": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/botbuilder-core/-/botbuilder-core-4.1.7.tgz",
"integrity": "sha512-kfNOOpHVDLNdpYVMAefWjETXI4VsnDHgucEfKgANcCUrXmsYETlioHOCngUWLrFcaeVMJodeZvafIYl5NTgy0A==",
"requires": {
"assert": "^1.4.1",
"botframework-schema": "^4.1.7"
}
},
"botframework-connector": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/botframework-connector/-/botframework-connector-4.1.7.tgz",
"integrity": "sha512-aIGY0acc/cMxmg1o+06HqReOjNC8qxbmPJDg+wDgaAwr85bSrDZE1CbyITcj2OqPG/QQ7VM3YzpPAZPlKkDWoQ==",
"requires": {
"@types/jsonwebtoken": "7.2.8",
"@types/node": "^9.3.0",
"@types/request": "^2.47.0",
"base64url": "^3.0.0",
"botframework-schema": "^4.1.7",
"jsonwebtoken": "8.0.1",
"ms-rest-azure-js": "1.0.176",
"ms-rest-js": "1.0.455",
"request": "^2.87.0",
"rsa-pem-from-mod-exp": "^0.8.4"
}
},
"botframework-schema": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/botframework-schema/-/botframework-schema-4.1.7.tgz",
"integrity": "sha512-vPb5gHldmTIpUFx5uCdv/4XEsouMkXvSfQS2zsAC3VqAo29YESHYzNbr5HecRaUveb48NZ27+Djm0U0mLFxe9Q==",
"requires": {
"@types/node": "^9.3.0",
"ms-rest-js": "1.0.455"
}
},
"ms-rest-azure-js": {
"version": "1.0.176",
"resolved": "https://registry.npmjs.org/ms-rest-azure-js/-/ms-rest-azure-js-1.0.176.tgz",
"integrity": "sha512-qtEBpSf/1nJ0/m1jGLkHISRnpOeHUp5n4SvzZRdFeYnGF4SQx9v/fl8a8ZwEmyujmgbUwyLNM9qKpH5PmW7pZg==",
"requires": {
"ms-rest-js": "^1.0.443",
"tslib": "^1.9.2"
}
},
"ms-rest-js": {
"version": "1.0.455",
"resolved": "https://registry.npmjs.org/ms-rest-js/-/ms-rest-js-1.0.455.tgz",
"integrity": "sha512-RUDnFFNhk4ZdvOACg0yfaxmp5OzNwUcTIwgh/rVBeuNzgA7hOoVh5zFW06XmOtaBHXL2Bu/vWoQtzloEUlv9tw==",
"requires": {
"axios": "^0.18.0",
"form-data": "^2.3.2",
"tough-cookie": "^2.4.3",
"tslib": "^1.9.2",
"uuid": "^3.2.1",
"xml2js": "^0.4.19"
}
}
}
},
"botbuilder-ai": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/botbuilder-ai/-/botbuilder-ai-4.1.5.tgz",
"integrity": "sha512-m9NGPsJ12dHey+/Or7516I4tj8EID1U8W2rnVwn3T9OpRMrL4XM9TloItNBqHhpAy1q7YfglxdsZP5721TMwvg==",
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/botbuilder-ai/-/botbuilder-ai-4.1.7.tgz",
"integrity": "sha512-TYYe7GrR9nZ55gJ+UBkbJnHea/LkJSwCjDuBncmRMsARGwxhYsBhLkkigY1Hzbl6+OuuPwZP/6OR0Xk9JzwgHA==",
"requires": {
"@microsoft/recognizers-text-date-time": "1.1.2",
"@types/html-entities": "^1.2.16",
"@types/node": "^9.3.0",
"@types/request-promise-native": "^1.0.10",
"azure-cognitiveservices-luis-runtime": "^1.0.0",
"botbuilder": "^4.1.5",
"botbuilder": "^4.1.7",
"html-entities": "^1.2.1",
"moment": "^2.20.1",
"ms-rest": "^2.3.6",
@ -3036,29 +3122,29 @@
},
"dependencies": {
"@types/node": {
"version": "9.6.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.36.tgz",
"integrity": "sha512-Fbw+AdRLL01vv7Rk7bYaNPecqmKoinJHGbpKnDpbUZmUj/0vj3nLqPQ4CNBzr3q2zso6Cq/4jHoCAdH78fvJrw=="
"version": "9.6.40",
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.40.tgz",
"integrity": "sha512-M3HHoXXndsho/sTbQML2BJr7/uwNhMg8P0D4lb+UsM65JQZx268faiz9hKpY4FpocWqpwlLwa8vevw8hLtKjOw=="
}
}
},
"botbuilder-azure": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/botbuilder-azure/-/botbuilder-azure-4.1.5.tgz",
"integrity": "sha512-3iyapL4wTm3D6QtkkQl4NbV8CtGzZjCetrWPLIrB04QBd6MM1AWIigAyo66KRl52O5/7k0KRpz0ZtIqwK4nRwA==",
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/botbuilder-azure/-/botbuilder-azure-4.1.7.tgz",
"integrity": "sha512-wdq+8Fgm8EscZqsg2lB+JJ4mtukQHOVm+mRpsgjFrYB84/SB0k3Z2wT4PHVNdNdvnSHAWOAXzigIJhPSIv9Hcw==",
"requires": {
"@types/node": "^9.3.0",
"azure-storage": "^2.10.2",
"botbuilder": "^4.1.5",
"botbuilder": "^4.1.7",
"documentdb": "1.14.5",
"flat": "^4.0.0",
"semaphore": "^1.1.0"
},
"dependencies": {
"@types/node": {
"version": "9.6.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.36.tgz",
"integrity": "sha512-Fbw+AdRLL01vv7Rk7bYaNPecqmKoinJHGbpKnDpbUZmUj/0vj3nLqPQ4CNBzr3q2zso6Cq/4jHoCAdH78fvJrw=="
"version": "9.6.40",
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.40.tgz",
"integrity": "sha512-M3HHoXXndsho/sTbQML2BJr7/uwNhMg8P0D4lb+UsM65JQZx268faiz9hKpY4FpocWqpwlLwa8vevw8hLtKjOw=="
}
}
},
@ -3227,16 +3313,16 @@
}
},
"botbuilder-dialogs": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/botbuilder-dialogs/-/botbuilder-dialogs-4.1.5.tgz",
"integrity": "sha512-tLBe+clYg6VWsarR3a6NOzK8RqjJ3mXA4IBsQNSiqxIbEu/jjQTZ8OoZceye5rWfa67cbm2aihShqFB5WZX3nA==",
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/botbuilder-dialogs/-/botbuilder-dialogs-4.1.7.tgz",
"integrity": "sha512-XDR6HT5xJFMrepT5TOjuvDIz0/jpuemi4hGNjW7a0klucfXroSB3yFvg6aVinbjVE5uAejnEwoRAXevFZRg+RQ==",
"requires": {
"@microsoft/recognizers-text-choice": "1.1.2",
"@microsoft/recognizers-text-date-time": "1.1.2",
"@microsoft/recognizers-text-number": "1.1.2",
"@microsoft/recognizers-text-suite": "1.1.2",
"@types/node": "^9.3.0",
"botbuilder-core": "^4.1.5"
"botbuilder-core": "^4.1.7"
},
"dependencies": {
"@microsoft/recognizers-text-choice": {
@ -3274,9 +3360,40 @@
}
},
"@types/node": {
"version": "9.6.36",
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.36.tgz",
"integrity": "sha512-Fbw+AdRLL01vv7Rk7bYaNPecqmKoinJHGbpKnDpbUZmUj/0vj3nLqPQ4CNBzr3q2zso6Cq/4jHoCAdH78fvJrw=="
"version": "9.6.40",
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.40.tgz",
"integrity": "sha512-M3HHoXXndsho/sTbQML2BJr7/uwNhMg8P0D4lb+UsM65JQZx268faiz9hKpY4FpocWqpwlLwa8vevw8hLtKjOw=="
},
"botbuilder-core": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/botbuilder-core/-/botbuilder-core-4.1.7.tgz",
"integrity": "sha512-kfNOOpHVDLNdpYVMAefWjETXI4VsnDHgucEfKgANcCUrXmsYETlioHOCngUWLrFcaeVMJodeZvafIYl5NTgy0A==",
"requires": {
"assert": "^1.4.1",
"botframework-schema": "^4.1.7"
}
},
"botframework-schema": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/botframework-schema/-/botframework-schema-4.1.7.tgz",
"integrity": "sha512-vPb5gHldmTIpUFx5uCdv/4XEsouMkXvSfQS2zsAC3VqAo29YESHYzNbr5HecRaUveb48NZ27+Djm0U0mLFxe9Q==",
"requires": {
"@types/node": "^9.3.0",
"ms-rest-js": "1.0.455"
}
},
"ms-rest-js": {
"version": "1.0.455",
"resolved": "https://registry.npmjs.org/ms-rest-js/-/ms-rest-js-1.0.455.tgz",
"integrity": "sha512-RUDnFFNhk4ZdvOACg0yfaxmp5OzNwUcTIwgh/rVBeuNzgA7hOoVh5zFW06XmOtaBHXL2Bu/vWoQtzloEUlv9tw==",
"requires": {
"axios": "^0.18.0",
"form-data": "^2.3.2",
"tough-cookie": "^2.4.3",
"tslib": "^1.9.2",
"uuid": "^3.2.1",
"xml2js": "^0.4.19"
}
}
}
},
@ -3730,9 +3847,9 @@
}
},
"bottleneck": {
"version": "2.13.0",
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.13.0.tgz",
"integrity": "sha512-9YmZ0aiKta2OAxTujKCS/INjGWCIGWK4Ff1nQpgHnR4CTjlk9jcnpaHOjPnMZPtqRXkqwKdtxZgvJ9udsXylaw==",
"version": "2.13.2",
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.13.2.tgz",
"integrity": "sha512-DVS4Uv7xr4Ql0w9valPBaueLRnEtBepeoevDhWO0LBhyihICJ7RySyzPfyvPswanrXAAbWaF8Zx4QpxmIxHa/g==",
"dev": true
},
"boxen": {
@ -4012,7 +4129,7 @@
"dependencies": {
"callsites": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
"resolved": "http://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
"integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
"dev": true
}
@ -4541,9 +4658,9 @@
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag=="
},
"commitizen": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/commitizen/-/commitizen-3.0.4.tgz",
"integrity": "sha512-djR5F7RBsGALyUEm/B1H/85nsN4L1F5DhWN+9/efSwqHDSyhw2MK6MF2VRuD26PUqGkQbcUlYO61btkTWjcjVw==",
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/commitizen/-/commitizen-3.0.5.tgz",
"integrity": "sha512-WB9sz7qudArOsW1ninU8YGLNoXLQ5lJBZf538iQ7i96SXAkqVMZdmPtSyN4WFPM5PjQR7rWxDa+hzfGIJfrXUg==",
"dev": true,
"requires": {
"cachedir": "2.1.0",
@ -4657,7 +4774,7 @@
},
"shelljs": {
"version": "0.7.6",
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.6.tgz",
"resolved": "http://registry.npmjs.org/shelljs/-/shelljs-0.7.6.tgz",
"integrity": "sha1-N5zM+1a5HIYB5HkzVutTgpJN6a0=",
"dev": true,
"requires": {
@ -5061,9 +5178,9 @@
}
},
"csv-parse": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.0.0.tgz",
"integrity": "sha512-M+cHI0SCXFGR0ZZWs7a6P14lXjrje5TOUpjkRQF9+Rauji8C4XOZpCyR/ENzH6uVqs+MTls00YE9IiI6Ao9Vrw=="
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.0.1.tgz",
"integrity": "sha512-ehkwejEj05wwO7Q9JD+YSI6dNMIauHIroNU1RALrmRrqPoZIwRnfBtgq5GkU6i2RxZOJqjo3dtI1NrVSXvaimA=="
},
"csv-parser": {
"version": "1.12.1",
@ -5332,6 +5449,12 @@
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
},
"deepmerge": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.0.0.tgz",
"integrity": "sha512-a8z8bkgHsAML+uHLqmMS83HHlpy3PvZOOuiTQqaa3wu8ZVg3h0hqHk6aCsGdOnZV2XMM/FRimNGjUh0KCcmHBw==",
"dev": true
},
"defer-to-connect": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.0.1.tgz",
@ -5841,9 +5964,9 @@
}
},
"env-ci": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/env-ci/-/env-ci-3.1.0.tgz",
"integrity": "sha512-+yFT8QX8W9bee0/fuzKvqt2vEhWvU3FXZ1P5xbveDq/EqcYLh4e0QNE16okUS3pawALDGXE9eCJPVeWY0/ilQA==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/env-ci/-/env-ci-3.1.2.tgz",
"integrity": "sha512-qJ+ug5OEHEK6HyjhEB0z2tPJCmdvemQE3WUUYEe7qj7teZIJGjZK9elWB4kxE8qRdVHWl4aBvyVmX0Y5xlMbBw==",
"dev": true,
"requires": {
"execa": "^1.0.0",
@ -6362,7 +6485,7 @@
},
"expand-range": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
"resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
"integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
"dev": true,
"requires": {
@ -8164,9 +8287,9 @@
}
},
"hook-std": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/hook-std/-/hook-std-1.1.0.tgz",
"integrity": "sha512-aIyBZbZl3NS8XoSwIDQ+ZaiBuPOhhPWoBFA3QX0Q8hOMO8Tx4xGRTDnn/nl/LAtZWdieXzFC9ohAtTSnWrlHCQ==",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/hook-std/-/hook-std-1.2.0.tgz",
"integrity": "sha512-yntre2dbOAjgQ5yoRykyON0D9T96BfshR8IuiL/r3celeHD8I/76w4qo8m3z99houR4Z678jakV3uXrQdSvW/w==",
"dev": true
},
"hosted-git-info": {
@ -9009,9 +9132,9 @@
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"issue-parser": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-3.0.0.tgz",
"integrity": "sha512-VWIhBdy0eOhlvpxOOMecBCHMpjx7lWVZcYpSzjD4dSdxptzI9TBR/cQEh057HL8+7jQKTLs+uCtezY/9VoveCA==",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-3.0.1.tgz",
"integrity": "sha512-5wdT3EE8Kq38x/hJD8QZCJ9scGoOZ5QnzwXyClkviSWTS+xOCE6hJ0qco3H5n5jCsFqpbofZCcMWqlXJzF72VQ==",
"dev": true,
"requires": {
"lodash.capitalize": "^4.2.1",
@ -9553,6 +9676,12 @@
"resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
"integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI="
},
"lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
"dev": true
},
"lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
@ -9641,6 +9770,18 @@
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
},
"lodash.pick": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
"integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=",
"dev": true
},
"lodash.set": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
"integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=",
"dev": true
},
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@ -9668,6 +9809,12 @@
"integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=",
"dev": true
},
"lodash.uniq": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
"integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
"dev": true
},
"lodash.uniqby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz",
@ -9781,9 +9928,9 @@
}
},
"macos-release": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/macos-release/-/macos-release-1.1.0.tgz",
"integrity": "sha512-mmLbumEYMi5nXReB9js3WGsB8UE6cDBWyIO62Z4DNx6GbRhDxHNjA1MlzSpJ2S2KM1wyiPRA0d19uHWYYvMHjA==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.0.0.tgz",
"integrity": "sha512-iCM3ZGeqIzlrH7KxYK+fphlJpCCczyHXc+HhRVbEu9uNTCrzYJjvvtefzeKTCVHd5AP/aD/fzC80JZ4ZP+dQ/A==",
"dev": true
},
"make-dir": {
@ -14928,6 +15075,12 @@
"isobject": "^3.0.1"
}
},
"octokit-pagination-methods": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz",
"integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==",
"dev": true
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@ -15020,13 +15173,13 @@
}
},
"os-name": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/os-name/-/os-name-2.0.1.tgz",
"integrity": "sha1-uaOGNhwXrjohc27wWZQFyajF3F4=",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/os-name/-/os-name-3.0.0.tgz",
"integrity": "sha512-7c74tib2FsdFbQ3W+qj8Tyd1R3Z6tuVRNNxXjJcZ4NgjIEQU9N/prVMqcW29XZPXGACqaXN3jq58/6hoaoXH6g==",
"dev": true,
"requires": {
"macos-release": "^1.0.0",
"win-release": "^1.0.0"
"macos-release": "^2.0.0",
"windows-release": "^3.1.0"
}
},
"os-tmpdir": {
@ -16407,9 +16560,9 @@
"integrity": "sha1-Az1go60g7PLgCUDRT5eCNGV3QzU="
},
"semantic-release": {
"version": "15.12.0",
"resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-15.12.0.tgz",
"integrity": "sha512-s8JQ0twxSTat4aIKy8AVPm6gP+2OlkMyyTGeeWFopOXQVa3Bg0LPNjdhsUL90MHvh9aVy9k0/ym4DWmOcGxOMQ==",
"version": "15.12.4",
"resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-15.12.4.tgz",
"integrity": "sha512-po30Te9E26v3Qb/G9pXFO6lCTFO07zvliqH00vmfuCoAjl1Wpg9SKb9dXVFM7BTdg5Fr/KqbdOsqHkT7kR4FeQ==",
"dev": true,
"requires": {
"@semantic-release/commit-analyzer": "^6.1.0",
@ -16657,9 +16810,9 @@
}
},
"yargs": {
"version": "12.0.4",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.4.tgz",
"integrity": "sha512-f5esswlPO351AnejaO2A1ZZr0zesz19RehQKwiRDqWtrraWrJy16tsUIKgDXFMVytvNOHPVmTiaTh3wO67I0fQ==",
"version": "12.0.5",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
"integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
"dev": true,
"requires": {
"cliui": "^4.0.0",
@ -16673,13 +16826,13 @@
"string-width": "^2.0.0",
"which-module": "^2.0.0",
"y18n": "^3.2.1 || ^4.0.0",
"yargs-parser": "^11.1.0"
"yargs-parser": "^11.1.1"
}
},
"yargs-parser": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.0.tgz",
"integrity": "sha512-lGA5HsbjkpCfekDBHAhgE5OE8xEoqiUDylowr+BvhRCwG1xVYTsd8hx2CYC0NY4k9RIgJeybFTG2EZW4P2aN1w==",
"version": "11.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",
"integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
@ -18006,9 +18159,9 @@
}
},
"tapable": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.0.tgz",
"integrity": "sha512-IlqtmLVaZA2qab8epUXbVWRn3aB1imbDMJtjB3nu4X0NqPkcY/JH9ZtCBWKHWPxs8Svi9tyo8w2dBoi07qZbBA==",
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz",
"integrity": "sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==",
"dev": true
},
"tar": {
@ -18589,9 +18742,9 @@
"integrity": "sha1-pZUhTHKY24M57u7gg+TRC9jLjdk="
},
"ts-loader": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.3.0.tgz",
"integrity": "sha512-lGSNs7szRFj/rK9T1EQuayE3QNLg6izDUxt5jpmq0RG1rU2bapAt7E7uLckLCUPeO1jwxCiet2oRaWovc53UAg==",
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.3.1.tgz",
"integrity": "sha512-fDDgpBH3SR8xlt2MasLdz3Yy611PQ/UY/KGyo7TgXhTRU/6sS8uGG0nJYnU1OdFBNKcoYbId1UTNaAOUn+i41g==",
"dev": true,
"requires": {
"chalk": "^2.3.0",
@ -18760,6 +18913,11 @@
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.4.0.tgz",
"integrity": "sha1-mtLCp6F5HxCoUuARL3e1cdzhDGY="
},
"typescript": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz",
"integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA=="
}
}
},
@ -18774,17 +18932,17 @@
"integrity": "sha512-/VMawTW4NnUUsgq0o8O37y9MmXFaOCDrH1dvDg7SZUS5ZSpUPSILVWwGJP+7g4I8vKZ5bBKZKHfPIEA4xUC+PQ=="
},
"typedoc-plugin-markdown": {
"version": "1.1.18",
"resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-1.1.18.tgz",
"integrity": "sha512-hE/2wM3NzMY/6K2wLtW7koVALLvVYm7w0mx+GFH3Er5gTioEMrUtd70Yf6Mb88fG6IvUWx1mX10ZD/ZR0AXS2w==",
"version": "1.1.19",
"resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-1.1.19.tgz",
"integrity": "sha512-dk1J9NHW3c1cMmcmTrw55U7ke6zadB3hZL7y7tkLQ6FeJGkz6SEMuexjVOq5rltuW7JeLqt1ngNKAwG9dXiMgQ==",
"requires": {
"turndown": "^5.0.1"
}
},
"typescript": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz",
"integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA=="
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.1.tgz",
"integrity": "sha512-jw7P2z/h6aPT4AENXDGjcfHTu5CSqzsbZc6YlUIebTyBAq8XaKp78x7VcSh30xwSCcsu5irZkYZUSFP1MrAMbg=="
},
"typescript-eslint-parser": {
"version": "16.0.1",
@ -18933,12 +19091,12 @@
}
},
"universal-user-agent": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.0.1.tgz",
"integrity": "sha512-vz+heWVydO0iyYAa65VHD7WZkYzhl7BeNVy4i54p4TF8OMiLSXdbuQe4hm+fmWAsL+rVibaQHXfhvkw3c1Ws2w==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.0.2.tgz",
"integrity": "sha512-nOwvHWLH3dBazyuzbECPA5uVFNd7AlgviXRHgR4yf48QqitIvpdncRrxMbZNMpPPEfgz30I9ubd1XmiJiqsTrg==",
"dev": true,
"requires": {
"os-name": "^2.0.1"
"os-name": "^3.0.0"
}
},
"universalify": {
@ -19169,6 +19327,11 @@
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
"vbscript-to-typescript": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/vbscript-to-typescript/-/vbscript-to-typescript-1.0.8.tgz",
"integrity": "sha512-vjElTpd4EVxUoxeGrRId4hetHdlyxIRicxkZxdErFfLJ9X7xyw0HEboXZO+s8prIC7s1eh0ulkuVbencrv6fAQ=="
},
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
@ -19261,9 +19424,9 @@
"integrity": "sha1-/IBORYzEYACbGiuWa8iBfSV4rvs="
},
"whatwg-mimetype": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.2.0.tgz",
"integrity": "sha512-5YSO1nMd5D1hY3WzAQV3PzZL83W3YeyR1yW9PcH26Weh1t+Vzh9B6XkDh7aXm83HBZ4nSMvkjvN2H2ySWIvBgw=="
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
"integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g=="
},
"whatwg-url": {
"version": "6.5.0",
@ -19338,13 +19501,30 @@
}
}
},
"win-release": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz",
"integrity": "sha1-X6VeAr58qTTt/BJmVjLoSbcuUgk=",
"windows-release": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.1.0.tgz",
"integrity": "sha512-hBb7m7acFgQPQc222uEQTmdcGLeBmQLNLFIh0rDk3CwFOBrfjefLzEfEfmpMq8Af/n/GnFf3eYf203FY1PmudA==",
"dev": true,
"requires": {
"semver": "^5.0.1"
"execa": "^0.10.0"
},
"dependencies": {
"execa": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz",
"integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==",
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
"get-stream": "^3.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
}
}
}
},
"winston": {

View file

@ -58,19 +58,20 @@
"azure-arm-search": "^1.3.0-preview",
"azure-arm-sql": "5.6.0",
"azure-arm-website": "5.7.0",
"bluebird": "^3.5.3",
"body-parser": "1.18.3",
"botbuilder": "^4.1.5",
"botbuilder-ai": "^4.1.5",
"botbuilder-azure": "^4.1.5",
"botbuilder": "^4.1.7",
"botbuilder-ai": "^4.1.7",
"botbuilder-azure": "^4.1.7",
"botbuilder-choices": "^4.0.0-preview1.2",
"botbuilder-dialogs": "^4.1.5",
"botbuilder-dialogs": "^4.1.7",
"botbuilder-prompts": "^4.0.0-preview1.2",
"botlib": "^0.1.8",
"chai": "4.2.0",
"child_process": "^1.0.2",
"chokidar": "2.0.4",
"cli-spinner": "^0.2.8",
"csv-parse": "4.0.0",
"csv-parse": "4.0.1",
"dotenv-extended": "2.3.0",
"express": "4.16.4",
"express-promise-router": "3.0.3",
@ -104,9 +105,10 @@
"ts-node": "7.0.1",
"typedoc": "0.13.0",
"typedoc-plugin-external-module-name": "^1.1.3",
"typedoc-plugin-markdown": "^1.1.18",
"typescript": "3.1.6",
"typedoc-plugin-markdown": "^1.1.19",
"typescript": "3.2.1",
"url-join": "4.0.0",
"vbscript-to-typescript": "^1.0.8",
"wait-until": "0.0.2",
"walk-promise": "0.2.0",
"winston": "3.1.0"
@ -115,12 +117,12 @@
"@semantic-release/changelog": "^3.0.1",
"@semantic-release/commit-analyzer": "^6.1.0",
"@semantic-release/git": "^7.0.5",
"@semantic-release/github": "^5.2.1",
"@semantic-release/github": "^5.2.5",
"@semantic-release/npm": "^5.1.1",
"@semantic-release/release-notes-generator": "^7.1.4",
"@types/chai": "4.1.7",
"@types/mocha": "5.2.5",
"@types/sequelize": "4.27.31",
"@types/sequelize": "4.27.32",
"@types/url-join": "0.8.2",
"@types/winston": "2.4.4",
"ban-sensitive-files": "1.9.2",
@ -134,10 +136,10 @@
"nsp": "3.2.1",
"pre-git": "3.17.1",
"prettier-standard": "8.0.1",
"semantic-release": "^15.12.0",
"semantic-release": "^15.12.4",
"standard": "12.0.1",
"travis-deploy-once": "5.0.9",
"ts-loader": "^5.3.0",
"ts-loader": "^5.3.1",
"tslint": "^5.11.0",
"tslint-microsoft-contrib": "^6.0.0"
},

View file

@ -141,7 +141,6 @@ export class AdminDialog extends IGBDialog {
return await step.replaceDialog('/admin', { firstRun: false });
} else if (cmdName === 'addConnection') {
await AdminDialog.addConnectionCommand(min, text);
return await step.replaceDialog('/admin', { firstRun: false });
} else if (cmdName === 'undeployPackage') {
await AdminDialog.undeployPackageCommand(text, min);

View file

@ -43,22 +43,11 @@ import { GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
import { Sequelize } from 'sequelize-typescript';
export class GBAnalyticsPackage implements IGBPackage {
public sysPackages: IGBPackage[] = null;
public loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
}
public unloadPackage(core: IGBCoreService): void {
}
public loadBot(min: GBMinInstance): void {
}
public unloadBot(min: GBMinInstance): void {
}
public onNewSession(min: GBMinInstance, step: any): void {
}
public loadPackage(core: IGBCoreService, sequelize: Sequelize): void {}
public unloadPackage(core: IGBCoreService): void {}
public loadBot(min: GBMinInstance): void {}
public unloadBot(min: GBMinInstance): void {}
public onNewSession(min: GBMinInstance, step: any): void {}
}

View file

@ -0,0 +1,12 @@
{
"version": "1.0.0",
"theme": "default.gbtheme",
"ui": "default.gbui",
"kb": "default.gbkb",
"title": "Default General Bot",
"description": "Default General Bot",
"whoAmIVideo": "TODO.mp4",
"author": "pragmatismo.io",
"license": "AGPL",
"engineName": "guaribas-1.0.0"
}

View file

@ -0,0 +1,3 @@
{
"groups": [{}]
}

View file

@ -0,0 +1,2 @@
{
}

View file

@ -0,0 +1,6 @@
{
"enabledAdmin": "true",
"searchScore": ".15",
"nlpScore": ".15",
"nlpVsSearch": ".4"
}

View file

@ -80,6 +80,7 @@ export class WelcomeDialog extends IGBDialog {
await step.replaceDialog('/answer', { query: step.context.activity.text });
}
}
return await step.next();
}
]));

View file

@ -64,6 +64,7 @@ export class WhoAmIDialog extends IGBDialog {
}
await step.replaceDialog('/ask', { isReturning: true });
return await step.next();
}
]));

View file

@ -0,0 +1,75 @@
/*****************************************************************************\
| ( )_ _ |
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
| | | ( )_) | |
| (_) \___/' |
| |
| General Bots Copyright (c) Pragmatismo.io. All rights reserved. |
| Licensed under the AGPL-3.0. |
| |
| According to our dual licensing model, this program can be used either |
| under the terms of the GNU Affero General Public License, version 3, |
| or under a proprietary license. |
| |
| The texts of the GNU Affero General Public License with an additional |
| permission and of our proprietary license can be found at and |
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
| "General Bots" is a registered trademark of Pragmatismo.io. |
| The licensing of the program under the AGPLv3 does not imply a |
| trademark license. Therefore any rights, title and interest in |
| our trademarks remain entirely with us. |
| |
\*****************************************************************************/
'use strict';
import { TurnContext } from 'botbuilder';
import { WaterfallStepContext } from 'botbuilder-dialogs';
import { GBMinInstance } from 'botlib';
const WaitUntil = require('wait-until');
/**
* @fileoverview General Bots server core.
*/
export class DialogClass {
public min: GBMinInstance;
public context: TurnContext;
public step: WaterfallStepContext;
constructor(min: GBMinInstance) {
this.min = min;
}
public async hear(cb) {
let idCallback = Math.floor(Math.random() * 1000000000000);
this.min.cbMap[idCallback] = cb;
await this.step.beginDialog('/hear', { id: idCallback});
}
public async talk(text: string) {
return await this.context.sendActivity(text);
}
/**
* Generic function to call any REST API.
*/
public sendEmail(to, subject, body) {
// tslint:disable-next-line:no-console
console.log(`[E-mail]: to:${to}, subject: ${subject}, body: ${body}.`);
}
/**
* Generic function to call any REST API.
*/
public post(url: string, data) {}
}

View file

@ -31,18 +31,15 @@
\*****************************************************************************/
/**
* @fileoverview General Bots server core.
* @fileoverview Conversation handling and external service calls.
*/
'use strict';
const logger = require('../../../src/logger');
import { any } from 'bluebird';
import { MessageFactory } from 'botbuilder';
import { LuisRecognizer } from 'botbuilder-ai';
import { IGBConversationalService } from 'botlib';
import { GBMinInstance } from 'botlib';
import { GBMinInstance, IGBConversationalService } from 'botlib';
import { AzureText } from 'pragmatismo-io-framework';
import { Messages } from '../strings';
import { GBCoreService } from './GBCoreService';
@ -70,33 +67,27 @@ export class GBConversationalService implements IGBConversationalService {
msg.value = value;
msg.type = 'event';
msg.name = name;
return step.context.sendActivity(msg);
}
}
public async sendSms(
min: GBMinInstance,
mobile: string,
text: string
): Promise<any> {
return new Promise((resolve: any, reject: any): any => {
const nexmo = new Nexmo({
apiKey: min.instance.smsKey,
apiSecret: min.instance.smsSecret
});
nexmo.message.sendSms(
min.instance.smsServiceNumber,
mobile,
text,
(err, data) => {
public async sendSms(min: GBMinInstance, mobile: string, text: string): Promise<any> {
return new Promise(
(resolve: any, reject: any): any => {
const nexmo = new Nexmo({
apiKey: min.instance.smsKey,
apiSecret: min.instance.smsSecret
});
nexmo.message.sendSms(min.instance.smsServiceNumber, mobile, text, (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
}
);
});
});
}
);
}
public async routeNLP(step: any, min: GBMinInstance, text: string): Promise<boolean> {
@ -112,15 +103,17 @@ export class GBConversationalService implements IGBConversationalService {
try {
nlp = await model.recognize(step.context);
} catch (error) {
if (error.statusCode == 404) {
logger.warn ('NLP application still not publish and there are no other options for answering.');
if (error.statusCode === 404) {
logger.warn('NLP application still not publish and there are no other options for answering.');
return Promise.resolve(false);
} else {
const msg = `Error calling NLP server, check if you have a published model and assigned keys on the service. Error: ${
error.statusCode ? error.statusCode : ''
} ${error.message}`;
return Promise.reject(new Error(msg)); }
const msg = `Error calling NLP, check if you have a published model and assigned keys. Error: ${
error.statusCode ? error.statusCode : ''
} ${error.message}`;
return Promise.reject(new Error(msg));
}
}
// Resolves intents returned from LUIS.
@ -128,37 +121,31 @@ export class GBConversationalService implements IGBConversationalService {
const topIntent = LuisRecognizer.topIntent(nlp);
if (topIntent) {
const intent = topIntent;
const entity =
nlp.entities && nlp.entities.length > 0
? nlp.entities[0].entity.toUpperCase()
: null;
const entity = nlp.entities && nlp.entities.length > 0 ? nlp.entities[0].entity.toUpperCase() : null;
if (intent === 'None') {
return Promise.resolve(false);
}
logger.info('NLP called:' + intent + ', ' + entity);
logger.info(`NLP called: ${intent}, ${entity}`);
try {
await step.replace('/' + intent, nlp.entities);
await step.replace(`/${intent}`, nlp.entities);
return Promise.resolve(true);
} catch (error) {
const msg = `Error finding dialog associated to NLP event: ${intent}: ${
error.message
}`;
const msg = `Error finding dialog associated to NLP event: ${intent}: ${error.message}`;
return Promise.reject(new Error(msg));
}
}
return Promise.resolve(false);
}
public async checkLanguage(step, min, text) {
const locale = await AzureText.getLocale(
min.instance.textAnalyticsKey,
min.instance.textAnalyticsEndpoint,
text
);
if (locale != step.context.activity.locale.split('-')[0]) {
const locale = await AzureText.getLocale(min.instance.textAnalyticsKey, min.instance.textAnalyticsEndpoint, text);
if (locale !== step.context.activity.locale.split('-')[0]) {
switch (locale) {
case 'pt':
step.context.activity.locale = 'pt-BR';

View file

@ -36,14 +36,24 @@
'use strict';
import { IGBCoreService, IGBInstance } from 'botlib';
import { IGBCoreService, IGBInstance, IGBPackage } from 'botlib';
import * as fs from 'fs';
import processExists = require('process-exists');
import { Sequelize } from 'sequelize-typescript';
const logger = require('../../../src/logger');
import { GBAdminPackage } from '../../admin.gbapp/index';
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService';
import { GBAnalyticsPackage } from '../../analytics.gblib';
import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService';
import { GBCorePackage } from '../../core.gbapp';
import { GBCustomerSatisfactionPackage } from '../../customer-satisfaction.gbapp';
import { GBKBPackage } from '../../kb.gbapp';
import { GBSecurityPackage } from '../../security.gblib';
import { GBWhatsappPackage } from '../../whatsapp.gblib/index';
import { GuaribasInstance } from '../models/GBModel';
import { GBConfigService } from './GBConfigService';
import { GBImporter } from './GBImporterService';
const logger = require('../../../src/logger');
const opn = require('opn');
/**
* Core service layer.
@ -67,11 +77,7 @@ export class GBCoreService implements IGBCoreService {
/**
* Custom create table query.
*/
private createTableQuery: (
tableName: string,
attributes: any,
options: any
) => string;
private createTableQuery: (tableName: string, attributes: any, options: any) => string;
/**
* Custom change column query.
@ -93,78 +99,79 @@ export class GBCoreService implements IGBCoreService {
/**
* Gets database config and connect to storage.
*/
public async initDatabase(): Promise<any> {
return new Promise(
(resolve: any, reject: any): any => {
try {
this.dialect = GBConfigService.get('STORAGE_DIALECT');
let host: string | undefined;
let database: string | undefined;
let username: string | undefined;
let password: string | undefined;
let storage: string | undefined;
public async initStorage(): Promise<any> {
this.dialect = GBConfigService.get('STORAGE_DIALECT');
if (this.dialect === 'mssql') {
host = GBConfigService.get('STORAGE_SERVER');
database = GBConfigService.get('STORAGE_NAME');
username = GBConfigService.get('STORAGE_USERNAME');
password = GBConfigService.get('STORAGE_PASSWORD');
} else if (this.dialect === 'sqlite') {
storage = GBConfigService.get('STORAGE_STORAGE');
} else {
reject(`Unknown dialect: ${this.dialect}.`);
let host: string | undefined;
let database: string | undefined;
let username: string | undefined;
let password: string | undefined;
let storage: string | undefined;
if (this.dialect === 'mssql') {
host = GBConfigService.get('STORAGE_SERVER');
database = GBConfigService.get('STORAGE_NAME');
username = GBConfigService.get('STORAGE_USERNAME');
password = GBConfigService.get('STORAGE_PASSWORD');
} else if (this.dialect === 'sqlite') {
storage = GBConfigService.get('STORAGE_STORAGE');
} else {
throw new Error(`Unknown dialect: ${this.dialect}.`);
}
const logging: any =
GBConfigService.get('STORAGE_LOGGING') === 'true'
? (str: string): void => {
logger.info(str);
}
: false;
const logging: any =
GBConfigService.get('STORAGE_LOGGING') === 'true'
? (str: string): void => {
logger.info(str);
}
: false;
const encrypt: boolean = GBConfigService.get('STORAGE_ENCRYPT') === 'true';
const encrypt: boolean =
GBConfigService.get('STORAGE_ENCRYPT') === 'true';
this.sequelize = new Sequelize({
host: host,
database: database,
username: username,
password: password,
logging: logging,
operatorsAliases: false,
dialect: this.dialect,
storage: storage,
dialectOptions: {
encrypt: encrypt
},
pool: {
max: 32,
min: 8,
idle: 40000,
evict: 40000,
acquire: 40000
}
});
if (this.dialect === 'mssql') {
this.queryGenerator = this.sequelize.getQueryInterface().QueryGenerator;
this.createTableQuery = this.queryGenerator.createTableQuery;
this.queryGenerator.createTableQuery = (
tableName,
attributes,
options
) => this.createTableQueryOverride(tableName, attributes, options);
this.changeColumnQuery = this.queryGenerator.changeColumnQuery;
this.queryGenerator.changeColumnQuery = (tableName, attributes) =>
this.changeColumnQueryOverride(tableName, attributes);
}
resolve();
} catch (error) {
reject(error);
}
this.sequelize = new Sequelize({
host: host,
database: database,
username: username,
password: password,
logging: logging,
operatorsAliases: false,
dialect: this.dialect,
storage: storage,
dialectOptions: {
encrypt: encrypt
},
pool: {
max: 32,
min: 8,
idle: 40000,
evict: 40000,
acquire: 40000
}
);
});
if (this.dialect === 'mssql') {
this.queryGenerator = this.sequelize.getQueryInterface().QueryGenerator;
this.createTableQuery = this.queryGenerator.createTableQuery;
this.queryGenerator.createTableQuery = (tableName, attributes, options) =>
this.createTableQueryOverride(tableName, attributes, options);
this.changeColumnQuery = this.queryGenerator.changeColumnQuery;
this.queryGenerator.changeColumnQuery = (tableName, attributes) =>
this.changeColumnQueryOverride(tableName, attributes);
}
}
public async checkStorage(azureDeployer: AzureDeployerService) {
try {
await this.sequelize.authenticate();
} catch (error) {
logger.info('Opening storage firewall on infrastructure...');
if (error.parent.code === 'ELOGIN') {
await this.openStorageFrontier(azureDeployer);
} else {
throw error;
}
}
}
public async syncDatabaseStructure() {
@ -172,12 +179,13 @@ export class GBCoreService implements IGBCoreService {
const alter = GBConfigService.get('STORAGE_SYNC_ALTER') === 'true';
const force = GBConfigService.get('STORAGE_SYNC_FORCE') === 'true';
logger.info('Syncing database...');
return this.sequelize.sync({
alter: alter,
force: force
});
} else {
const msg = 'Database synchronization is disabled.';
const msg = `Database synchronization is disabled.`;
logger.info(msg);
}
}
@ -194,6 +202,7 @@ export class GBCoreService implements IGBCoreService {
*/
public async loadInstanceById(instanceId: string): Promise<IGBInstance> {
const options = { where: { instanceId: instanceId } };
return GuaribasInstance.findOne(options);
}
@ -202,63 +211,183 @@ export class GBCoreService implements IGBCoreService {
*/
public async loadInstance(botId: string): Promise<IGBInstance> {
const options = { where: {} };
options.where = { botId: botId };
if (botId !== '[default]') {
options.where = { botId: botId };
}
return GuaribasInstance.findOne(options);
return await GuaribasInstance.findOne(options);
}
public async writeEnv(instance: IGBInstance) {
const env =
`ADDITIONAL_DEPLOY_PATH=\n` +
`ADMIN_PASS=${instance.adminPass}\n` +
`CLOUD_SUBSCRIPTIONID=${instance.cloudSubscriptionId}\n` +
`CLOUD_LOCATION=${instance.cloudLocation}\n` +
`CLOUD_GROUP=${instance.botId}\n` +
`CLOUD_USERNAME=${instance.cloudUsername}\n` +
`CLOUD_PASSWORD=${instance.cloudPassword}\n` +
`MARKETPLACE_ID=${instance.marketplaceId}\n` +
`MARKETPLACE_SECRET=${instance.marketplacePassword}\n` +
`NLP_AUTHORING_KEY=${instance.nlpAuthoringKey}\n` +
`STORAGE_DIALECT=${instance.storageDialect}\n` +
`STORAGE_SERVER=${instance.storageServer}.database.windows.net\n` +
`STORAGE_NAME=${instance.storageName}\n` +
`STORAGE_USERNAME=${instance.storageUsername}\n` +
`STORAGE_PASSWORD=${instance.storagePassword}\n` +
`STORAGE_SYNC=true\n`;
const env = `ADDITIONAL_DEPLOY_PATH=
ADMIN_PASS=${instance.adminPass}
CLOUD_SUBSCRIPTIONID=${instance.cloudSubscriptionId}
CLOUD_LOCATION=${instance.cloudLocation}
CLOUD_GROUP=${instance.botId}
CLOUD_USERNAME=${instance.cloudUsername}
CLOUD_PASSWORD=${instance.cloudPassword}
MARKETPLACE_ID=${instance.marketplaceId}
MARKETPLACE_SECRET=${instance.marketplacePassword}
NLP_AUTHORING_KEY=${instance.nlpAuthoringKey}
STORAGE_DIALECT=${instance.storageDialect}
STORAGE_SERVER=${instance.storageServer}.database.windows.net
STORAGE_NAME=${instance.storageName}
STORAGE_USERNAME=${instance.storageUsername}
STORAGE_PASSWORD=${instance.storagePassword}
STORAGE_SYNC=true`;
fs.writeFileSync('.env', env);
}
public async ensureProxy(port): Promise<string> {
let proxyAddress: string;
const ngrok = require('ngrok');
return await ngrok.connect({ port: port });
try {
const ngrok = require('ngrok');
return await ngrok.connect({ port: port });
} catch (error) {
// There are false positive from ngrok regarding to no memory, but it's just
// lack of connection.
logger.verbose(error);
throw new Error('Error connecting to remote ngrok server, please check network connection.');
}
}
public async saveInstance(fullInstance: any) {
const options = { where: {} };
options.where = { botId: fullInstance.botId };
let instance = await GuaribasInstance.findOne(options);
// tslint:disable-next-line:prefer-object-spread
instance = Object.assign(instance, fullInstance);
return await instance.save();
}
/**
* Loads all bot instances from object storage, if it's formatted.
*
* @param core
* @param azureDeployer
* @param proxyAddress
*/
public async loadAllInstances(core: GBCoreService, azureDeployer: AzureDeployerService, proxyAddress: string) {
logger.info(`Loading instances from storage...`);
let instances: GuaribasInstance[];
try {
instances = await core.loadInstances();
const instance = instances[0];
if (process.env.NODE_ENV === 'development') {
logger.info(`Updating bot endpoint to local reverse proxy (ngrok)...`);
await azureDeployer.updateBotProxy(
instance.botId,
instance.botId,
`${proxyAddress}/api/messages/${instance.botId}`
);
}
} catch (error) {
// Check if storage is empty and needs formatting.
const isInvalidObject = error.parent.number == 208 || error.parent.errno == 1; // MSSQL or SQLITE.
if (isInvalidObject) {
if (GBConfigService.get('STORAGE_SYNC') != 'true') {
throw new Error(
`Operating storage is out of sync or there is a storage connection error.
Try setting STORAGE_SYNC to true in .env file. Error: ${error.message}.`
);
} else {
logger.info(`Storage is empty. After collecting storage structure from all .gbapps it will get synced.`);
}
} else {
throw new Error(`Cannot connect to operating storage: ${error.message}.`);
}
}
return instances;
}
/**
* If instances is undefined here it's because storage has been formatted.
* Load all instances from .gbot found on deploy package directory.
* @param instances
* @param bootInstance
* @param core
*/
public async ensureInstances(instances: GuaribasInstance[], bootInstance: any, core: GBCoreService) {
if (!instances) {
const saveInstance = new GuaribasInstance(bootInstance);
await saveInstance.save();
instances = await core.loadInstances();
}
return instances;
}
public loadSysPackages(core: GBCoreService) {
// NOTE: if there is any code before this line a semicolon
// will be necessary before this line.
// Loads all system packages.
[
GBAdminPackage,
GBAnalyticsPackage,
GBCorePackage,
GBSecurityPackage,
GBKBPackage,
GBCustomerSatisfactionPackage,
GBWhatsappPackage
].forEach(e => {
logger.info(`Loading sys package: ${e.name}...`);
const p = Object.create(e.prototype) as IGBPackage;
p.loadPackage(core, core.sequelize);
});
}
public ensureAdminIsSecured() {
const password = GBConfigService.get('ADMIN_PASS');
if (!GBAdminService.StrongRegex.test(password)) {
throw new Error(
'Please, define a really strong password in ADMIN_PASS environment variable before running the server.'
);
}
}
public async createBootInstance(core: GBCoreService, azureDeployer: AzureDeployerService, proxyAddress: string) {
let instance: IGBInstance;
logger.info(`Deploying cognitive infrastructure (on the cloud / on premises)...`);
try {
instance = await azureDeployer.deployFarm(proxyAddress);
} catch (error) {
logger.warn(
`In case of error, please cleanup any infrastructure objects
created during this procedure and .env before running again.`
);
throw error;
}
core.writeEnv(instance);
logger.info(`File .env written, starting General Bots...`);
GBConfigService.init();
return instance;
}
public openBrowserInDevelopment() {
if (process.env.NODE_ENV === 'development') {
opn('http://localhost:4242');
}
}
/**
* SQL:
*
* // let sql: string = '' +
* // 'IF OBJECT_ID(\'[UserGroup]\', \'U\') IS NULL\n' +
* // 'CREATE TABLE [UserGroup] (\n' +
* // ' [id] INTEGER NOT NULL IDENTITY(1,1),\n' +
* // ' [userId] INTEGER NULL,\n' +
* // ' [groupId] INTEGER NULL,\n' +
* // ' [instanceId] INTEGER NULL,\n' +
* // ' PRIMARY KEY ([id1], [id2]),\n' +
* // ' FOREIGN KEY ([userId1], [userId2], [userId3]) REFERENCES [User] ([userId1], [userId2], [userId3]) ON DELETE NO ACTION,\n' +
* // ' FOREIGN KEY ([groupId1], [groupId2]) REFERENCES [Group] ([groupId1], [groupId1]) ON DELETE NO ACTION,\n' +
* // 'IF OBJECT_ID(\'[UserGroup]\', \'U\') IS NULL' +
* // 'CREATE TABLE [UserGroup] (' +
* // ' [id] INTEGER NOT NULL IDENTITY(1,1),' +
* // ' [userId] INTEGER NULL,' +
* // ' [groupId] INTEGER NULL,' +
* // ' [instanceId] INTEGER NULL,' +
* // ' PRIMARY KEY ([id1], [id2]),' +
* // ' FOREIGN KEY ([userId1], [userId2], [userId3]) REFERENCES [User] ([userId1], [userId2], [userId3]) ON DELETE NO ACTION,' +
* // ' FOREIGN KEY ([groupId1], [groupId2]) REFERENCES [Group] ([groupId1], [groupId1]) ON DELETE NO ACTION,' +
* // ' FOREIGN KEY ([instanceId]) REFERENCES [Instance] ([instanceId]) ON DELETE NO ACTION)'
*/
private createTableQueryOverride(tableName, attributes, options): string {
let sql: string = this.createTableQuery.apply(this.queryGenerator, [
tableName,
attributes,
options
]);
let sql: string = this.createTableQuery.apply(this.queryGenerator, [tableName, attributes, options]);
const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/;
const matches = re1.exec(sql);
if (matches) {
@ -292,16 +421,13 @@ export class GBCoreService implements IGBCoreService {
/**
* SQL:
* let sql = '' +
* 'ALTER TABLE [UserGroup]\n' +
* ' ADD CONSTRAINT [invalid1] FOREIGN KEY ([userId1], [userId2], [userId3]) REFERENCES [User] ([userId1], [userId2], [userId3]) ON DELETE NO ACTION,\n' +
* ' CONSTRAINT [invalid2] FOREIGN KEY ([groupId1], [groupId2]) REFERENCES [Group] ([groupId1], [groupId2]) ON DELETE NO ACTION, \n' +
* ' CONSTRAINT [invalid3] FOREIGN KEY ([instanceId1]) REFERENCES [Instance] ([instanceId1]) ON DELETE NO ACTION\n'
* 'ALTER TABLE [UserGroup]' +
* ' ADD CONSTRAINT [invalid1] FOREIGN KEY ([userId1], [userId2], [userId3]) REFERENCES [User] ([userId1], [userId2], [userId3]) ON DELETE NO ACTION,' +
* ' CONSTRAINT [invalid2] FOREIGN KEY ([groupId1], [groupId2]) REFERENCES [Group] ([groupId1], [groupId2]) ON DELETE NO ACTION, ' +
* ' CONSTRAINT [invalid3] FOREIGN KEY ([instanceId1]) REFERENCES [Instance] ([instanceId1]) ON DELETE NO ACTION'
*/
private changeColumnQueryOverride(tableName, attributes): string {
let sql: string = this.changeColumnQuery.apply(this.queryGenerator, [
tableName,
attributes
]);
let sql: string = this.changeColumnQuery.apply(this.queryGenerator, [tableName, attributes]);
const re1 = /ALTER\s+TABLE\s+\[([^\]]*)\]/;
const matches = re1.exec(sql);
if (matches) {
@ -318,17 +444,21 @@ export class GBCoreService implements IGBCoreService {
fkname += '_' + matches[1];
matches = re3.exec(fkcols);
}
return (
(args[0] ? args[0] : '') +
'CONSTRAINT [' +
fkname +
'_fk] FOREIGN KEY (' +
fkcols +
')'
);
return (args[0] ? args[0] : '') + 'CONSTRAINT [' + fkname + '_fk] FOREIGN KEY (' + fkcols + ')';
}
);
}
return sql;
}
/**
* Opens storage firewall.
*
* @param azureDeployer Infrastructure Deployer instance.
*/
private async openStorageFrontier(deployer: AzureDeployerService) {
const group = GBConfigService.get('CLOUD_GROUP');
const serverName = GBConfigService.get('STORAGE_SERVER').split('.database.windows.net')[0];
await deployer.openStorageFirewall(group, serverName);
}
}

View file

@ -42,8 +42,9 @@ const UrlJoin = require('url-join');
const Fs = require('fs');
const WaitUntil = require('wait-until');
const express = require('express');
const child_process = require('child_process');
import { IGBCoreService, IGBInstance } from 'botlib';
import { GBMinInstance, IGBCoreService, IGBInstance } from 'botlib';
import { GBError } from 'botlib';
import { IGBPackage } from 'botlib';
import { AzureSearch } from 'pragmatismo-io-framework';
@ -51,7 +52,8 @@ import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDe
import { GuaribasInstance, GuaribasPackage } from '../models/GBModel';
import { KBService } from './../../kb.gbapp/services/KBService';
import { GBConfigService } from './GBConfigService';
import { GBImporter } from './GBImporter';
import { GBImporter } from './GBImporterService';
import { GBVMService } from './GBVMService';
/** Deployer service for bots, themes, ai and more. */
export class GBDeployer {
@ -66,13 +68,9 @@ export class GBDeployer {
}
public static getConnectionStringFromInstance(instance: GuaribasInstance) {
return `Server=tcp:${
instance.storageServer
}.database.windows.net,1433;Database=${instance.storageName};User ID=${
return `Server=tcp:${instance.storageServer}.database.windows.net,1433;Database=${instance.storageName};User ID=${
instance.storageUsername
};Password=${
instance.storagePassword
};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;`;
};Password=${instance.storagePassword};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;`;
}
/**
@ -80,163 +78,152 @@ export class GBDeployer {
* Performs package deployment in all .gbai or default.
*
* */
public deployPackages(
core: IGBCoreService,
server: any,
appPackages: IGBPackage[]
) {
public deployPackages(core: IGBCoreService, server: any, appPackages: IGBPackage[]) {
const _this = this;
return new Promise((resolve: any, reject: any): any => {
let totalPackages = 0;
const additionalPath = GBConfigService.get('ADDITIONAL_DEPLOY_PATH');
let paths = [GBDeployer.deployFolder];
if (additionalPath) {
paths = paths.concat(additionalPath.toLowerCase().split(';'));
}
const botPackages = new Array<string>();
const gbappPackages = new Array<string>();
let generalPackages = new Array<string>();
function doIt(path) {
const isDirectory = source => Fs.lstatSync(source).isDirectory();
const getDirectories = source =>
Fs.readdirSync(source)
.map(name => Path.join(source, name))
.filter(isDirectory);
const dirs = getDirectories(path);
dirs.forEach(element => {
if (element.startsWith('.')) {
logger.info(`Ignoring ${element}...`);
} else {
if (element.endsWith('.gbot')) {
botPackages.push(element);
} else if (element.endsWith('.gbapp')) {
gbappPackages.push(element);
} else {
generalPackages.push(element);
}
}
});
}
logger.info(
`Starting looking for packages (.gbot, .gbtheme, .gbkb, .gbapp)...`
);
paths.forEach(e => {
logger.info(`Looking in: ${e}...`);
doIt(e);
});
/** Deploys all .gbapp files first. */
let appPackagesProcessed = 0;
gbappPackages.forEach(e => {
// Skips .gbapp inside deploy folder.
if (!e.startsWith('packages')) {
logger.info(`Deploying app: ${e}...`);
import(e)
.then(m => {
const p = new m.Package();
p.loadPackage(core, core.sequelize);
appPackages.push(p);
logger.info(`App (.gbapp) deployed: ${e}.`);
appPackagesProcessed++;
})
.catch(err => {
logger.error(`Error deploying App (.gbapp): ${e}: ${err}`);
appPackagesProcessed++;
});
} else {
appPackagesProcessed++;
return new Promise(
(resolve: any, reject: any): any => {
let totalPackages = 0;
const additionalPath = GBConfigService.get('ADDITIONAL_DEPLOY_PATH');
let paths = [GBDeployer.deployFolder];
if (additionalPath) {
paths = paths.concat(additionalPath.toLowerCase().split(';'));
}
});
const botPackages = new Array<string>();
const gbappPackages = new Array<string>();
let generalPackages = new Array<string>();
WaitUntil()
.interval(1000)
.times(10)
.condition(function(cb) {
logger.info(`Waiting for app package deployment...`);
cb(appPackagesProcessed == gbappPackages.length);
})
.done(async result => {
logger.info(`App Package deployment done.`);
function doIt(path) {
const isDirectory = source => Fs.lstatSync(source).isDirectory();
const getDirectories = source =>
Fs.readdirSync(source)
.map(name => Path.join(source, name))
.filter(isDirectory);
try {
await core.syncDatabaseStructure();
} catch (e) {
throw e;
}
/** Deploys all .gbot files first. */
botPackages.forEach(e => {
logger.info(`Deploying bot: ${e}...`);
_this.deployBot(e);
logger.info(`Bot: ${e} deployed...`);
});
/** Then all remaining generalPackages are loaded. */
generalPackages = generalPackages.filter(p => !p.endsWith('.git'));
generalPackages.forEach(filename => {
const filenameOnly = Path.basename(filename);
logger.info(`Deploying package: ${filename}...`);
/** Handles apps for general bots - .gbapp must stay out of deploy folder. */
if (
Path.extname(filename) === '.gbapp' ||
Path.extname(filename) === '.gblib'
) {
/** Themes for bots. */
} else if (Path.extname(filename) === '.gbtheme') {
server.use('/themes/' + filenameOnly, express.static(filename));
logger.info(
`Theme (.gbtheme) assets accessible at: ${'/themes/' +
filenameOnly}.`
);
/** Knowledge base for bots. */
} else if (Path.extname(filename) === '.gbkb') {
server.use(
'/kb/' + filenameOnly + '/subjects',
express.static(UrlJoin(filename, 'subjects'))
);
logger.info(
`KB (.gbkb) assets accessible at: ${'/kb/' + filenameOnly}.`
);
} else if (Path.extname(filename) === '.gbui') {
// Already Handled
const dirs = getDirectories(path);
dirs.forEach(element => {
if (element.startsWith('.')) {
logger.info(`Ignoring ${element}...`);
} else {
/** Unknown package format. */
const err = new Error(`Package type not handled: ${filename}.`);
reject(err);
}
totalPackages++;
});
WaitUntil()
.interval(100)
.times(5)
.condition(function(cb) {
logger.info(`Waiting for package deployment...`);
cb(totalPackages == generalPackages.length);
})
.done(function(result) {
if (botPackages.length === 0) {
logger.info(
'No external packages to load, please use ADDITIONAL_DEPLOY_PATH to point to a .gbai package folder.'
);
if (element.endsWith('.gbot')) {
botPackages.push(element);
} else if (element.endsWith('.gbapp')) {
gbappPackages.push(element);
} else {
logger.info(`Package deployment done.`);
generalPackages.push(element);
}
resolve();
});
}
});
}
logger.info(`Starting looking for packages (.gbot, .gbtheme, .gbkb, .gbapp)...`);
paths.forEach(e => {
logger.info(`Looking in: ${e}...`);
doIt(e);
});
});
/** Deploys all .gbapp files first. */
let appPackagesProcessed = 0;
gbappPackages.forEach(e => {
// Skips .gbapp inside deploy folder.
if (!e.startsWith('packages')) {
logger.info(`Deploying app: ${e}...`);
import(e)
.then(m => {
const p = new m.Package();
p.loadPackage(core, core.sequelize);
appPackages.push(p);
logger.info(`App (.gbapp) deployed: ${e}.`);
appPackagesProcessed++;
})
.catch(err => {
logger.error(`Error deploying App (.gbapp): ${e}: ${err}`);
appPackagesProcessed++;
});
} else {
appPackagesProcessed++;
}
});
WaitUntil()
.interval(1000)
.times(10)
.condition(function(cb) {
logger.info(`Waiting for app package deployment...`);
cb(appPackagesProcessed == gbappPackages.length);
})
.done(async result => {
logger.info(`App Package deployment done.`);
try {
await core.syncDatabaseStructure();
} catch (e) {
throw e;
}
/** Deploys all .gbot files first. */
botPackages.forEach(e => {
if (e !== 'packages\\boot.gbot') {
logger.info(`Deploying bot: ${e}...`);
_this.deployBot(e);
logger.info(`Bot: ${e} deployed...`);
}
});
/** Then all remaining generalPackages are loaded. */
generalPackages = generalPackages.filter(p => !p.endsWith('.git'));
generalPackages.forEach(filename => {
const filenameOnly = Path.basename(filename);
logger.info(`Deploying package: ${filename}...`);
/** Handles apps for general bots - .gbapp must stay out of deploy folder. */
if (Path.extname(filename) === '.gbapp' || Path.extname(filename) === '.gblib') {
/** Themes for bots. */
} else if (Path.extname(filename) === '.gbtheme') {
server.use('/themes/' + filenameOnly, express.static(filename));
logger.info(`Theme (.gbtheme) assets accessible at: ${'/themes/' + filenameOnly}.`);
/** Knowledge base for bots. */
} else if (Path.extname(filename) === '.gbkb') {
server.use('/kb/' + filenameOnly + '/subjects', express.static(UrlJoin(filename, 'subjects')));
logger.info(`KB (.gbkb) assets accessible at: ${'/kb/' + filenameOnly}.`);
} else if (Path.extname(filename) === '.gbui') {
// Already Handled
} else if (Path.extname(filename) === '.gbdialog') {
// Already Handled
} else {
/** Unknown package format. */
const err = new Error(`Package type not handled: ${filename}.`);
reject(err);
}
totalPackages++;
});
WaitUntil()
.interval(100)
.times(5)
.condition(function(cb) {
logger.info(`Waiting for package deployment...`);
cb(totalPackages == generalPackages.length);
})
.done(function(result) {
if (botPackages.length === 0) {
logger.info(
'No external packages to load, please use ADDITIONAL_DEPLOY_PATH to point to a .gbai package folder.'
);
} else {
logger.info(`Package deployment done.`);
}
resolve();
});
});
}
);
}
/**
@ -246,23 +233,20 @@ export class GBDeployer {
public async deployBot(localPath: string): Promise<IGBInstance> {
const packageType = Path.extname(localPath);
const packageName = Path.basename(localPath);
const instance = await this.importer.importIfNotExistsBotPackage(
packageName,
localPath
);
const instance = await this.importer.importIfNotExistsBotPackage(null, packageName, localPath);
return instance;
}
public async deployPackageToStorage(
instanceId: number,
packageName: string
): Promise<GuaribasPackage> {
public async deployPackageToStorage(instanceId: number, packageName: string): Promise<GuaribasPackage> {
return GuaribasPackage.create({
packageName: packageName,
instanceId: instanceId
});
}
public deployScriptToStorage(instanceId: number, localPath: string) {}
public deployTheme(localPath: string) {
// DISABLED: Until completed, "/ui/public".
// FsExtra.copy(localPath, this.workDir + packageName)
@ -275,7 +259,7 @@ export class GBDeployer {
// })
}
public async deployPackageFromLocalPath(localPath: string) {
public async deployPackageFromLocalPath(min: GBMinInstance, localPath: string) {
const packageType = Path.extname(localPath);
switch (packageType) {
@ -293,10 +277,12 @@ export class GBDeployer {
case '.gbui':
break;
case '.gbdialog':
const vm = new GBVMService();
return vm.loadJS(localPath, min, this.core, this, localPath);
default:
const err = GBError.create(
`GuaribasBusinessError: Unknow package type: ${packageType}.`
);
const err = GBError.create(`GuaribasBusinessError: Unknown package type: ${packageType}.`);
Promise.reject(err);
break;
}
@ -324,10 +310,11 @@ export class GBDeployer {
case '.gbui':
break;
case '.gbdialog':
break;
default:
const err = GBError.create(
`GuaribasBusinessError: Unknown package type: ${packageType}.`
);
const err = GBError.create(`GuaribasBusinessError: Unknown package type: ${packageType}.`);
Promise.reject(err);
break;
}
@ -353,13 +340,7 @@ export class GBDeployer {
}
}
await search.createDataSource(
dsName,
dsName,
'GuaribasQuestion',
'azuresql',
connectionString
);
await search.createDataSource(dsName, dsName, 'GuaribasQuestion', 'azuresql', connectionString);
try {
await search.deleteIndex();
@ -369,37 +350,22 @@ export class GBDeployer {
throw err;
}
}
await search.createIndex(
AzureDeployerService.getKBSearchSchema(instance.searchIndex),
dsName
);
await search.createIndex(AzureDeployerService.getKBSearchSchema(instance.searchIndex), dsName);
}
public async getPackageByName(
instanceId: number,
packageName: string
): Promise<GuaribasPackage> {
public async getPackageByName(instanceId: number, packageName: string): Promise<GuaribasPackage> {
const where = { packageName: packageName, instanceId: instanceId };
return GuaribasPackage.findOne({
where: where
});
}
/**
*
* Hot deploy processing.
*
*/
public async scanBootPackage() {
const deployFolder = 'packages';
const bootPackage = GBConfigService.get('BOOT_PACKAGE');
if (bootPackage === 'none') {
return Promise.resolve(true);
} else {
return this.deployPackageFromLocalPath(
UrlJoin(deployFolder, bootPackage)
);
public installDefaultGBUI() {
const root = 'packages/default.gbui';
if (!Fs.existsSync(`${root}/build`)) {
Fs.writeFileSync(`${root}/.env`, 'SKIP_PREFLIGHT_CHECK=true');
child_process.execSync('npm install', { cwd: root });
child_process.execSync('npm run build', { cwd: root });
}
}
}

View file

@ -50,44 +50,29 @@ export class GBImporter {
this.core = core;
}
public async importIfNotExistsBotPackage(
packageName: string,
localPath: string) {
const packageJson = JSON.parse(
fs.readFileSync(UrlJoin(localPath, 'package.json'), 'utf8')
);
const botId = packageJson.botId;
public async importIfNotExistsBotPackage(botId: string, packageName: string, localPath: string) {
const packageJson = JSON.parse(fs.readFileSync(UrlJoin(localPath, 'package.json'), 'utf8'));
if (!botId) {
botId = packageJson.botId;
}
const instance = await this.core.loadInstance(botId);
if (instance) {
return Promise.resolve(instance);
return instance;
} else {
return this.createInstanceInternal(packageName, localPath, packageJson);
return await this.createInstanceInternal(botId, packageName, localPath, packageJson);
}
}
private async createInstanceInternal(
packageName: string,
localPath: string,
packageJson: any
) {
const settings = JSON.parse(
fs.readFileSync(UrlJoin(localPath, 'settings.json'), 'utf8')
);
const servicesJson = JSON.parse(
fs.readFileSync(UrlJoin(localPath, 'services.json'), 'utf8')
);
private async createInstanceInternal(botId: string, packageName: string, localPath: string, packageJson: any) {
const settings = JSON.parse(fs.readFileSync(UrlJoin(localPath, 'settings.json'), 'utf8'));
const servicesJson = JSON.parse(fs.readFileSync(UrlJoin(localPath, 'services.json'), 'utf8'));
packageJson = {...packageJson, ...settings, ...servicesJson};
packageJson = { ...packageJson, ...settings, ...servicesJson };
GuaribasInstance.create(packageJson).then((instance: IGBInstance) => {
if (botId){
packageJson.botId = botId;
}
const service = new SecService();
// TODO: service.importSecurityFile(localPath, instance)
Promise.resolve(instance);
});
return GuaribasInstance.create(packageJson);
}
}

View file

@ -43,21 +43,9 @@ const logger = require('../../../src/logger');
const request = require('request-promise-native');
const AuthenticationContext = require('adal-node').AuthenticationContext;
import {
AutoSaveStateMiddleware,
BotFrameworkAdapter,
ConversationState,
MemoryStorage,
UserState
} from 'botbuilder';
import { AutoSaveStateMiddleware, BotFrameworkAdapter, ConversationState, MemoryStorage, UserState } from 'botbuilder';
import {
GBMinInstance,
IGBAdminService,
IGBConversationalService,
IGBCoreService,
IGBPackage
} from 'botlib';
import { GBMinInstance, IGBAdminService, IGBConversationalService, IGBCoreService, IGBPackage } from 'botlib';
import { GBAnalyticsPackage } from '../../analytics.gblib';
import { GBCorePackage } from '../../core.gbapp';
import { GBCustomerSatisfactionPackage } from '../../customer-satisfaction.gbapp';
@ -88,7 +76,7 @@ export class GBMinService {
core: IGBCoreService,
conversationalService: IGBConversationalService,
adminService: IGBAdminService,
deployer: GBDeployer,
deployer: GBDeployer
) {
this.core = core;
this.conversationalService = conversationalService;
@ -108,17 +96,16 @@ export class GBMinService {
* */
public async buildMin(
bootInstance: GuaribasInstance,
server: any,
appPackages: IGBPackage[],
instances: GuaribasInstance[],
deployer: GBDeployer
): Promise<GBMinInstance> {
// Serves default UI on root address '/'.
const uiPackage = 'default.gbui';
server.use(
'/',
express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, 'build')),
);
server.use('/', express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, 'build')));
Promise.all(
instances.map(async instance => {
@ -133,7 +120,11 @@ export class GBMinService {
(async () => {
// Returns the instance object to clients requesting bot info.
const botId = req.params.botId;
let botId = req.params.botId;
if (botId === '[default]') {
botId = bootInstance.botId;
}
const instance = await this.core.loadInstance(botId);
if (instance) {
@ -152,8 +143,8 @@ export class GBMinService {
speechToken: speechToken,
conversationId: webchatToken.conversationId,
authenticatorTenant: instance.authenticatorTenant,
authenticatorClientId: instance.authenticatorClientId,
}),
authenticatorClientId: instance.authenticatorClientId
})
);
} else {
const error = `Instance not found: ${botId}.`;
@ -165,9 +156,11 @@ export class GBMinService {
// Build bot adapter.
const { min, adapter, conversationState } = await this.buildBotAdapter(
instance,
);
const { min, adapter, conversationState } = await this.buildBotAdapter(instance);
// Install default VBA module.
deployer.deployPackageFromLocalPath(min, 'packages/default.gbdialog');
// Call the loadBot context.activity for all packages.
@ -177,32 +170,17 @@ export class GBMinService {
const url = `/api/messages/${instance.botId}`;
server.post(url, async (req, res) => {
return this.receiver(
adapter,
req,
res,
conversationState,
min,
instance,
appPackages,
);
return await this.receiver(adapter, req, res, conversationState, min, instance, appPackages);
});
logger.info(
`GeneralBots(${instance.engineName}) listening on: ${url}.`,
);
logger.info(`GeneralBots(${instance.engineName}) listening on: ${url}.`);
// Serves individual URL for each bot user interface.
const uiUrl = `/${instance.botId}`;
server.use(
uiUrl,
express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, 'build')),
);
server.use(uiUrl, express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, 'build')));
logger.info(`Bot UI ${uiPackage} accessible at: ${uiUrl}.`);
const state = `${instance.instanceId}${Math.floor(
Math.random() * 1000000000,
)}`;
const state = `${instance.instanceId}${Math.floor(Math.random() * 1000000000)}`;
// Clients get redirected here in order to create an OAuth authorize url and redirect them to AAD.
// There they will authenticate and give their consent to allow this app access to
@ -211,13 +189,11 @@ export class GBMinService {
let authorizationUrl = UrlJoin(
min.instance.authenticatorAuthorityHostUrl,
min.instance.authenticatorTenant,
'/oauth2/authorize',
'/oauth2/authorize'
);
authorizationUrl = `${authorizationUrl}?response_type=code&client_id=${
min.instance.authenticatorClientId
}&redirect_uri=${min.instance.botEndpoint}/${
min.instance.botId
}/token`;
}&redirect_uri=${min.instance.botEndpoint}/${min.instance.botId}/token`;
res.redirect(authorizationUrl);
});
@ -227,23 +203,16 @@ export class GBMinService {
// access token that can be used to access the user owned resource.
server.get(`/${min.instance.botId}/token`, async (req, res) => {
const state = await min.adminService.getValue(
min.instance.instanceId,
'AntiCSRFAttackState',
);
const state = await min.adminService.getValue(min.instance.instanceId, 'AntiCSRFAttackState');
if (req.query.state !== state) {
const msg =
'WARNING: state field was not provided as anti-CSRF token';
const msg = 'WARNING: state field was not provided as anti-CSRF token';
logger.error(msg);
throw new Error(msg);
}
const authenticationContext = new AuthenticationContext(
UrlJoin(
min.instance.authenticatorAuthorityHostUrl,
min.instance.authenticatorTenant,
),
UrlJoin(min.instance.authenticatorAuthorityHostUrl, min.instance.authenticatorTenant)
);
const resource = 'https://graph.microsoft.com';
@ -260,48 +229,17 @@ export class GBMinService {
logger.error(msg);
res.send(msg);
} else {
await this.adminService.setValue(
instance.instanceId,
'refreshToken',
token.refreshToken,
);
await this.adminService.setValue(
instance.instanceId,
'accessToken',
token.accessToken,
);
await this.adminService.setValue(
instance.instanceId,
'expiresOn',
token.expiresOn.toString(),
);
await this.adminService.setValue(
instance.instanceId,
'AntiCSRFAttackState',
null,
);
await this.adminService.setValue(instance.instanceId, 'refreshToken', token.refreshToken);
await this.adminService.setValue(instance.instanceId, 'accessToken', token.accessToken);
await this.adminService.setValue(instance.instanceId, 'expiresOn', token.expiresOn.toString());
await this.adminService.setValue(instance.instanceId, 'AntiCSRFAttackState', null);
res.redirect(min.instance.botEndpoint);
}
},
}
);
});
// Setups handlers.
// send: function (context.activity, next) {
// logger.info(
// `[SND]: ChannelID: ${context.activity.address.channelId}, ConversationID: ${context.activity.address.conversation},
// Type: ${context.activity.type} `)
// this.core.createMessage(
// this.min.conversation,
// this.min.conversation.startedBy,
// context.activity.source,
// (data, err) => {
// logger.info(context.activity.source)
// }
// )
// next()
}),
})
);
}
@ -316,8 +254,8 @@ export class GBMinService {
url: 'https://directline.botframework.com/v3/directline/tokens/generate',
method: 'POST',
headers: {
Authorization: `Bearer ${instance.webchatKey}`,
},
Authorization: `Bearer ${instance.webchatKey}`
}
};
try {
@ -344,8 +282,8 @@ export class GBMinService {
url: 'https://westus.api.cognitive.microsoft.com/sts/v1.0/issueToken',
method: 'POST',
headers: {
'Ocp-Apim-Subscription-Key': instance.speechKey,
},
'Ocp-Apim-Subscription-Key': instance.speechKey
}
};
try {
@ -359,7 +297,7 @@ export class GBMinService {
private async buildBotAdapter(instance: any) {
const adapter = new BotFrameworkAdapter({
appId: instance.marketplaceId,
appPassword: instance.marketplacePassword,
appPassword: instance.marketplacePassword
});
const storage = new MemoryStorage();
@ -377,8 +315,10 @@ export class GBMinService {
min.conversationalService = this.conversationalService;
min.adminService = this.adminService;
min.instance = await this.core.loadInstance(min.botId);
min.cbMap = {};
min.userProfile = conversationState.createProperty('userProfile');
const dialogState = conversationState.createProperty('dialogState');
min.dialogs = new DialogSet(dialogState);
min.dialogs.add(new TextPrompt('textPrompt'));
@ -395,7 +335,7 @@ export class GBMinService {
GBKBPackage,
GBAnalyticsPackage,
GBCustomerSatisfactionPackage,
GBWhatsappPackage,
GBWhatsappPackage
].forEach(sysPackage => {
const p = Object.create(sysPackage.prototype) as IGBPackage;
p.loadBot(min);
@ -417,17 +357,18 @@ export class GBMinService {
/**
* Bot Service hook method.
*/
private receiver(
private async receiver(
adapter: BotFrameworkAdapter,
req: any,
res: any,
conversationState: ConversationState,
min: any,
instance: any,
appPackages: any[],
appPackages: any[]
) {
return adapter.processActivity(req, res, async context => {
const state = conversationState.get(context);
return await adapter.processActivity(req, res, async context => {
// Get loaded user state
const state = await conversationState.get(context);
const step = await min.dialogs.createContext(context, state);
step.context.activity.locale = 'en-US'; // TODO: Make dynamic.
@ -439,22 +380,20 @@ export class GBMinService {
instanceId: instance.instanceId,
botId: instance.botId,
theme: instance.theme ? instance.theme : 'default.gbtheme',
secret: instance.webchatKey,
secret: instance.webchatKey
});
user.loaded = true;
user.subjects = [];
user.cb = null;
await min.userProfile.set(step.context, user);
}
logger.info(
`User>: ${context.activity.text} (${context.activity.type}, ${
context.activity.name
}, ${context.activity.channelId}, {context.activity.value})`,
`User>: ${context.activity.text} (${context.activity.type}, ${context.activity.name}, ${
context.activity.channelId
}, {context.activity.value})`
);
if (
context.activity.type === 'conversationUpdate' &&
context.activity.membersAdded.length > 0
) {
if (context.activity.type === 'conversationUpdate' && context.activity.membersAdded.length > 0) {
const member = context.activity.membersAdded[0];
if (member.name === 'GeneralBots') {
logger.info(`Bot added to conversation, starting chat...`);
@ -471,23 +410,29 @@ export class GBMinService {
// Processes messages.
} else if (context.activity.type === 'message') {
// Checks for /admin request.
if (context.activity.text === 'admin') {
if (context.activity.text === 'alpha-vba') {
min.sandbox.context = context;
min.sandbox.step = step;
min.sandbox['bot'].bind(min.sandbox);
await min.sandbox['bot']();
} else if (context.activity.text === 'admin') {
await step.beginDialog('/admin');
// Checks for /menu JSON signature.
} else if (context.activity.text.startsWith('{"title"')) {
await step.beginDialog('/menu', {
data: JSON.parse(context.activity.text),
data: JSON.parse(context.activity.text)
});
// Otherwise, continue to the active dialog in the stack.
} else {
const user = await min.userProfile.get(context, {});
if (step.activeDialog) {
await step.continueDialog();
} else {
await step.beginDialog('/answer', {
query: context.activity.text,
query: context.activity.text
});
}
}
@ -504,18 +449,18 @@ export class GBMinService {
await step.beginDialog('/menu');
} else if (context.activity.name === 'giveFeedback') {
await step.beginDialog('/feedback', {
fromMenu: true,
fromMenu: true
});
} else if (context.activity.name === 'showFAQ') {
await step.beginDialog('/faq');
} else if (context.activity.name === 'answerEvent') {
await step.beginDialog('/answerEvent', {
questionId: (context.activity as any).data,
fromFaq: true,
fromFaq: true
});
} else if (context.activity.name === 'quality') {
await step.beginDialog('/quality', {
score: (context.activity as any).data,
score: (context.activity as any).data
});
} else if (context.activity.name === 'updateToken') {
const token = (context.activity as any).data;
@ -524,13 +469,12 @@ export class GBMinService {
await step.continueDialog();
}
}
await conversationState.saveChanges(context, true);
} catch (error) {
const msg = `ERROR: ${error.message} ${error.stack ? error.stack : ''}`;
logger.error(msg);
await step.context.sendActivity(
Messages[step.context.activity.locale].very_sorry_about_error,
);
await step.context.sendActivity(Messages[step.context.activity.locale].very_sorry_about_error);
await step.beginDialog('/ask', { isReturning: true });
}
});

View file

@ -0,0 +1,195 @@
/*****************************************************************************\
| ( )_ _ |
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
| | | ( )_) | |
| (_) \___/' |
| |
| General Bots Copyright (c) Pragmatismo.io. All rights reserved. |
| Licensed under the AGPL-3.0. |
| |
| According to our dual licensing model, this program can be used either |
| under the terms of the GNU Affero General Public License, version 3, |
| or under a proprietary license. |
| |
| The texts of the GNU Affero General Public License with an additional |
| permission and of our proprietary license can be found at and |
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
| "General Bots" is a registered trademark of Pragmatismo.io. |
| The licensing of the program under the AGPLv3 does not imply a |
| trademark license. Therefore any rights, title and interest in |
| our trademarks remain entirely with us. |
| |
\*****************************************************************************/
'use strict';
import { GBMinInstance, IGBCoreService } from 'botlib';
import * as fs from 'fs';
import { DialogClass } from './GBAPIService';
import { GBDeployer } from './GBDeployer';
import { TSCompiler } from './TSCompiler';
import { WaterfallDialog } from 'botbuilder-dialogs';
const util = require('util');
const logger = require('../../../src/logger');
const vm = require('vm');
const UrlJoin = require('url-join');
const vb2ts = require('vbscript-to-typescript/dist/converter');
/**
* @fileoverview Virtualization services for emulation of BASIC.
*/
export class GBVMService implements IGBCoreService {
private script = new vm.Script();
public async loadJS(
filename: string,
min: GBMinInstance,
core: IGBCoreService,
deployer: GBDeployer,
localPath: string
): Promise<void> {
const path = 'packages/default.gbdialog';
const file = 'bot.vbs';
const source = UrlJoin(path, file);
// Example when handled through fs.watch() listener
fs.watchFile(source, async (curr, prev) => {
await this.run(source, path, min, deployer, filename);
});
await this.run(source, path, min, deployer, filename);
this.addHearDialog(min);
}
public async run(source: any, path: string, min: any, deployer: GBDeployer, filename: string) {
// Converts VBS into TS.
vb2ts.convertFile(source);
// Convert TS into JS.
const tsfile = `bot.ts`;
const tsc = new TSCompiler();
tsc.compile([UrlJoin(path, tsfile)]);
// Run JS into the GB context.
const jsfile = `bot.js`;
let localPath = UrlJoin(path, jsfile);
if (fs.existsSync(localPath)) {
let code: string = fs.readFileSync(localPath, 'utf8');
code = code.replace(/^.*exports.*$/gm, '');
// Finds all hear calls.
let parsedCode = code;
let hearExp = /(\w+).*hear.*\(\)/;
let match1;
while ((match1 = hearExp.exec(code))) {
let pos = 0;
// Writes async body.
const variable = match1[1]; // variable = hear();
parsedCode = code.substring(pos, pos + match1.index);
parsedCode += `hear (async (${variable}) => {\n`;
// Skips old construction and point to the async block.
pos = pos + match1.index;
let tempCode = code.substring(pos + match1[0].length + 1);
let start = pos;
// Balances code blocks and checks for exits.
let right = 0;
let left = 1;
let match2;
while ((match2 = /\{|\}/.exec(tempCode))) {
const c = tempCode.substring(match2.index, match2.index + 1);
if (c === '}') {
right++;
} else if (c === '{') {
left++;
}
tempCode = tempCode.substring(match2.index + 1);
pos += match2.index + 1;
if (left === right) {
break;
}
}
parsedCode += code.substring(start + match1[0].length + 1, pos + match1[0].length);
parsedCode += '});\n';
parsedCode += code.substring(pos + match1[0].length);
// A interaction will be made for each hear.
code = parsedCode;
}
parsedCode = parsedCode.replace(/("[^"]*"|'[^']*')|\btalk\b/g, function($0, $1) {
return $1 == undefined ? 'this.talk' : $1;
});
parsedCode = parsedCode.replace(/("[^"]*"|'[^']*')|\bhear\b/g, function($0, $1) {
return $1 == undefined ? 'this.hear' : $1;
});
parsedCode = parsedCode.replace(/("[^"]*"|'[^']*')|\bsendEmail\b/g, function($0, $1) {
return $1 == undefined ? 'this.sendEmail' : $1;
});
parsedCode = parsedCode.replace(/this\./gm, 'await this.');
parsedCode = parsedCode.replace(/function/gm, 'async function');
fs.writeFileSync(localPath, parsedCode);
const sandbox: DialogClass = new DialogClass(min);
const context = vm.createContext(sandbox);
vm.runInContext(parsedCode, context);
min.sandbox = sandbox;
await deployer.deployScriptToStorage(min.instanceId, filename);
logger.info(`[GBVMService] Finished loading of ${filename}`);
}
}
private addHearDialog(min) {
min.dialogs.add(
new WaterfallDialog('/hear', [
async step => {
step.activeDialog.state.cbId = step.options['id'];
return await step.prompt('textPrompt', {});
},
async step => {
min.sandbox.context = step.context;
min.sandbox.step = step;
const cbId = step.activeDialog.state.cbId;
const cb = min.cbMap[cbId];
cb.bind({ step: step, context: step.context }); // TODO: Necessary or min.sandbox
await step.endDialog();
return await cb(step.result);
}
])
);
}
}

View file

@ -0,0 +1,75 @@
/*****************************************************************************\
| ( )_ _ |
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
| | | ( )_) | |
| (_) \___/' |
| |
| General Bots Copyright (c) Pragmatismo.io. All rights reserved. |
| Licensed under the AGPL-3.0. |
| |
| According to our dual licensing model, this program can be used either |
| under the terms of the GNU Affero General Public License, version 3, |
| or under a proprietary license. |
| |
| The texts of the GNU Affero General Public License with an additional |
| permission and of our proprietary license can be found at and |
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
| "General Bots" is a registered trademark of Pragmatismo.io. |
| The licensing of the program under the AGPLv3 does not imply a |
| trademark license. Therefore any rights, title and interest in |
| our trademarks remain entirely with us. |
| |
\*****************************************************************************/
/**
* @fileoverview General Bots server core.
*/
'use strict';
import * as ts from 'typescript';
const logger = require('../../../src/logger');
export class TSCompiler {
public compile(
fileNames: string[],
options: ts.CompilerOptions = {
noStrictGenericChecks: true,
noImplicitUseStrict: true,
noEmitOnError: false,
noImplicitAny: true,
target: ts.ScriptTarget.ES5,
module: ts.ModuleKind.None,
moduleResolution: ts.ModuleResolutionKind.Classic,
noEmitHelpers: true,
maxNodeModuleJsDepth: 0,
esModuleInterop: false
}
) {
const program = ts.createProgram(fileNames, options);
const emitResult = program.emit();
const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
allDiagnostics.forEach(diagnostic => {
if (diagnostic.file) {
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
logger.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
} else {
logger.error(`${ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`);
}
});
return emitResult;
}
}

View file

@ -1,7 +1,7 @@
import { expect } from 'chai';
import 'mocha';
import {GBImporter} from '../services/GBImporter';
import {GBImporter} from '../services/GBImporterService';
describe('Hello function', () => {

View file

@ -0,0 +1,51 @@
/*****************************************************************************\
| ( )_ _ |
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
| | | ( )_) | |
| (_) \___/' |
| |
| General Bots Copyright (c) Pragmatismo.io. All rights reserved. |
| Licensed under the AGPL-3.0. |
| |
| According to our dual licensing model, this program can be used either |
| under the terms of the GNU Affero General Public License, version 3, |
| or under a proprietary license. |
| |
| The texts of the GNU Affero General Public License with an additional |
| permission and of our proprietary license can be found at and |
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
| "General Bots" is a registered trademark of Pragmatismo.io. |
| The licensing of the program under the AGPLv3 does not imply a |
| trademark license. Therefore any rights, title and interest in |
| our trademarks remain entirely with us. |
| |
\*****************************************************************************/
'use strict';
/**
* @fileoverview Tests for General Bots VM.
*/
import { expect } from 'chai';
import { GBVMService } from '../services/GBVMService';
describe('Load function', () => {
it('should fail on invalid file', () => {
try {
const service = new GBVMService();
service.loadJS('invalid.file', null, null, null, null);
} catch (error) {
expect(error).to.equal(0);
}
});
});

View file

@ -78,35 +78,37 @@ export class FeedbackDialog extends IGBDialog {
])
);
min.dialogs.add(new WaterfallDialog('/feedback', [
async step => {
const locale = step.context.activity.locale;
if (step.result.fromMenu) {
min.dialogs.add(
new WaterfallDialog('/feedback', [
async step => {
const locale = step.context.activity.locale;
await step.context.sendActivity(Messages[locale].about_suggestions);
}
step.activeDialog.state.cbId = step.options['id'];
await step.prompt('textPrompt', Messages[locale].what_about_service);
return await step.next();
},
async step => {
const locale = step.context.activity.locale;
const rate = await AzureText.getSentiment(
min.instance.textAnalyticsKey,
min.instance.textAnalyticsEndpoint,
min.conversationalService.getCurrentLanguage(step),
step.result
);
return await step.prompt('textPrompt', Messages[locale].what_about_service);
},
async step => {
if (rate > 0.5) {
await step.context.sendActivity(Messages[locale].glad_you_liked);
} else {
await step.context.sendActivity(Messages[locale].we_will_improve);
const locale = step.context.activity.locale;
const rate = await AzureText.getSentiment(
min.instance.textAnalyticsKey,
min.instance.textAnalyticsEndpoint,
min.conversationalService.getCurrentLanguage(step),
step.result
);
if (rate > 0.5) {
await step.context.sendActivity(Messages[locale].glad_you_liked);
} else {
await step.context.sendActivity(Messages[locale].we_will_improve);
// TODO: Record.
}
return await step.replaceDialog('/ask', { isReturning: true });
}
await step.replaceDialog('/ask', { isReturning: true });
return await step.next();
}
]));
])
);
}
}

View file

@ -0,0 +1,114 @@
<%
'****************************************************************************
' ( )_ _
' _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _
' ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\
' | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) )
' | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/'
' | | ( )_) |
' (_) \___/'
'
' General Bots Copyright (c) Pragmatismo.io. All rights reserved.
' Licensed under the AGPL-3.0.
'
' This BASIC file is based on this JavaScript file by Rodrigo Ruotolo:
' -> http://jsfiddle.net/roderick/dym05hsy
'
' According to our dual licensing model, this program can be used either
' under the terms of the GNU Affero General Public License, version 3,
' or under a proprietary license.
'
' The texts of the GNU Affero General Public License with an additional
' permission and of our proprietary license can be found at and
' in the LICENSE file you have received along with this program.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY, without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
' GNU Affero General Public License for more details.
'
' "General Bots" is a registered trademark of Pragmatismo.io.
' The licensing of the program under the AGPLv3 does not imply a
' trademark license. Therefore any rights, title and interest in
' our trademarks remain entirely with us.
'
'****************************************************************************
talk ("How many installments do you want to pay your Credit?")
installments = hear ()
if installments > 60 then
talk ("The maximum number of payments is 60")
else
talk ("What is the amount requested?")
ammount = hear ()
if ammount >100000 then
talk ("We are sorry, we can only accept proposals bellow 100k")
else
talk ("What is the best due date?")
dueDate = hear ()
interestRate = 0
adjustment = 0
if installments < 12 then
interestRate = 1.60
adjustment = 0.09748
end if
if installments > 12 and installments < 18 then
interestRate = 1.66
adjustment = 0.06869
end if
if installments > 18 and installments < 36 then
interestRate = 1.64
adjustment = 0.05397
end if
if installments > 36 and installments < 48 then
interestRate = 1.62
adjustment = 0.03931
end if
if installments > 48 and installments < 60 then
interestRate = 1.70
adjustment = 0.03270
end if
if installments = 60 then
interestRate = 1.79
adjustment = 0.02916
end if
if installments > 60 then
talk ("The maximum number of payments is 60")
end if
' TODO: This must be reviewed in terms of financing logic.
nInstallments = parseInt(installments)
vAmmount = parseFloat(ammount)
initialPayment = parseFloat(vAmmount) * 0.3 ' 30% of the value
tac = 800
adjustment = 1.3
totalValue = ammount - initialPayment + tac
paymentValue = totalValue * adjustment
finalValue = paymentValue * nInstallments + initialPayment
talk("Congratulations! Your credit analysis is **done**:")
talk("First payment: **" + initialPayment + "**")
talk("Payment value: **" + paymentValue + "**")
talk("Interest Rate: **" + interestRate + "%**")
talk("Total Value: **" + totalValue + "**")
talk("Final Value: **" + finalValue + "**")
end if
end if
%>

View file

@ -0,0 +1,3 @@
Últimas notícias
Contato
Ofertas

View file

@ -0,0 +1,6 @@
{
"botId":"pragmatismo-ai-prd",
"version": "1.0.0",
"description": "Bot pragmatismo.",
"license": "Private"
}

View file

@ -0,0 +1,16 @@
#Desenvolvimento Personalizado
General Bots usa linguagem natural para entender o que as pessoas querem, facilitando o desenvolvimento de código. Quando alguém diz: "Preciso do relatório mensal" ou "Imprima o relatório do mês", General Bots entende o mesmo. Utilize o nosso desenvolvimento para estender a conversa com suas próprias regras e intenções.
#Descoberta
General Bots pode pró-ativamente sugerir suas habilidades para os usuários baseada no contexto, como solicitação de um pedido, envio de uma mensagem, agendamento de uma conferência telefônica ou qualquer ação definida na sua aplicação.
#Torne pessoal
Entregue experiências únicas através do conhecimento que a General Bots possui sobre seus usuários e preferências, para ajudar a tomar decisões e apresentar sempre o melhor cenário.
#Sem downloads adicionais
A interface da sua aplicação é automaticamente integrada à General Bots, de modo que não seja necessário realizar download ou instalações.

View file

@ -0,0 +1,58 @@
{
"children": [
{
"title": "Bots & AI",
"description": "Bots & inteligência artificial.",
"id": "bots-ai",
"children": [
{
"title": "General Bots",
"description": "Plataforma de bots da Pragmatismo.io.",
"id": "general-bots"
},
{
"title": "Cortana Intelligence Suite",
"description": "Suite de Big Data da Microsoft.",
"id": "cortana"
}
]
},
{
"title": "Produtividade",
"description": "Artigos sobre sistemas Internos.",
"id": "produtividade",
"children": [
{
"title": "Microsoft Project Online",
"description": "Artigos sobre o Microsoft Project Online.",
"id": "msproject"
},
{
"title": "SharePoint",
"description": "SharePoint, sites e serviços.",
"id": "sharepoint"
},
{
"title": "Office 365",
"description": "Plataforma colaborativa moderna da Microsoft.",
"id": "office365"
},
{
"title": "Microsoft Dynamics",
"description": "Artigos sobre plataforma de CRM da Microsoft.",
"id": "msdynamics"
},
{
"title": "Power BI",
"description": "Dashboards modernos e intuitivos.",
"id": "powerbi"
}
]
},
{
"title": "Sobre",
"description": "Artigos sobre o Bot da Pragmatismo.io",
"id": "sobre"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.
1 subjects from to question answer
2 common.goodbye question answer obrigado Obrigado a você!
3 common.goodbye question answer Obrigada Obrigado a você!
4 common.goodbye question answer Muito obrigada Obrigado a você!
5 common.goodbye question answer Obrigado Obrigado a você!
6 common.goodbye question answer Muito obrigado Obrigado a você!
7 common.goodbye question answer Até mais Até breve!
8 common.goodbye question answer Entendi Que bom que você entendeu.
9 common.goodbye question answer Valeu Valeu!
10 common.goodbye question answer Agradeço pela atenção Agradeço também
11 common.goodbye question answer Agradeço Agradeço também
12 common.goodbye question answer Obrigado Obrigado a você!
13 common.goodbye question answer Obrigada Obrigado a você!
14 common.goodbye question answer Obg Obrigado a você!
15 common.goodbye question answer Tks Obrigado a você!
16 common.goodbye question answer certo Certo!
17 common.goodbye question answer grata Obrigado a você!
18 common.goodbye question answer entendi Entendi também.
19 common.goodbye question answer Valeu Valeu!
20 common.goodbye question answer vlw Valeu!
21 common.goodbye question answer fui Valeu!
22 common.goodbye question answer inté Valeu!
23 common.goodbye question answer good bye Valeu!
24 common.goodbye question answer t+ Valeu!

Binary file not shown.
1 subjects from to question answer
2 common.hello question answer tudo bem Tudo bem... Espero que você também.
3 common.hello question answer Como você está Tudo bem... Espero que você também.
4 common.hello question answer Olá! Olá!
5 common.hello question answer Boa tarde Boa tarde!
6 common.hello question answer Boa noite Boa noite!
7 common.hello question answer Boa noite, tudo bem? Boa noite, tudo bem!
8 common.hello question answer Boa tarde, tudo bem? Boa tarde!
9 common.hello question answer Tudo bem? Tudo bem... Espero que você também.
10 common.hello question answer De boa? Olá!
11 common.hello question answer Bom dia Bom dia.
12 common.hello question answer Boa tarde Boa tarde.
13 common.hello question answer Boa noite Boa noite.
14 common.hello question answer Eai? Oi!

Binary file not shown.
1 subjects from to question answer
2 common.persona question answer Quem te criou? Fui criado por um time dedicado de pessoas que estudam ciência de dados e engenharia de software, é bem fácil de começar.
3 common.persona question answer Qual tua idade? Desde o último **build** tenho algumas horas... O tempo não passa do mesmo modo para mim.
4 common.persona question answer Quem é você? Sou um bot, ou agente de conversação autônomo. Sou um programa de computador que usa interfaces conversacionais para simular o comportamento humano. Interessante, não?
5 common.persona question answer Você é real? Sim, sou software. Mas não sou uma pessoa, apenas um programa de computador.
6 common.persona question answer Onde você mora? Moro no Azure, nas nuvens. Especificamente na memória RAM de alguns computadores, chamados de servidores.
7 common.persona question answer De onde você é? Moro no Azure, nas nuvens. Especificamente na memória RAM de alguns computadores, chamados de servidores.
8 common.persona question answer Qual idiomas ou linguagens você fala? Português, mas posso rapidamente me tornar poliglota com os serviços em nuvem.
9 common.persona question answer Como você está? Estou muito bem, serviços OK também. Espero que você também.

Binary file not shown.
1 subjects from to question answer
2 geral menu answer GB oi

View file

View file

@ -1134,9 +1134,9 @@
"integrity": "sha512-ugTb7Lq7u4GfWSqqpwE0bGyoBZNMTok/zDBXxfEG0QM50jNlGhIWjRC1pPN7bvV1anhF+bs+/gNcRw+o55Evbg=="
},
"adaptivecards": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/adaptivecards/-/adaptivecards-1.1.0.tgz",
"integrity": "sha512-n4vRIjo0vKvjMMnTKqRZm3TXhq+8saN1s17Z0pQEtDpBWjrGbfn8e+Qx/xvgNjqFYzWIme7uZAX3DBDhSOLu/A=="
"version": "1.0.0",
"resolved": "http://registry.npmjs.org/adaptivecards/-/adaptivecards-1.0.0.tgz",
"integrity": "sha1-96HxdpJRYmirQMpU8Z/aP6WJdjQ="
},
"address": {
"version": "1.0.3",
@ -2043,15 +2043,6 @@
}
}
},
"babel-runtime": {
"version": "7.0.0-beta.3",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-7.0.0-beta.3.tgz",
"integrity": "sha512-jlzZ8RACjt0QGxq+wqsw5bCQE9RcUyWpw987mDY3GYxTpOQT2xoyNoG++oVCHzr/nACLBIprfVBNvv/If1ZYcg==",
"requires": {
"core-js": "^2.4.0",
"regenerator-runtime": "^0.11.0"
}
},
"babel-template": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
@ -2338,86 +2329,48 @@
}
},
"botframework-webchat": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/botframework-webchat/-/botframework-webchat-4.1.0.tgz",
"integrity": "sha512-ZvmY2iYN+VPp/myuqVRHGehgx+xtHXnv7cwn1c2nCz+/ak0WAR4D2sakxEhX4vB09t5MNUbx8GYq9GPxTI+lCA==",
"version": "0.14.3-master.72bfef9",
"resolved": "https://registry.npmjs.org/botframework-webchat/-/botframework-webchat-0.14.3-master.72bfef9.tgz",
"integrity": "sha512-rgppVWeVd43FT5O2HpoPeVkowPtGN74cAhC+ZSGGd7HiDq5UyHtR4+PISLvR9XtRy/dLTF2afubOOThPvW+44w==",
"requires": {
"@babel/runtime": "^7.0.0",
"adaptivecards": "^1.0.0",
"babel-runtime": "^7.0.0-beta.3",
"botframework-directlinejs": "^0.10.0",
"botframework-webchat-component": "4.1.0",
"botframework-webchat-core": "4.1.0",
"core-js": "^2.5.7",
"markdown-it": "^8.4.2",
"markdown-it-for-inline": "^0.1.1",
"memoize-one": "^4.0.2",
"microsoft-speech-browser-sdk": "^0.0.12",
"react": "^16.5.0",
"react-dom": "^16.5.0",
"react-redux": "^5.0.7",
"redux": "^4.0.0",
"sanitize-html": "^1.19.0",
"store": "^2.0.12",
"url-search-params-polyfill": "^5.0.0",
"web-speech-cognitive-services": "^3.0.0",
"whatwg-fetch": "^3.0.0"
"adaptivecards": "1.0.0",
"bluebird": "^3.5.1",
"botframework-directlinejs": "0.9.17",
"core-js": "2.4.1",
"jspeech": "^0.1.1",
"markdown-it": "8.3.1",
"microsoft-speech-browser-sdk": "0.0.12",
"react-redux": "5.0.5",
"redux": "3.7.2",
"redux-observable": "0.13.0",
"rxjs": "5.4.3",
"simple-update-in": "^1.2.0",
"tslib": "1.7.1"
},
"dependencies": {
"whatwg-fetch": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
"botframework-directlinejs": {
"version": "0.9.17",
"resolved": "https://registry.npmjs.org/botframework-directlinejs/-/botframework-directlinejs-0.9.17.tgz",
"integrity": "sha512-Ib2BhalcxbKi5rtCO1OX5VhWkfb/rN/voq5823hCIvd/p+GCI/G9jEnxzRcfFWmLUk6hWYjwUnKarIeg93YiMA==",
"requires": {
"rxjs": "^5.0.3"
}
},
"core-js": {
"version": "2.4.1",
"resolved": "http://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz",
"integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4="
},
"rxjs": {
"version": "5.4.3",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.4.3.tgz",
"integrity": "sha512-fSNi+y+P9ss+EZuV0GcIIqPUK07DEaMRUtLJvdcvMyFjc9dizuDjere+A4V7JrLGnm9iCc+nagV/4QdMTkqC4A==",
"requires": {
"symbol-observable": "^1.0.1"
}
}
}
},
"botframework-webchat-component": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/botframework-webchat-component/-/botframework-webchat-component-4.1.0.tgz",
"integrity": "sha512-kTgAxA1zMwblg/3/cE2GjWX9ff+NodCnVMcPm7Daas5iik74orqoPUJKARcKNH+iRihlfE/2oeoj06Gl0CB1Gw==",
"requires": {
"adaptivecards": "^1.0.0",
"botframework-webchat-core": "4.1.0",
"bytes": "^3.0.0",
"classnames": "^2.2.6",
"glamor": "^2.20.40",
"memoize-one": "^3.1.1",
"react-dictate-button": "^1.1.3",
"react-film": "^1.1.1",
"react-redux": "^5.0.7",
"react-say": "^1.1.1",
"react-scroll-to-bottom": "^1.2.0",
"redux": "^4.0.0",
"sanitize-html": "^1.18.2",
"simple-update-in": "^1.3.0"
},
"dependencies": {
"memoize-one": {
"version": "3.1.1",
"resolved": "http://registry.npmjs.org/memoize-one/-/memoize-one-3.1.1.tgz",
"integrity": "sha512-YqVh744GsMlZu6xkhGslPSqSurOv6P+kLN2J3ysBZfagLcL5FdRK/0UpgLoL8hwjjEvvAVkjJZyFP+1T6p1vgA=="
}
}
},
"botframework-webchat-core": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/botframework-webchat-core/-/botframework-webchat-core-4.1.0.tgz",
"integrity": "sha512-mPw92k0Pq2ATsx1rE3oi73oy7lqrCfzV/XFK+XjXYeiSp6PMi1Mn6B4eIrnGKZe8vLQ8Y92jt0Zgq7HUl2jqLg==",
"requires": {
"@babel/runtime": "^7.0.0-rc.2",
"jsonwebtoken": "^8.3.0",
"mime": "^2.3.1",
"redux": "^4.0.0",
"redux-promise-middleware": "^5.1.1",
"redux-saga": "^0.16.0",
"simple-update-in": "^1.3.0"
}
},
"bowser": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz",
"integrity": "sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ=="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -2555,11 +2508,6 @@
"isarray": "^1.0.0"
}
},
"buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@ -2883,11 +2831,6 @@
}
}
},
"classnames": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
},
"clean-css": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
@ -3234,6 +3177,16 @@
"sha.js": "^2.4.8"
}
},
"create-react-class": {
"version": "15.6.3",
"resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz",
"integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==",
"requires": {
"fbjs": "^0.8.9",
"loose-envify": "^1.3.1",
"object-assign": "^4.1.1"
}
},
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@ -3290,15 +3243,6 @@
}
}
},
"css-in-js-utils": {
"version": "2.0.1",
"resolved": "http://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz",
"integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==",
"requires": {
"hyphenate-style-name": "^1.0.2",
"isobject": "^3.0.1"
}
},
"css-loader": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.0.tgz",
@ -3912,14 +3856,6 @@
"webidl-conversions": "^4.0.2"
}
},
"domhandler": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
"requires": {
"domelementtype": "1"
}
},
"domutils": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
@ -3988,14 +3924,6 @@
"safer-buffer": "^2.1.0"
}
},
"ecdsa-sig-formatter": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz",
"integrity": "sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM=",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -4503,21 +4431,11 @@
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"event-as-promise": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/event-as-promise/-/event-as-promise-1.0.5.tgz",
"integrity": "sha512-z/WIlyou7oTvXBjm5YYjfklr2d8gUWtx8b5GAcrIs1n1D35f7NIK0CrcYSXbY3VYikG9bUan+wScPyGXL/NH4A=="
},
"eventemitter3": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
"integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM="
},
"events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz",
"integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA=="
},
"eventsource": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz",
@ -5703,11 +5621,13 @@
},
"balanced-match": {
"version": "1.0.0",
"bundled": true
"bundled": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -5720,15 +5640,18 @@
},
"code-point-at": {
"version": "1.1.0",
"bundled": true
"bundled": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true
"bundled": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true
"bundled": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -5831,7 +5754,8 @@
},
"inherits": {
"version": "2.0.3",
"bundled": true
"bundled": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -5841,6 +5765,7 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -5853,17 +5778,20 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true
"bundled": true,
"optional": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@ -5880,6 +5808,7 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -5952,7 +5881,8 @@
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true
"bundled": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -5962,6 +5892,7 @@
"once": {
"version": "1.4.0",
"bundled": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -6067,6 +5998,7 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -6168,18 +6100,6 @@
"assert-plus": "^1.0.0"
}
},
"glamor": {
"version": "2.20.40",
"resolved": "https://registry.npmjs.org/glamor/-/glamor-2.20.40.tgz",
"integrity": "sha512-DNXCd+c14N9QF8aAKrfl4xakPk5FdcFwmH7sD0qnC0Pr7xoZ5W9yovhUrY/dJc3psfGGXC58vqQyRtuskyUJxA==",
"requires": {
"fbjs": "^0.8.12",
"inline-style-prefixer": "^3.0.6",
"object-assign": "^4.1.1",
"prop-types": "^15.5.10",
"through": "^2.3.8"
}
},
"glob": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
@ -6504,12 +6424,9 @@
"integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA=="
},
"hoist-non-react-statics": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.1.0.tgz",
"integrity": "sha512-MYcYuROh7SBM69xHGqXEwQqDux34s9tz+sCnxJmN18kgWh6JFdTw/5YdZtqsOdZJXddE/wUpCzfEdDrJj8p0Iw==",
"requires": {
"react-is": "^16.3.2"
}
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz",
"integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs="
},
"home-or-tmp": {
"version": "2.0.0",
@ -6628,19 +6545,6 @@
"util.promisify": "1.0.0"
}
},
"htmlparser2": {
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz",
"integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==",
"requires": {
"domelementtype": "^1.3.0",
"domhandler": "^2.3.0",
"domutils": "^1.5.1",
"entities": "^1.1.1",
"inherits": "^2.0.1",
"readable-stream": "^3.0.6"
}
},
"http-deceiver": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
@ -6977,11 +6881,6 @@
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM="
},
"hyphenate-style-name": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz",
"integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es="
},
"iconv-lite": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
@ -7097,15 +6996,6 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc="
},
"inline-style-prefixer": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz",
"integrity": "sha1-hVG45bTVcyROZqNLBPfTIHaitTQ=",
"requires": {
"bowser": "^1.7.3",
"css-in-js-utils": "^2.0.0"
}
},
"inquirer": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz",
@ -8280,21 +8170,10 @@
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
"integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM="
},
"jsonwebtoken": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz",
"integrity": "sha512-oge/hvlmeJCH+iIz1DwcO7vKPkNGJHhgkspk8OH3VKlw+mbi42WtD4ig1+VXRln765vxptAv+xT26Fd3cteqag==",
"requires": {
"jws": "^3.1.5",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1"
}
"jspeech": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jspeech/-/jspeech-0.1.1.tgz",
"integrity": "sha1-n+wcnRGeFJBajeqCpQWvBs+Sg1k="
},
"jsprim": {
"version": "1.4.1",
@ -8315,25 +8194,6 @@
"array-includes": "^3.0.3"
}
},
"jwa": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.6.tgz",
"integrity": "sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw==",
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.10",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.1.5.tgz",
"integrity": "sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ==",
"requires": {
"jwa": "^1.1.5",
"safe-buffer": "^5.0.1"
}
},
"killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@ -8394,9 +8254,9 @@
}
},
"linkify-it": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz",
"integrity": "sha1-2UpGSPmxwXnWT6lykSaL22zpQ08=",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.1.0.tgz",
"integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==",
"requires": {
"uc.micro": "^1.0.1"
}
@ -8503,6 +8363,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha1-s56mIp72B+zYniyN8SU2iRysm40="
},
"lodash-es": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.11.tgz",
"integrity": "sha512-DHb1ub+rMjjrxqlB3H56/6MXtm1lSksDp2rA2cNWjG8mlDUYFhUj3Di2Zn5IwSU87xLv8tNIQ7sSwE/YOX/D/Q=="
},
"lodash._reinterpolate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
@ -8513,66 +8378,16 @@
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
"integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
},
"lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
},
"lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
},
"lodash.escaperegexp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
"integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c="
},
"lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
},
"lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
},
"lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
},
"lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
},
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
},
"lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
},
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
},
"lodash.mergewith": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz",
"integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ=="
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
},
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@ -8682,22 +8497,17 @@
}
},
"markdown-it": {
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
"integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
"version": "8.3.1",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.3.1.tgz",
"integrity": "sha1-L0tiKUjM3Bk9ZvPKLUMSWsSscyM=",
"requires": {
"argparse": "^1.0.7",
"entities": "~1.1.1",
"linkify-it": "^2.0.0",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
"uc.micro": "^1.0.3"
}
},
"markdown-it-for-inline": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/markdown-it-for-inline/-/markdown-it-for-inline-0.1.1.tgz",
"integrity": "sha1-Q18jFvW15o4UUM+iJC8rjVmtx18="
},
"math-random": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
@ -8736,11 +8546,6 @@
"mimic-fn": "^1.0.0"
}
},
"memoize-one": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-4.0.3.tgz",
"integrity": "sha512-QmpUu4KqDmX0plH4u+tf0riMc1KHE1+lw95cMrLlXQAFOx/xnBtwhZ52XJxd9X2O6kwKBqX32kmhbhlobD0cuw=="
},
"memory-fs": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
@ -11569,16 +11374,6 @@
}
}
},
"react-dictate-button": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/react-dictate-button/-/react-dictate-button-1.1.3.tgz",
"integrity": "sha512-4Od7sTAEIvPKpZbpy1tCv7qqfRNwLnZom9hrLnNvr1FIWjSOYC94ekAP8S5kevqnVaFvSqwFisCmjd3uLmvsrA==",
"requires": {
"classnames": "^2.2.6",
"glamor": "^2.20.40",
"memoize-one": "^4.0.0"
}
},
"react-dom": {
"version": "16.6.3",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.6.3.tgz",
@ -11606,15 +11401,6 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-5.1.0.tgz",
"integrity": "sha512-akMy/BQT5m1J3iJIHkSb4qycq2wzllWsmmolaaFVnb+LPV9cIJ/nTud40ZsiiT0H3P+/wXIdbjx2fzF61OaeOQ=="
},
"react-film": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/react-film/-/react-film-1.1.1.tgz",
"integrity": "sha512-el6Uw1yDeiu7cKyyuL0eupAKO6vmmTX8un+5btvyYlzD15J1JWLp+Q4rKR3JfcJ2ZM8LKPhAHMfCUGV8t9lVMQ==",
"requires": {
"classnames": "^2.2.6",
"glamor": "^2.20.40"
}
},
"react-helmet": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-5.2.0.tgz",
@ -11626,11 +11412,6 @@
"react-side-effect": "^1.1.0"
}
},
"react-is": {
"version": "16.6.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.6.1.tgz",
"integrity": "sha512-wOKsGtvTMYs7WAscmwwdM8sfRRvE17Ym30zFj3n37Qx5tHRfhenPKEPILHaHob6WoLFADmQm1ZNrE5xMCM6sCw=="
},
"react-lifecycles-compat": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
@ -11655,28 +11436,17 @@
}
},
"react-redux": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.1.1.tgz",
"integrity": "sha512-LE7Ned+cv5qe7tMV5BPYkGQ5Lpg8gzgItK07c67yHvJ8t0iaD9kPFPAli/mYkiyJYrs2pJgExR2ZgsGqlrOApg==",
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.5.tgz",
"integrity": "sha1-+OjHsjlCJXblLWt9sGQ5RpvphGo=",
"requires": {
"@babel/runtime": "^7.1.2",
"hoist-non-react-statics": "^3.1.0",
"invariant": "^2.2.4",
"create-react-class": "^15.5.3",
"hoist-non-react-statics": "^1.0.3",
"invariant": "^2.0.0",
"lodash": "^4.2.0",
"lodash-es": "^4.2.0",
"loose-envify": "^1.1.0",
"prop-types": "^15.6.1",
"react-is": "^16.6.0",
"react-lifecycles-compat": "^3.0.0"
}
},
"react-say": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/react-say/-/react-say-1.1.1.tgz",
"integrity": "sha512-R+XfFQjpwlD48miC0AAb6DZDq4h5DkKFnqQFi/83wpO73isfYx+wuPU6PodzRGP4rF+/6nibnKc2V328ifiALA==",
"requires": {
"classnames": "^2.2.6",
"event-as-promise": "^1.0.3",
"glamor": "^2.20.40",
"memoize-one": "^4.0.0"
"prop-types": "^15.5.10"
}
},
"react-scripts": {
@ -11749,17 +11519,6 @@
}
}
},
"react-scroll-to-bottom": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/react-scroll-to-bottom/-/react-scroll-to-bottom-1.2.0.tgz",
"integrity": "sha512-/tAaVVnSpnMtv4PVIxmxOFh45g6PcUihIK6zH17WTPkqreRFRrbCBnC7ieVu2isV68Zjee98cmBMGgKapI9fCw==",
"requires": {
"classnames": "^2.2.6",
"glamor": "^2.20.40",
"memoize-one": "^4.0.2",
"simple-update-in": "^1.4.0"
}
},
"react-side-effect": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-1.1.5.tgz",
@ -11837,16 +11596,6 @@
}
}
},
"readable-stream": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.0.6.tgz",
"integrity": "sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"readdirp": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
@ -12146,22 +11895,16 @@
}
},
"redux": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.0.1.tgz",
"integrity": "sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg==",
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz",
"integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==",
"requires": {
"loose-envify": "^1.4.0",
"symbol-observable": "^1.2.0"
"lodash": "^4.2.1",
"lodash-es": "^4.2.1",
"loose-envify": "^1.1.0",
"symbol-observable": "^1.0.3"
},
"dependencies": {
"loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"requires": {
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
"symbol-observable": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
@ -12169,15 +11912,10 @@
}
}
},
"redux-promise-middleware": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/redux-promise-middleware/-/redux-promise-middleware-5.1.1.tgz",
"integrity": "sha512-YC1tiheU28Hgmtu5HHMLiuveLgjL1aCJWsSnwquMiZBcj5i/J9qVLt6vgOnb0Gz37y4deJ/rjiNt7l6Dh+Z8lA=="
},
"redux-saga": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/redux-saga/-/redux-saga-0.16.2.tgz",
"integrity": "sha512-iIjKnRThI5sKPEASpUvySemjzwqwI13e3qP7oLub+FycCRDysLSAOwt958niZW6LhxfmS6Qm1BzbU70w/Koc4w=="
"redux-observable": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/redux-observable/-/redux-observable-0.13.0.tgz",
"integrity": "sha1-NbJsLNu3HkmbMcqZYdoFgcKXOQk="
},
"regenerate": {
"version": "1.4.0",
@ -12556,20 +12294,18 @@
}
},
"rxjs": {
"version": "6.3.3",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz",
"integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==",
"version": "5.5.12",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz",
"integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==",
"requires": {
"tslib": "^1.9.0"
},
"dependencies": {
"tslib": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
}
"symbol-observable": "1.0.1"
}
},
"rxjs-compat": {
"version": "6.3.3",
"resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.3.3.tgz",
"integrity": "sha512-caGN7ixiabHpOofginKEquuHk7GgaCrC7UpUQ9ZqGp80tMc68msadOeP/2AKy2R4YJsT1+TX5GZCtxO82qWkyA=="
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@ -12867,23 +12603,6 @@
}
}
},
"sanitize-html": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.19.1.tgz",
"integrity": "sha512-zNYr6FvBn4bZukr9x2uny6od/9YdjCLwF+FqxivqI0YOt/m9GIxfX+tWhm52tBAPUXiTTb4bJTGVagRz5b06bw==",
"requires": {
"chalk": "^2.3.0",
"htmlparser2": "^3.9.0",
"lodash.clonedeep": "^4.5.0",
"lodash.escaperegexp": "^4.1.2",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.mergewith": "^4.6.0",
"postcss": "^6.0.14",
"srcset": "^1.0.0",
"xtend": "^4.0.0"
}
},
"sass-loader": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.1.0.tgz",
@ -13539,15 +13258,6 @@
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"srcset": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/srcset/-/srcset-1.0.0.tgz",
"integrity": "sha1-pWad4StC87HV6D7QPHEEb8SPQe8=",
"requires": {
"array-uniq": "^1.0.2",
"number-is-nan": "^1.0.0"
}
},
"sshpk": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz",
@ -13611,11 +13321,6 @@
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
},
"store": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/store/-/store-2.0.12.tgz",
"integrity": "sha1-jFNOKguDH3K3X8XxEZhXxE711ZM="
},
"stream-browserify": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
@ -14531,11 +14236,6 @@
"requires-port": "^1.0.0"
}
},
"url-search-params-polyfill": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/url-search-params-polyfill/-/url-search-params-polyfill-5.0.0.tgz",
"integrity": "sha512-+SCD22QJp4UnqPOI5UTTR0Ljuh8cHbjEf1lIiZrZ8nHTlTixqwVsVQTSfk5vrmDz7N09/Y+ka5jQr0ff35FnQQ=="
},
"use": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
@ -14675,18 +14375,6 @@
"minimalistic-assert": "^1.0.0"
}
},
"web-speech-cognitive-services": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/web-speech-cognitive-services/-/web-speech-cognitive-services-3.0.0.tgz",
"integrity": "sha512-mkAsnL1pzGTn4TXKxFNwcgYL5hhh/NyvZtUghsFk6cGuP2OHebG8K04uJlcwpZnzp18HSWyi3YcYXXGU1tAZJg==",
"requires": {
"@babel/runtime": "^7.1.2",
"event-as-promise": "^1.0.5",
"events": "^3.0.0",
"memoize-one": "^4.0.0",
"simple-update-in": "^1.2.0"
}
},
"webidl-conversions": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",

View file

@ -2,24 +2,27 @@
"name": "default.gbui",
"version": "0.0.12",
"private": false,
"repository": "https://github.com/pragmatismo-io/BotServer",
"description": "Default web interface for General Bots open-core",
"license": "AGPL-3.0",
"homepage": ".",
"dependencies": {
"ajv": "^6.5.5",
"ajv": "^6.5.4",
"botframework-directlinejs": "^0.10.0",
"botframework-webchat": "4.1.0",
"botframework-webchat": "0.14.3-master.72bfef9",
"deep-extend": "^0.6.0",
"fetch": "^1.1.0",
"msal": "^0.2.3",
"powerbi-client": "^2.6.5",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react": "^16.6.0",
"react-dom": "^16.6.0",
"react-helmet": "^5.2.0",
"react-player": "^1.7.0",
"react-player": "^1.6.6",
"react-powerbi": "^0.3.1",
"react-scripts": "^2.1.1",
"react-transition-group": "^2.5.0",
"rxjs": "^6.3.3",
"rxjs": "^5.5.12",
"rxjs-compat": "^6.3.3",
"url-join": "^4.0.0"
},
"scripts": {

View file

@ -314,6 +314,7 @@ class GBUIApp extends React.Component {
// let speechOptions;
// let token = this.state.instanceClient.speechToken;
// speechOptions = {
// speechRecognizer: new SpeechRecognizer({
// locale: "pt-br",

View file

@ -149,6 +149,7 @@ export class AskDialog extends IGBDialog {
return await step.replaceDialog('/ask', { isReturning: true });
} else {
// Second time running Search, now with no filter.
const resultsB = await service.ask(
@ -161,10 +162,10 @@ export class AskDialog extends IGBDialog {
// If there is some result, answer immediately.
if (resultsB && resultsB.answer) {
// Saves some context info.
const user = await min.userProfile.get(step.context, {});
user.isAsking = false;
user.lastQuestionId = resultsB.questionId;
await min.userProfile.set(step.context, user);
@ -212,9 +213,9 @@ export class AskDialog extends IGBDialog {
// Three forms of asking.
if (step.options && step.options['firstTime'] ) {
if (step.options && step.options['firstTime']) {
text = Messages[locale].ask_first_time;
} else if (step.options && step.options['isReturning'] ) {
} else if (step.options && step.options['isReturning']) {
text = Messages[locale].anything_else;
} else if (user.subjects.length > 0) {
text = Messages[locale].which_question;

View file

@ -30,11 +30,15 @@
| |
\*****************************************************************************/
/**
* @fileoverview Knowledge base services and logic.
*/
const logger = require('../../../src/logger');
const Path = require('path');
const Fs = require('fs');
const promise = require('bluebird');
const parse = promise.promisify(require('csv-parse'));
const parse = require('bluebird').promisify(require('csv-parse'));
const UrlJoin = require('url-join');
const marked = require('marked');
const path = require('path');
@ -69,6 +73,7 @@ export class KBService {
subjects.forEach(subject => {
out.push(subject.title);
});
return out.join(', ');
}
@ -77,6 +82,7 @@ export class KBService {
subjects.forEach(subject => {
out.push(subject.internalId);
});
return out.join(' ');
}
@ -125,8 +131,10 @@ export class KBService {
answerId: question.answerId
}
});
return Promise.resolve({ question: question, answer: answer });
}
return Promise.resolve(null);
}
@ -163,9 +171,9 @@ export class KBService {
query = `${query} ${text}`;
}
}
// TODO: Filter by instance. what = `${what}&$filter=instanceId eq ${instanceId}`
query = `${query}&$filter=instanceId eq ${instance.instanceId}`;
try {
if (instance.searchKey && GBConfigService.get('STORAGE_DIALECT') == 'mssql') {
if (instance.searchKey && GBConfigService.get('STORAGE_DIALECT') === 'mssql') {
const service = new AzureSearch(
instance.searchKey,
instance.searchHost,
@ -203,6 +211,7 @@ export class KBService {
parentId: number
): Promise<GuaribasSubject[]> {
const where = { parentSubjectId: parentId, instanceId: instanceId };
return GuaribasSubject.findAll({
where: where
});
@ -210,7 +219,7 @@ export class KBService {
public async getFaqBySubjectArray(from: string, subjects: any): Promise<GuaribasQuestion[]> {
const where = {
from: from, subject1: null, subject2: null, subject3: null, subject4:null
from: from, subject1: null, subject2: null, subject3: null, subject4: null
};
if (subjects) {
@ -230,6 +239,7 @@ export class KBService {
where.subject4 = subjects[3].internalId;
}
}
return await GuaribasQuestion.findAll({
where: where
});
@ -250,6 +260,7 @@ export class KBService {
let lastAnswer: GuaribasAnswer;
const data = await parse(file, opts);
return asyncPromise.eachSeries(data, async line => {
// Extracts values from columns in the current line.
@ -262,7 +273,7 @@ export class KBService {
// Skips the first line.
if (!(subjectsText === 'subjects' && from == 'from')) {
if (!(subjectsText === 'subjects' && from === 'from')) {
let format = '.txt';
// Extracts answer from external media if any.
@ -281,8 +292,10 @@ export class KBService {
// Processes subjects hierarchy splitting by dots.
const subjectArray = subjectsText.split('.');
let subject1: string, subject2: string, subject3: string,
subject4: string;
let subject1: string;
let subject2: string;
let subject3: string;
let subject4: string;
let indexer = 0;
subjectArray.forEach(element => {

View file

@ -59,7 +59,7 @@ export class GBWhatsappPackage implements IGBPackage {
// Only loads engine if it is defined on services.json.
if (min.instance.whatsappBotKey != '') {
if (min.instance.whatsappBotKey) {
this.channel = new WhatsappDirectLine(min.botId, min.instance.whatsappBotKey, min.instance.whatsappServiceKey,
min.instance.whatsappServiceNumber, min.instance.whatsappServiceUrl, min.instance.whatsappServiceWebhookUrl);
}

View file

@ -40,25 +40,17 @@
const logger = require('./logger');
const express = require('express');
const bodyParser = require('body-parser');
const opn = require('opn');
import { IGBInstance, IGBPackage } from 'botlib';
import { GBAdminPackage } from '../packages/admin.gbapp/index';
import { GBAdminService } from '../packages/admin.gbapp/services/GBAdminService';
import { GBAnalyticsPackage } from '../packages/analytics.gblib';
import { AzureDeployerService } from '../packages/azuredeployer.gbapp/services/AzureDeployerService';
import { GBCorePackage } from '../packages/core.gbapp';
import { GuaribasInstance } from '../packages/core.gbapp/models/GBModel';
import { GBConfigService } from '../packages/core.gbapp/services/GBConfigService';
import { GBConversationalService } from '../packages/core.gbapp/services/GBConversationalService';
import { GBCoreService } from '../packages/core.gbapp/services/GBCoreService';
import { GBDeployer } from '../packages/core.gbapp/services/GBDeployer';
import { GBImporter } from '../packages/core.gbapp/services/GBImporter';
import { GBImporter } from '../packages/core.gbapp/services/GBImporterService';
import { GBMinService } from '../packages/core.gbapp/services/GBMinService';
import { GBCustomerSatisfactionPackage } from '../packages/customer-satisfaction.gbapp';
import { GBKBPackage } from '../packages/kb.gbapp';
import { GBSecurityPackage } from '../packages/security.gblib';
import { GBWhatsappPackage } from './../packages/whatsapp.gblib/index';
import { GBVMService } from '../packages/core.gbapp/services/GBVMService';
const appPackages = new Array<IGBPackage>();
@ -66,13 +58,11 @@ const appPackages = new Array<IGBPackage>();
* General Bots open-core entry point.
*/
export class GBServer {
/**
* Program entry-point.
*/
public static run() {
logger.info(`The Bot Server is in STARTING mode...`);
// Creates a basic HTTP server that will serve several URL, one for each
@ -104,136 +94,52 @@ export class GBServer {
// Ensures cloud / on-premises infrastructure is setup.
logger.info(`Establishing a development local proxy (ngrok)...`);
const proxyAddress = await core.ensureProxy(port);
const deployer = new GBDeployer(core, new GBImporter(core));
const azureDeployer = new AzureDeployerService(deployer);
try {
await core.initDatabase();
} catch (error) {
logger.info(`Deploying cognitive infrastructure (on the cloud / on premises)...`);
try {
bootInstance = await azureDeployer.deployFarm(proxyAddress);
} catch (error) {
logger.warn(
'In case of error, please cleanup any infrastructure objects created during this procedure and .env before running again.'
);
throw error;
}
core.writeEnv(bootInstance);
logger.info(`File .env written, starting General Bots...`);
GBConfigService.init();
await core.initDatabase();
}
// TODO: Get .gb* templates from GitHub and download do additional deploy folder.
// Check admin password.
const conversationalService = new GBConversationalService(core);
const adminService = new GBAdminService(core);
const password = GBConfigService.get('ADMIN_PASS');
if (!GBAdminService.StrongRegex.test(password)) {
throw new Error(
'Please, define a really strong password in ADMIN_PASS environment variable before running the server.'
);
}
// NOTE: the semicolon is necessary before this line.
// Loads all system packages.
[
GBAdminPackage,
GBAnalyticsPackage,
GBCorePackage,
GBSecurityPackage,
GBKBPackage,
GBCustomerSatisfactionPackage,
GBWhatsappPackage
].forEach(e => {
logger.info(`Loading sys package: ${e.name}...`);
const p = Object.create(e.prototype) as IGBPackage;
p.loadPackage(core, core.sequelize);
});
// Loads all bot instances from object storage, if it's formatted.
logger.info(`Loading instances from storage...`);
let instances: GuaribasInstance[];
try {
instances = await core.loadInstances();
const instance = instances[0];
if (process.env.NODE_ENV === 'development') {
logger.info(`Updating bot endpoint to local reverse proxy (ngrok)...`);
await azureDeployer.updateBotProxy(
instance.botId,
instance.botId,
`${proxyAddress}/api/messages/${instance.botId}`
);
}
} catch (error) {
if (error.parent.code === 'ELOGIN') {
const group = GBConfigService.get('CLOUD_GROUP');
const serverName = GBConfigService.get('STORAGE_SERVER').split(
'.database.windows.net'
)[0];
await azureDeployer.openStorageFirewall(group, serverName);
} else {
// Check if storage is empty and needs formatting.
const isInvalidObject =
error.parent.number == 208 || error.parent.errno == 1; // MSSQL or SQLITE.
if (isInvalidObject) {
if (GBConfigService.get('STORAGE_SYNC') != 'true') {
throw new Error(`Operating storage is out of sync or there is a storage connection error. Try setting STORAGE_SYNC to true in .env file. Error: ${
error.message
}.`);
} else {
logger.info(
`Storage is empty. After collecting storage structure from all .gbapps it will get synced.`
);
}
} else {
throw new Error(`Cannot connect to operating storage: ${error.message}.`);
}
}
}
// Deploy packages and format object store according to .gbapp storage models.
const proxyAddress: string = await core.ensureProxy(port);
logger.info(`Deploying packages...`);
const importer: GBImporter = new GBImporter(core);
const deployer: GBDeployer = new GBDeployer(core, importer);
const azureDeployer: AzureDeployerService = new AzureDeployerService(deployer);
const adminService: GBAdminService = new GBAdminService(core);
const conversationalService: GBConversationalService = new GBConversationalService(core);
core.ensureAdminIsSecured();
let bootInstance: IGBInstance = null;
try {
await core.initStorage();
} catch (error) {
bootInstance = await core.createBootInstance(core, azureDeployer, proxyAddress);
await core.initStorage();
}
await core.loadSysPackages(core);
await core.checkStorage(azureDeployer);
await deployer.deployPackages(core, server, appPackages);
// If instances is undefined here it's because storage has been formatted.
// Load all instances from .gbot found on deploy package directory.
if (!instances) {
const saveInstance = new GuaribasInstance(bootInstance);
await saveInstance.save();
instances = await core.loadInstances();
}
// Setup server dynamic (per bot instance) resources and listeners.
logger.info(`Publishing instances...`);
const minService = new GBMinService(
core,
conversationalService,
adminService,
deployer
const packageInstance = await importer.importIfNotExistsBotPackage(
GBConfigService.get('CLOUD_GROUP'),
'boot.gbot',
'packages/boot.gbot'
);
await minService.buildMin(server, appPackages, instances);
logger.info(`The Bot Server is in RUNNING mode...`);
if (process.env.NODE_ENV === 'development') {
opn('http://localhost:4242');
const fullInstance = Object.assign(packageInstance, bootInstance);
await core.saveInstance(fullInstance);
let instances: GuaribasInstance[] = await core.loadAllInstances(core, azureDeployer, proxyAddress);
instances = await core.ensureInstances(instances, bootInstance, core);
if(!bootInstance) {
bootInstance = instances[0];
}
const minService: GBMinService = new GBMinService(core, conversationalService, adminService, deployer);
await minService.buildMin(bootInstance, server, appPackages, instances, deployer);
logger.info(`Preparing default.gbui (it may take some additional time for the first time)...`);
deployer.installDefaultGBUI();
logger.info(`The Bot Server is in RUNNING mode...`);
core.openBrowserInDevelopment();
return core;
} catch (err) {
logger.error(`STOP: ${err} ${err.stack ? err.stack : ''}`);
@ -246,4 +152,10 @@ export class GBServer {
// First line to run.
// const path = 'packages/default.gbdialog';
// const file = 'bot.vbs';
// const source =(path + '/' + file);
// let s = new GBVMService();
// s.run(source, path, null, null, null)
GBServer.run();

View file

@ -30,6 +30,10 @@
| |
\*****************************************************************************/
/**
* @fileoverview Logging support.
*/
const { createLogger, format, transports } = require('winston');
const config = {

View file

@ -15,6 +15,8 @@
],
"jsRules": {},
"rules": {
"no-var-requires":false,
"typedef":false,
"variable-name": false,
"no-parameter-properties": false,
"no-reserved-keywords": false,
@ -34,6 +36,6 @@
"export-name":false,
"no-relative-imports": false,
"no-backbone-get-set-outside-model": false,
"max-line-length": [true,{"limit":80,"ignore-pattern":"^\\s+\\*"}]
"max-line-length": [true,{"limit":120,"ignore-pattern":"^\\s+\\*"}]
}
}